Commit 7b724a2260731edbddadfa08f13de5bce2e601a2
Exists in
master
and in
4 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: ALSA: Fix yet another race in disconnection ALSA: asihpi - Update verbose debug print macros ALSA: asihpi - Improve non-busmaster adapter operation ALSA: asihpi - Support single-rate no-SRC cards ALSA: HDA: New AD1984A model for Dell Precision R5500 ALSA: vmalloc buffers should use normal mmap ALSA: hda - Fix SPDIF out regression on ALC889 ALSA: usb-audio - Support for Boss JS-8 Jam Station ALSA: usb-audio: add Cakewalk UM-1G support sound/oss/opl3: validate voice and channel indexes sound/oss: remove offset from load_patch callbacks
Showing 12 changed files Side-by-side Diff
include/sound/pcm.h
... | ... | @@ -1031,9 +1031,7 @@ |
1031 | 1031 | #define snd_pcm_lib_mmap_iomem NULL |
1032 | 1032 | #endif |
1033 | 1033 | |
1034 | -int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, | |
1035 | - struct vm_area_struct *area); | |
1036 | -#define snd_pcm_lib_mmap_vmalloc snd_pcm_lib_mmap_noncached | |
1034 | +#define snd_pcm_lib_mmap_vmalloc NULL | |
1037 | 1035 | |
1038 | 1036 | static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) |
1039 | 1037 | { |
sound/core/init.c
... | ... | @@ -848,6 +848,7 @@ |
848 | 848 | return -ENOMEM; |
849 | 849 | mfile->file = file; |
850 | 850 | mfile->disconnected_f_op = NULL; |
851 | + INIT_LIST_HEAD(&mfile->shutdown_list); | |
851 | 852 | spin_lock(&card->files_lock); |
852 | 853 | if (card->shutdown) { |
853 | 854 | spin_unlock(&card->files_lock); |
... | ... | @@ -883,6 +884,9 @@ |
883 | 884 | list_for_each_entry(mfile, &card->files_list, list) { |
884 | 885 | if (mfile->file == file) { |
885 | 886 | list_del(&mfile->list); |
887 | + spin_lock(&shutdown_lock); | |
888 | + list_del(&mfile->shutdown_list); | |
889 | + spin_unlock(&shutdown_lock); | |
886 | 890 | if (mfile->disconnected_f_op) |
887 | 891 | fops_put(mfile->disconnected_f_op); |
888 | 892 | found = mfile; |
sound/core/pcm_native.c
... | ... | @@ -3201,15 +3201,6 @@ |
3201 | 3201 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); |
3202 | 3202 | #endif /* SNDRV_PCM_INFO_MMAP */ |
3203 | 3203 | |
3204 | -/* mmap callback with pgprot_noncached */ | |
3205 | -int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, | |
3206 | - struct vm_area_struct *area) | |
3207 | -{ | |
3208 | - area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | |
3209 | - return snd_pcm_default_mmap(substream, area); | |
3210 | -} | |
3211 | -EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached); | |
3212 | - | |
3213 | 3204 | /* |
3214 | 3205 | * mmap DMA buffer |
3215 | 3206 | */ |
sound/oss/dev_table.h
... | ... | @@ -271,7 +271,7 @@ |
271 | 271 | void (*reset) (int dev); |
272 | 272 | void (*hw_control) (int dev, unsigned char *event); |
273 | 273 | int (*load_patch) (int dev, int format, const char __user *addr, |
274 | - int offs, int count, int pmgr_flag); | |
274 | + int count, int pmgr_flag); | |
275 | 275 | void (*aftertouch) (int dev, int voice, int pressure); |
276 | 276 | void (*controller) (int dev, int voice, int ctrl_num, int value); |
277 | 277 | void (*panning) (int dev, int voice, int value); |
sound/oss/midi_synth.c
... | ... | @@ -476,7 +476,7 @@ |
476 | 476 | |
477 | 477 | int |
478 | 478 | midi_synth_load_patch(int dev, int format, const char __user *addr, |
479 | - int offs, int count, int pmgr_flag) | |
479 | + int count, int pmgr_flag) | |
480 | 480 | { |
481 | 481 | int orig_dev = synth_devs[dev]->midi_dev; |
482 | 482 | |
483 | 483 | |
484 | 484 | |
485 | 485 | |
486 | 486 | |
487 | 487 | |
488 | 488 | |
489 | 489 | |
490 | 490 | |
... | ... | @@ -491,33 +491,29 @@ |
491 | 491 | if (!prefix_cmd(orig_dev, 0xf0)) |
492 | 492 | return 0; |
493 | 493 | |
494 | + /* Invalid patch format */ | |
494 | 495 | if (format != SYSEX_PATCH) |
495 | - { | |
496 | -/* printk("MIDI Error: Invalid patch format (key) 0x%x\n", format);*/ | |
497 | 496 | return -EINVAL; |
498 | - } | |
497 | + | |
498 | + /* Patch header too short */ | |
499 | 499 | if (count < hdr_size) |
500 | - { | |
501 | -/* printk("MIDI Error: Patch header too short\n");*/ | |
502 | 500 | return -EINVAL; |
503 | - } | |
501 | + | |
504 | 502 | count -= hdr_size; |
505 | 503 | |
506 | 504 | /* |
507 | - * Copy the header from user space but ignore the first bytes which have | |
508 | - * been transferred already. | |
505 | + * Copy the header from user space | |
509 | 506 | */ |
510 | 507 | |
511 | - if(copy_from_user(&((char *) &sysex)[offs], &(addr)[offs], hdr_size - offs)) | |
508 | + if (copy_from_user(&sysex, addr, hdr_size)) | |
512 | 509 | return -EFAULT; |
513 | - | |
514 | - if (count < sysex.len) | |
515 | - { | |
516 | -/* printk(KERN_WARNING "MIDI Warning: Sysex record too short (%d<%d)\n", count, (int) sysex.len);*/ | |
510 | + | |
511 | + /* Sysex record too short */ | |
512 | + if ((unsigned)count < (unsigned)sysex.len) | |
517 | 513 | sysex.len = count; |
518 | - } | |
519 | - left = sysex.len; | |
520 | - src_offs = 0; | |
514 | + | |
515 | + left = sysex.len; | |
516 | + src_offs = 0; | |
521 | 517 | |
522 | 518 | for (i = 0; i < left && !signal_pending(current); i++) |
523 | 519 | { |
sound/oss/midi_synth.h
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | void midi_synth_close (int dev); |
9 | 9 | void midi_synth_hw_control (int dev, unsigned char *event); |
10 | 10 | int midi_synth_load_patch (int dev, int format, const char __user * addr, |
11 | - int offs, int count, int pmgr_flag); | |
11 | + int count, int pmgr_flag); | |
12 | 12 | void midi_synth_panning (int dev, int channel, int pressure); |
13 | 13 | void midi_synth_aftertouch (int dev, int channel, int pressure); |
14 | 14 | void midi_synth_controller (int dev, int channel, int ctrl_num, int value); |
sound/oss/opl3.c
... | ... | @@ -820,7 +820,7 @@ |
820 | 820 | } |
821 | 821 | |
822 | 822 | static int opl3_load_patch(int dev, int format, const char __user *addr, |
823 | - int offs, int count, int pmgr_flag) | |
823 | + int count, int pmgr_flag) | |
824 | 824 | { |
825 | 825 | struct sbi_instrument ins; |
826 | 826 | |
... | ... | @@ -830,11 +830,7 @@ |
830 | 830 | return -EINVAL; |
831 | 831 | } |
832 | 832 | |
833 | - /* | |
834 | - * What the fuck is going on here? We leave junk in the beginning | |
835 | - * of ins and then check the field pretty close to that beginning? | |
836 | - */ | |
837 | - if(copy_from_user(&((char *) &ins)[offs], addr + offs, sizeof(ins) - offs)) | |
833 | + if (copy_from_user(&ins, addr, sizeof(ins))) | |
838 | 834 | return -EFAULT; |
839 | 835 | |
840 | 836 | if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) |
... | ... | @@ -849,6 +845,10 @@ |
849 | 845 | |
850 | 846 | static void opl3_panning(int dev, int voice, int value) |
851 | 847 | { |
848 | + | |
849 | + if (voice < 0 || voice >= devc->nr_voice) | |
850 | + return; | |
851 | + | |
852 | 852 | devc->voc[voice].panning = value; |
853 | 853 | } |
854 | 854 | |
... | ... | @@ -1066,8 +1066,15 @@ |
1066 | 1066 | |
1067 | 1067 | static void opl3_setup_voice(int dev, int voice, int chn) |
1068 | 1068 | { |
1069 | - struct channel_info *info = | |
1070 | - &synth_devs[dev]->chn_info[chn]; | |
1069 | + struct channel_info *info; | |
1070 | + | |
1071 | + if (voice < 0 || voice >= devc->nr_voice) | |
1072 | + return; | |
1073 | + | |
1074 | + if (chn < 0 || chn > 15) | |
1075 | + return; | |
1076 | + | |
1077 | + info = &synth_devs[dev]->chn_info[chn]; | |
1071 | 1078 | |
1072 | 1079 | opl3_set_instr(dev, voice, info->pgm_num); |
1073 | 1080 |
sound/oss/sequencer.c
sound/pci/asihpi/asihpi.c
... | ... | @@ -22,21 +22,6 @@ |
22 | 22 | * for any purpose including commercial applications. |
23 | 23 | */ |
24 | 24 | |
25 | -/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ | |
26 | -#define REALLY_VERBOSE_LOGGING 0 | |
27 | - | |
28 | -#if REALLY_VERBOSE_LOGGING | |
29 | -#define VPRINTK1 snd_printd | |
30 | -#else | |
31 | -#define VPRINTK1(...) | |
32 | -#endif | |
33 | - | |
34 | -#if REALLY_VERBOSE_LOGGING > 1 | |
35 | -#define VPRINTK2 snd_printd | |
36 | -#else | |
37 | -#define VPRINTK2(...) | |
38 | -#endif | |
39 | - | |
40 | 25 | #include "hpi_internal.h" |
41 | 26 | #include "hpimsginit.h" |
42 | 27 | #include "hpioctl.h" |
43 | 28 | |
... | ... | @@ -57,11 +42,25 @@ |
57 | 42 | #include <sound/tlv.h> |
58 | 43 | #include <sound/hwdep.h> |
59 | 44 | |
60 | - | |
61 | 45 | MODULE_LICENSE("GPL"); |
62 | 46 | MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); |
63 | 47 | MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); |
64 | 48 | |
49 | +#if defined CONFIG_SND_DEBUG_VERBOSE | |
50 | +/** | |
51 | + * snd_printddd - very verbose debug printk | |
52 | + * @format: format string | |
53 | + * | |
54 | + * Works like snd_printk() for debugging purposes. | |
55 | + * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. | |
56 | + * Must set snd module debug parameter to 3 to enable at runtime. | |
57 | + */ | |
58 | +#define snd_printddd(format, args...) \ | |
59 | + __snd_printk(3, __FILE__, __LINE__, format, ##args) | |
60 | +#else | |
61 | +#define snd_printddd(format, args...) do { } while (0) | |
62 | +#endif | |
63 | + | |
65 | 64 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ |
66 | 65 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
67 | 66 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
... | ... | @@ -289,7 +288,6 @@ |
289 | 288 | #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) |
290 | 289 | |
291 | 290 | /***************************** GENERAL PCM ****************/ |
292 | -#if REALLY_VERBOSE_LOGGING | |
293 | 291 | static void print_hwparams(struct snd_pcm_hw_params *p) |
294 | 292 | { |
295 | 293 | snd_printd("HWPARAMS \n"); |
... | ... | @@ -304,9 +302,6 @@ |
304 | 302 | snd_printd("periods %d \n", params_periods(p)); |
305 | 303 | snd_printd("buffer_size %d \n", params_buffer_size(p)); |
306 | 304 | } |
307 | -#else | |
308 | -#define print_hwparams(x) | |
309 | -#endif | |
310 | 305 | |
311 | 306 | static snd_pcm_format_t hpi_to_alsa_formats[] = { |
312 | 307 | -1, /* INVALID */ |
... | ... | @@ -381,13 +376,13 @@ |
381 | 376 | "No local sampleclock, err %d\n", err); |
382 | 377 | } |
383 | 378 | |
384 | - for (idx = 0; idx < 100; idx++) { | |
385 | - if (hpi_sample_clock_query_local_rate( | |
386 | - h_control, idx, &sample_rate)) { | |
387 | - if (!idx) | |
388 | - snd_printk(KERN_ERR | |
389 | - "Local rate query failed\n"); | |
390 | - | |
379 | + for (idx = -1; idx < 100; idx++) { | |
380 | + if (idx == -1) { | |
381 | + if (hpi_sample_clock_get_sample_rate(h_control, | |
382 | + &sample_rate)) | |
383 | + continue; | |
384 | + } else if (hpi_sample_clock_query_local_rate(h_control, | |
385 | + idx, &sample_rate)) { | |
391 | 386 | break; |
392 | 387 | } |
393 | 388 | |
... | ... | @@ -440,8 +435,6 @@ |
440 | 435 | } |
441 | 436 | } |
442 | 437 | |
443 | - /* printk(KERN_INFO "Supported rates %X %d %d\n", | |
444 | - rates, rate_min, rate_max); */ | |
445 | 438 | pcmhw->rates = rates; |
446 | 439 | pcmhw->rate_min = rate_min; |
447 | 440 | pcmhw->rate_max = rate_max; |
... | ... | @@ -466,7 +459,7 @@ |
466 | 459 | if (err) |
467 | 460 | return err; |
468 | 461 | |
469 | - VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n", | |
462 | + snd_printdd("format %d, %d chans, %d_hz\n", | |
470 | 463 | format, params_channels(params), |
471 | 464 | params_rate(params)); |
472 | 465 | |
473 | 466 | |
... | ... | @@ -489,13 +482,12 @@ |
489 | 482 | err = hpi_stream_host_buffer_attach(dpcm->h_stream, |
490 | 483 | params_buffer_bytes(params), runtime->dma_addr); |
491 | 484 | if (err == 0) { |
492 | - VPRINTK1(KERN_INFO | |
485 | + snd_printdd( | |
493 | 486 | "stream_host_buffer_attach succeeded %u %lu\n", |
494 | 487 | params_buffer_bytes(params), |
495 | 488 | (unsigned long)runtime->dma_addr); |
496 | 489 | } else { |
497 | - snd_printd(KERN_INFO | |
498 | - "stream_host_buffer_attach error %d\n", | |
490 | + snd_printd("stream_host_buffer_attach error %d\n", | |
499 | 491 | err); |
500 | 492 | return -ENOMEM; |
501 | 493 | } |
... | ... | @@ -504,7 +496,7 @@ |
504 | 496 | &dpcm->hpi_buffer_attached, |
505 | 497 | NULL, NULL, NULL); |
506 | 498 | |
507 | - VPRINTK1(KERN_INFO "stream_host_buffer_attach status 0x%x\n", | |
499 | + snd_printdd("stream_host_buffer_attach status 0x%x\n", | |
508 | 500 | dpcm->hpi_buffer_attached); |
509 | 501 | } |
510 | 502 | bytes_per_sec = params_rate(params) * params_channels(params); |
... | ... | @@ -517,7 +509,7 @@ |
517 | 509 | dpcm->bytes_per_sec = bytes_per_sec; |
518 | 510 | dpcm->buffer_bytes = params_buffer_bytes(params); |
519 | 511 | dpcm->period_bytes = params_period_bytes(params); |
520 | - VPRINTK1(KERN_INFO "buffer_bytes=%d, period_bytes=%d, bps=%d\n", | |
512 | + snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n", | |
521 | 513 | dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec); |
522 | 514 | |
523 | 515 | return 0; |
... | ... | @@ -573,7 +565,7 @@ |
573 | 565 | struct snd_pcm_substream *s; |
574 | 566 | u16 e; |
575 | 567 | |
576 | - VPRINTK1(KERN_INFO "%c%d trigger\n", | |
568 | + snd_printdd("%c%d trigger\n", | |
577 | 569 | SCHR(substream->stream), substream->number); |
578 | 570 | switch (cmd) { |
579 | 571 | case SNDRV_PCM_TRIGGER_START: |
... | ... | @@ -597,7 +589,7 @@ |
597 | 589 | * data?? |
598 | 590 | */ |
599 | 591 | unsigned int preload = ds->period_bytes * 1; |
600 | - VPRINTK2(KERN_INFO "%d preload x%x\n", s->number, preload); | |
592 | + snd_printddd("%d preload x%x\n", s->number, preload); | |
601 | 593 | hpi_handle_error(hpi_outstream_write_buf( |
602 | 594 | ds->h_stream, |
603 | 595 | &runtime->dma_area[0], |
... | ... | @@ -607,7 +599,7 @@ |
607 | 599 | } |
608 | 600 | |
609 | 601 | if (card->support_grouping) { |
610 | - VPRINTK1(KERN_INFO "\t%c%d group\n", | |
602 | + snd_printdd("\t%c%d group\n", | |
611 | 603 | SCHR(s->stream), |
612 | 604 | s->number); |
613 | 605 | e = hpi_stream_group_add( |
... | ... | @@ -622,7 +614,7 @@ |
622 | 614 | } else |
623 | 615 | break; |
624 | 616 | } |
625 | - VPRINTK1(KERN_INFO "start\n"); | |
617 | + snd_printdd("start\n"); | |
626 | 618 | /* start the master stream */ |
627 | 619 | snd_card_asihpi_pcm_timer_start(substream); |
628 | 620 | if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || |
629 | 621 | |
... | ... | @@ -644,14 +636,14 @@ |
644 | 636 | s->runtime->status->state = SNDRV_PCM_STATE_SETUP; |
645 | 637 | |
646 | 638 | if (card->support_grouping) { |
647 | - VPRINTK1(KERN_INFO "\t%c%d group\n", | |
639 | + snd_printdd("\t%c%d group\n", | |
648 | 640 | SCHR(s->stream), |
649 | 641 | s->number); |
650 | 642 | snd_pcm_trigger_done(s, substream); |
651 | 643 | } else |
652 | 644 | break; |
653 | 645 | } |
654 | - VPRINTK1(KERN_INFO "stop\n"); | |
646 | + snd_printdd("stop\n"); | |
655 | 647 | |
656 | 648 | /* _prepare and _hwparams reset the stream */ |
657 | 649 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); |
658 | 650 | |
... | ... | @@ -664,12 +656,12 @@ |
664 | 656 | break; |
665 | 657 | |
666 | 658 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
667 | - VPRINTK1(KERN_INFO "pause release\n"); | |
659 | + snd_printdd("pause release\n"); | |
668 | 660 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); |
669 | 661 | snd_card_asihpi_pcm_timer_start(substream); |
670 | 662 | break; |
671 | 663 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
672 | - VPRINTK1(KERN_INFO "pause\n"); | |
664 | + snd_printdd("pause\n"); | |
673 | 665 | snd_card_asihpi_pcm_timer_stop(substream); |
674 | 666 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); |
675 | 667 | break; |
... | ... | @@ -741,7 +733,7 @@ |
741 | 733 | u16 state; |
742 | 734 | u32 buffer_size, bytes_avail, samples_played, on_card_bytes; |
743 | 735 | |
744 | - VPRINTK1(KERN_INFO "%c%d snd_card_asihpi_timer_function\n", | |
736 | + snd_printdd("%c%d snd_card_asihpi_timer_function\n", | |
745 | 737 | SCHR(substream->stream), substream->number); |
746 | 738 | |
747 | 739 | /* find minimum newdata and buffer pos in group */ |
748 | 740 | |
... | ... | @@ -770,10 +762,10 @@ |
770 | 762 | if ((bytes_avail == 0) && |
771 | 763 | (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { |
772 | 764 | hpi_handle_error(hpi_stream_start(ds->h_stream)); |
773 | - VPRINTK1(KERN_INFO "P%d start\n", s->number); | |
765 | + snd_printdd("P%d start\n", s->number); | |
774 | 766 | } |
775 | 767 | } else if (state == HPI_STATE_DRAINED) { |
776 | - VPRINTK1(KERN_WARNING "P%d drained\n", | |
768 | + snd_printd(KERN_WARNING "P%d drained\n", | |
777 | 769 | s->number); |
778 | 770 | /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); |
779 | 771 | continue; */ |
780 | 772 | |
... | ... | @@ -794,13 +786,13 @@ |
794 | 786 | newdata); |
795 | 787 | } |
796 | 788 | |
797 | - VPRINTK1(KERN_INFO "PB timer hw_ptr x%04lX, appl_ptr x%04lX\n", | |
789 | + snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", | |
798 | 790 | (unsigned long)frames_to_bytes(runtime, |
799 | 791 | runtime->status->hw_ptr), |
800 | 792 | (unsigned long)frames_to_bytes(runtime, |
801 | 793 | runtime->control->appl_ptr)); |
802 | 794 | |
803 | - VPRINTK1(KERN_INFO "%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," | |
795 | + snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," | |
804 | 796 | " aux=x%04X space=x%04X\n", |
805 | 797 | loops, SCHR(s->stream), s->number, |
806 | 798 | state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, |
... | ... | @@ -822,7 +814,7 @@ |
822 | 814 | |
823 | 815 | next_jiffies = max(next_jiffies, 1U); |
824 | 816 | dpcm->timer.expires = jiffies + next_jiffies; |
825 | - VPRINTK1(KERN_INFO "jif %d buf pos x%04X newdata x%04X xfer x%04X\n", | |
817 | + snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", | |
826 | 818 | next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); |
827 | 819 | |
828 | 820 | snd_pcm_group_for_each_entry(s, substream) { |
... | ... | @@ -837,7 +829,7 @@ |
837 | 829 | if (xfercount && (on_card_bytes <= ds->period_bytes)) { |
838 | 830 | if (card->support_mmap) { |
839 | 831 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
840 | - VPRINTK2(KERN_INFO "P%d write x%04x\n", | |
832 | + snd_printddd("P%d write x%04x\n", | |
841 | 833 | s->number, |
842 | 834 | ds->period_bytes); |
843 | 835 | hpi_handle_error( |
... | ... | @@ -848,7 +840,7 @@ |
848 | 840 | xfercount, |
849 | 841 | &ds->format)); |
850 | 842 | } else { |
851 | - VPRINTK2(KERN_INFO "C%d read x%04x\n", | |
843 | + snd_printddd("C%d read x%04x\n", | |
852 | 844 | s->number, |
853 | 845 | xfercount); |
854 | 846 | hpi_handle_error( |
... | ... | @@ -871,7 +863,7 @@ |
871 | 863 | static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, |
872 | 864 | unsigned int cmd, void *arg) |
873 | 865 | { |
874 | - /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */ | |
866 | + snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); | |
875 | 867 | return snd_pcm_lib_ioctl(substream, cmd, arg); |
876 | 868 | } |
877 | 869 | |
... | ... | @@ -881,7 +873,7 @@ |
881 | 873 | struct snd_pcm_runtime *runtime = substream->runtime; |
882 | 874 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
883 | 875 | |
884 | - VPRINTK1(KERN_INFO "playback prepare %d\n", substream->number); | |
876 | + snd_printdd("playback prepare %d\n", substream->number); | |
885 | 877 | |
886 | 878 | hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); |
887 | 879 | dpcm->pcm_buf_host_rw_ofs = 0; |
... | ... | @@ -898,7 +890,7 @@ |
898 | 890 | snd_pcm_uframes_t ptr; |
899 | 891 | |
900 | 892 | ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); |
901 | - /* VPRINTK2(KERN_INFO "playback_pointer=x%04lx\n", (unsigned long)ptr); */ | |
893 | + snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); | |
902 | 894 | return ptr; |
903 | 895 | } |
904 | 896 | |
905 | 897 | |
... | ... | @@ -1014,12 +1006,13 @@ |
1014 | 1006 | |
1015 | 1007 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
1016 | 1008 | card->update_interval_frames); |
1009 | + | |
1017 | 1010 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
1018 | 1011 | card->update_interval_frames * 2, UINT_MAX); |
1019 | 1012 | |
1020 | 1013 | snd_pcm_set_sync(substream); |
1021 | 1014 | |
1022 | - VPRINTK1(KERN_INFO "playback open\n"); | |
1015 | + snd_printdd("playback open\n"); | |
1023 | 1016 | |
1024 | 1017 | return 0; |
1025 | 1018 | } |
... | ... | @@ -1030,7 +1023,7 @@ |
1030 | 1023 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1031 | 1024 | |
1032 | 1025 | hpi_handle_error(hpi_outstream_close(dpcm->h_stream)); |
1033 | - VPRINTK1(KERN_INFO "playback close\n"); | |
1026 | + snd_printdd("playback close\n"); | |
1034 | 1027 | |
1035 | 1028 | return 0; |
1036 | 1029 | } |
1037 | 1030 | |
... | ... | @@ -1050,13 +1043,13 @@ |
1050 | 1043 | if (copy_from_user(runtime->dma_area, src, len)) |
1051 | 1044 | return -EFAULT; |
1052 | 1045 | |
1053 | - VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n", | |
1046 | + snd_printddd("playback copy%d %u bytes\n", | |
1054 | 1047 | substream->number, len); |
1055 | 1048 | |
1056 | 1049 | hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, |
1057 | 1050 | runtime->dma_area, len, &dpcm->format)); |
1058 | 1051 | |
1059 | - dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; | |
1052 | + dpcm->pcm_buf_host_rw_ofs += len; | |
1060 | 1053 | |
1061 | 1054 | return 0; |
1062 | 1055 | } |
... | ... | @@ -1066,16 +1059,11 @@ |
1066 | 1059 | snd_pcm_uframes_t pos, |
1067 | 1060 | snd_pcm_uframes_t count) |
1068 | 1061 | { |
1069 | - unsigned int len; | |
1070 | - struct snd_pcm_runtime *runtime = substream->runtime; | |
1071 | - struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | |
1072 | - | |
1073 | - len = frames_to_bytes(runtime, count); | |
1074 | - VPRINTK1(KERN_INFO "playback silence %u bytes\n", len); | |
1075 | - | |
1076 | - memset(runtime->dma_area, 0, len); | |
1077 | - hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, | |
1078 | - runtime->dma_area, len, &dpcm->format)); | |
1062 | + /* Usually writes silence to DMA buffer, which should be overwritten | |
1063 | + by real audio later. Our fifos cannot be overwritten, and are not | |
1064 | + free-running DMAs. Silence is output on fifo underflow. | |
1065 | + This callback is still required to allow the copy callback to be used. | |
1066 | + */ | |
1079 | 1067 | return 0; |
1080 | 1068 | } |
1081 | 1069 | |
... | ... | @@ -1110,7 +1098,7 @@ |
1110 | 1098 | struct snd_pcm_runtime *runtime = substream->runtime; |
1111 | 1099 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1112 | 1100 | |
1113 | - VPRINTK2(KERN_INFO "capture pointer %d=%d\n", | |
1101 | + snd_printddd("capture pointer %d=%d\n", | |
1114 | 1102 | substream->number, dpcm->pcm_buf_dma_ofs); |
1115 | 1103 | /* NOTE Unlike playback can't use actual samples_played |
1116 | 1104 | for the capture position, because those samples aren't yet in |
... | ... | @@ -1135,7 +1123,7 @@ |
1135 | 1123 | dpcm->pcm_buf_dma_ofs = 0; |
1136 | 1124 | dpcm->pcm_buf_elapsed_dma_ofs = 0; |
1137 | 1125 | |
1138 | - VPRINTK1("Capture Prepare %d\n", substream->number); | |
1126 | + snd_printdd("Capture Prepare %d\n", substream->number); | |
1139 | 1127 | return 0; |
1140 | 1128 | } |
1141 | 1129 | |
... | ... | @@ -1198,7 +1186,7 @@ |
1198 | 1186 | if (dpcm == NULL) |
1199 | 1187 | return -ENOMEM; |
1200 | 1188 | |
1201 | - VPRINTK1("hpi_instream_open adapter %d stream %d\n", | |
1189 | + snd_printdd("capture open adapter %d stream %d\n", | |
1202 | 1190 | card->adapter_index, substream->number); |
1203 | 1191 | |
1204 | 1192 | err = hpi_handle_error( |
... | ... | @@ -1268,7 +1256,7 @@ |
1268 | 1256 | |
1269 | 1257 | len = frames_to_bytes(runtime, count); |
1270 | 1258 | |
1271 | - VPRINTK2(KERN_INFO "capture copy%d %d bytes\n", substream->number, len); | |
1259 | + snd_printddd("capture copy%d %d bytes\n", substream->number, len); | |
1272 | 1260 | hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, |
1273 | 1261 | runtime->dma_area, len)); |
1274 | 1262 | |
... | ... | @@ -2887,6 +2875,9 @@ |
2887 | 2875 | if (err) |
2888 | 2876 | asihpi->update_interval_frames = 512; |
2889 | 2877 | |
2878 | + if (!asihpi->support_mmap) | |
2879 | + asihpi->update_interval_frames *= 2; | |
2880 | + | |
2890 | 2881 | hpi_handle_error(hpi_instream_open(asihpi->adapter_index, |
2891 | 2882 | 0, &h_stream)); |
2892 | 2883 | |
... | ... | @@ -2909,7 +2900,6 @@ |
2909 | 2900 | asihpi->support_mrx |
2910 | 2901 | ); |
2911 | 2902 | |
2912 | - | |
2913 | 2903 | err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams); |
2914 | 2904 | if (err < 0) { |
2915 | 2905 | snd_printk(KERN_ERR "pcm_new failed\n"); |
... | ... | @@ -2944,6 +2934,7 @@ |
2944 | 2934 | sprintf(card->longname, "%s %i", |
2945 | 2935 | card->shortname, asihpi->adapter_index); |
2946 | 2936 | err = snd_card_register(card); |
2937 | + | |
2947 | 2938 | if (!err) { |
2948 | 2939 | hpi_card->snd_card_asihpi = card; |
2949 | 2940 | dev++; |
sound/pci/hda/patch_analog.c
... | ... | @@ -4256,6 +4256,84 @@ |
4256 | 4256 | } |
4257 | 4257 | |
4258 | 4258 | /* |
4259 | + * Precision R5500 | |
4260 | + * 0x12 - HP/line-out | |
4261 | + * 0x13 - speaker (mono) | |
4262 | + * 0x15 - mic-in | |
4263 | + */ | |
4264 | + | |
4265 | +static struct hda_verb ad1984a_precision_verbs[] = { | |
4266 | + /* Unmute main output path */ | |
4267 | + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | |
4268 | + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ | |
4269 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */ | |
4270 | + /* Analog mixer; mute as default */ | |
4271 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | |
4272 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | |
4273 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | |
4274 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | |
4275 | + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | |
4276 | + /* Select mic as input */ | |
4277 | + {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, | |
4278 | + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */ | |
4279 | + /* Configure as mic */ | |
4280 | + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | |
4281 | + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ | |
4282 | + /* HP unmute */ | |
4283 | + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | |
4284 | + /* turn on EAPD */ | |
4285 | + {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | |
4286 | + /* unsolicited event for pin-sense */ | |
4287 | + {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, | |
4288 | + { } /* end */ | |
4289 | +}; | |
4290 | + | |
4291 | +static struct snd_kcontrol_new ad1984a_precision_mixers[] = { | |
4292 | + HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | |
4293 | + HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), | |
4294 | + HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), | |
4295 | + HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), | |
4296 | + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | |
4297 | + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | |
4298 | + HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), | |
4299 | + HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), | |
4300 | + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT), | |
4301 | + HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | |
4302 | + HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | |
4303 | + { } /* end */ | |
4304 | +}; | |
4305 | + | |
4306 | + | |
4307 | +/* mute internal speaker if HP is plugged */ | |
4308 | +static void ad1984a_precision_automute(struct hda_codec *codec) | |
4309 | +{ | |
4310 | + unsigned int present; | |
4311 | + | |
4312 | + present = snd_hda_jack_detect(codec, 0x12); | |
4313 | + snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, | |
4314 | + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | |
4315 | +} | |
4316 | + | |
4317 | + | |
4318 | +/* unsolicited event for HP jack sensing */ | |
4319 | +static void ad1984a_precision_unsol_event(struct hda_codec *codec, | |
4320 | + unsigned int res) | |
4321 | +{ | |
4322 | + if ((res >> 26) != AD1884A_HP_EVENT) | |
4323 | + return; | |
4324 | + ad1984a_precision_automute(codec); | |
4325 | +} | |
4326 | + | |
4327 | +/* initialize jack-sensing, too */ | |
4328 | +static int ad1984a_precision_init(struct hda_codec *codec) | |
4329 | +{ | |
4330 | + ad198x_init(codec); | |
4331 | + ad1984a_precision_automute(codec); | |
4332 | + return 0; | |
4333 | +} | |
4334 | + | |
4335 | + | |
4336 | +/* | |
4259 | 4337 | * HP Touchsmart |
4260 | 4338 | * port-A (0x11) - front hp-out |
4261 | 4339 | * port-B (0x14) - unused |
... | ... | @@ -4384,6 +4462,7 @@ |
4384 | 4462 | AD1884A_MOBILE, |
4385 | 4463 | AD1884A_THINKPAD, |
4386 | 4464 | AD1984A_TOUCHSMART, |
4465 | + AD1984A_PRECISION, | |
4387 | 4466 | AD1884A_MODELS |
4388 | 4467 | }; |
4389 | 4468 | |
4390 | 4469 | |
... | ... | @@ -4393,9 +4472,11 @@ |
4393 | 4472 | [AD1884A_MOBILE] = "mobile", |
4394 | 4473 | [AD1884A_THINKPAD] = "thinkpad", |
4395 | 4474 | [AD1984A_TOUCHSMART] = "touchsmart", |
4475 | + [AD1984A_PRECISION] = "precision", | |
4396 | 4476 | }; |
4397 | 4477 | |
4398 | 4478 | static struct snd_pci_quirk ad1884a_cfg_tbl[] = { |
4479 | + SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), | |
4399 | 4480 | SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), |
4400 | 4481 | SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), |
4401 | 4482 | SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), |
... | ... | @@ -4488,6 +4569,14 @@ |
4488 | 4569 | spec->input_mux = &ad1984a_thinkpad_capture_source; |
4489 | 4570 | codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; |
4490 | 4571 | codec->patch_ops.init = ad1984a_thinkpad_init; |
4572 | + break; | |
4573 | + case AD1984A_PRECISION: | |
4574 | + spec->mixers[0] = ad1984a_precision_mixers; | |
4575 | + spec->init_verbs[spec->num_init_verbs++] = | |
4576 | + ad1984a_precision_verbs; | |
4577 | + spec->multiout.dig_out_nid = 0; | |
4578 | + codec->patch_ops.unsol_event = ad1984a_precision_unsol_event; | |
4579 | + codec->patch_ops.init = ad1984a_precision_init; | |
4491 | 4580 | break; |
4492 | 4581 | case AD1984A_TOUCHSMART: |
4493 | 4582 | spec->mixers[0] = ad1984a_touchsmart_mixers; |
sound/pci/hda/patch_realtek.c
sound/usb/quirks-table.h
... | ... | @@ -1568,6 +1568,46 @@ |
1568 | 1568 | } |
1569 | 1569 | }, |
1570 | 1570 | { |
1571 | + USB_DEVICE_VENDOR_SPEC(0x0582, 0x0104), | |
1572 | + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | |
1573 | + /* .vendor_name = "Roland", */ | |
1574 | + /* .product_name = "UM-1G", */ | |
1575 | + .ifnum = 0, | |
1576 | + .type = QUIRK_MIDI_FIXED_ENDPOINT, | |
1577 | + .data = & (const struct snd_usb_midi_endpoint_info) { | |
1578 | + .out_cables = 0x0001, | |
1579 | + .in_cables = 0x0001 | |
1580 | + } | |
1581 | + } | |
1582 | +}, | |
1583 | +{ | |
1584 | + /* Boss JS-8 Jam Station */ | |
1585 | + USB_DEVICE(0x0582, 0x0109), | |
1586 | + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | |
1587 | + /* .vendor_name = "BOSS", */ | |
1588 | + /* .product_name = "JS-8", */ | |
1589 | + .ifnum = QUIRK_ANY_INTERFACE, | |
1590 | + .type = QUIRK_COMPOSITE, | |
1591 | + .data = (const struct snd_usb_audio_quirk[]) { | |
1592 | + { | |
1593 | + .ifnum = 0, | |
1594 | + .type = QUIRK_AUDIO_STANDARD_INTERFACE | |
1595 | + }, | |
1596 | + { | |
1597 | + .ifnum = 1, | |
1598 | + .type = QUIRK_AUDIO_STANDARD_INTERFACE | |
1599 | + }, | |
1600 | + { | |
1601 | + .ifnum = 2, | |
1602 | + .type = QUIRK_MIDI_STANDARD_INTERFACE | |
1603 | + }, | |
1604 | + { | |
1605 | + .ifnum = -1 | |
1606 | + } | |
1607 | + } | |
1608 | + } | |
1609 | +}, | |
1610 | +{ | |
1571 | 1611 | /* has ID 0x0110 when not in Advanced Driver mode */ |
1572 | 1612 | USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f), |
1573 | 1613 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |