diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-27 23:35:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-27 23:35:07 -0400 |
commit | 7b724a2260731edbddadfa08f13de5bce2e601a2 (patch) | |
tree | dcf905f023635ee22aacd917d2a2706f257ee7eb /sound | |
parent | 551b0bda46d4caf74755a018e2cdb1d093e000c9 (diff) | |
parent | a45e3d6b13e97506b616980c0f122c3389bcefa4 (diff) |
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
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/init.c | 4 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 9 | ||||
-rw-r--r-- | sound/oss/dev_table.h | 2 | ||||
-rw-r--r-- | sound/oss/midi_synth.c | 30 | ||||
-rw-r--r-- | sound/oss/midi_synth.h | 2 | ||||
-rw-r--r-- | sound/oss/opl3.c | 23 | ||||
-rw-r--r-- | sound/oss/sequencer.c | 2 | ||||
-rw-r--r-- | sound/pci/asihpi/asihpi.c | 137 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 89 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 40 |
11 files changed, 229 insertions, 111 deletions
diff --git a/sound/core/init.c b/sound/core/init.c index 3e65da21a08c..a0080aa45ae9 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -848,6 +848,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file) | |||
848 | return -ENOMEM; | 848 | return -ENOMEM; |
849 | mfile->file = file; | 849 | mfile->file = file; |
850 | mfile->disconnected_f_op = NULL; | 850 | mfile->disconnected_f_op = NULL; |
851 | INIT_LIST_HEAD(&mfile->shutdown_list); | ||
851 | spin_lock(&card->files_lock); | 852 | spin_lock(&card->files_lock); |
852 | if (card->shutdown) { | 853 | if (card->shutdown) { |
853 | spin_unlock(&card->files_lock); | 854 | spin_unlock(&card->files_lock); |
@@ -883,6 +884,9 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) | |||
883 | list_for_each_entry(mfile, &card->files_list, list) { | 884 | list_for_each_entry(mfile, &card->files_list, list) { |
884 | if (mfile->file == file) { | 885 | if (mfile->file == file) { |
885 | list_del(&mfile->list); | 886 | list_del(&mfile->list); |
887 | spin_lock(&shutdown_lock); | ||
888 | list_del(&mfile->shutdown_list); | ||
889 | spin_unlock(&shutdown_lock); | ||
886 | if (mfile->disconnected_f_op) | 890 | if (mfile->disconnected_f_op) |
887 | fops_put(mfile->disconnected_f_op); | 891 | fops_put(mfile->disconnected_f_op); |
888 | found = mfile; | 892 | found = mfile; |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index ae42b6509ce4..fe5c8036beba 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -3201,15 +3201,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | |||
3201 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); | 3201 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); |
3202 | #endif /* SNDRV_PCM_INFO_MMAP */ | 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 | * mmap DMA buffer | 3205 | * mmap DMA buffer |
3215 | */ | 3206 | */ |
diff --git a/sound/oss/dev_table.h b/sound/oss/dev_table.h index b7617bee6388..0199a317c5a9 100644 --- a/sound/oss/dev_table.h +++ b/sound/oss/dev_table.h | |||
@@ -271,7 +271,7 @@ struct synth_operations | |||
271 | void (*reset) (int dev); | 271 | void (*reset) (int dev); |
272 | void (*hw_control) (int dev, unsigned char *event); | 272 | void (*hw_control) (int dev, unsigned char *event); |
273 | int (*load_patch) (int dev, int format, const char __user *addr, | 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 | void (*aftertouch) (int dev, int voice, int pressure); | 275 | void (*aftertouch) (int dev, int voice, int pressure); |
276 | void (*controller) (int dev, int voice, int ctrl_num, int value); | 276 | void (*controller) (int dev, int voice, int ctrl_num, int value); |
277 | void (*panning) (int dev, int voice, int value); | 277 | void (*panning) (int dev, int voice, int value); |
diff --git a/sound/oss/midi_synth.c b/sound/oss/midi_synth.c index 3c09374ea5bf..2292c230d7e6 100644 --- a/sound/oss/midi_synth.c +++ b/sound/oss/midi_synth.c | |||
@@ -476,7 +476,7 @@ EXPORT_SYMBOL(midi_synth_hw_control); | |||
476 | 476 | ||
477 | int | 477 | int |
478 | midi_synth_load_patch(int dev, int format, const char __user *addr, | 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 | int orig_dev = synth_devs[dev]->midi_dev; | 481 | int orig_dev = synth_devs[dev]->midi_dev; |
482 | 482 | ||
@@ -491,33 +491,29 @@ midi_synth_load_patch(int dev, int format, const char __user *addr, | |||
491 | if (!prefix_cmd(orig_dev, 0xf0)) | 491 | if (!prefix_cmd(orig_dev, 0xf0)) |
492 | return 0; | 492 | return 0; |
493 | 493 | ||
494 | /* Invalid patch format */ | ||
494 | if (format != SYSEX_PATCH) | 495 | if (format != SYSEX_PATCH) |
495 | { | ||
496 | /* printk("MIDI Error: Invalid patch format (key) 0x%x\n", format);*/ | ||
497 | return -EINVAL; | 496 | return -EINVAL; |
498 | } | 497 | |
498 | /* Patch header too short */ | ||
499 | if (count < hdr_size) | 499 | if (count < hdr_size) |
500 | { | ||
501 | /* printk("MIDI Error: Patch header too short\n");*/ | ||
502 | return -EINVAL; | 500 | return -EINVAL; |
503 | } | 501 | |
504 | count -= hdr_size; | 502 | count -= hdr_size; |
505 | 503 | ||
506 | /* | 504 | /* |
507 | * Copy the header from user space but ignore the first bytes which have | 505 | * Copy the header from user space |
508 | * been transferred already. | ||
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 | return -EFAULT; | 509 | return -EFAULT; |
513 | 510 | ||
514 | if (count < sysex.len) | 511 | /* Sysex record too short */ |
515 | { | 512 | if ((unsigned)count < (unsigned)sysex.len) |
516 | /* printk(KERN_WARNING "MIDI Warning: Sysex record too short (%d<%d)\n", count, (int) sysex.len);*/ | ||
517 | sysex.len = count; | 513 | sysex.len = count; |
518 | } | 514 | |
519 | left = sysex.len; | 515 | left = sysex.len; |
520 | src_offs = 0; | 516 | src_offs = 0; |
521 | 517 | ||
522 | for (i = 0; i < left && !signal_pending(current); i++) | 518 | for (i = 0; i < left && !signal_pending(current); i++) |
523 | { | 519 | { |
diff --git a/sound/oss/midi_synth.h b/sound/oss/midi_synth.h index 6bc9d00bc77c..b64ddd6c4abc 100644 --- a/sound/oss/midi_synth.h +++ b/sound/oss/midi_synth.h | |||
@@ -8,7 +8,7 @@ int midi_synth_open (int dev, int mode); | |||
8 | void midi_synth_close (int dev); | 8 | void midi_synth_close (int dev); |
9 | void midi_synth_hw_control (int dev, unsigned char *event); | 9 | void midi_synth_hw_control (int dev, unsigned char *event); |
10 | int midi_synth_load_patch (int dev, int format, const char __user * addr, | 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 | void midi_synth_panning (int dev, int channel, int pressure); | 12 | void midi_synth_panning (int dev, int channel, int pressure); |
13 | void midi_synth_aftertouch (int dev, int channel, int pressure); | 13 | void midi_synth_aftertouch (int dev, int channel, int pressure); |
14 | void midi_synth_controller (int dev, int channel, int ctrl_num, int value); | 14 | void midi_synth_controller (int dev, int channel, int ctrl_num, int value); |
diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c index 938c48c43585..407cd677950b 100644 --- a/sound/oss/opl3.c +++ b/sound/oss/opl3.c | |||
@@ -820,7 +820,7 @@ static void opl3_hw_control(int dev, unsigned char *event) | |||
820 | } | 820 | } |
821 | 821 | ||
822 | static int opl3_load_patch(int dev, int format, const char __user *addr, | 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 | struct sbi_instrument ins; | 825 | struct sbi_instrument ins; |
826 | 826 | ||
@@ -830,11 +830,7 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, | |||
830 | return -EINVAL; | 830 | return -EINVAL; |
831 | } | 831 | } |
832 | 832 | ||
833 | /* | 833 | if (copy_from_user(&ins, addr, sizeof(ins))) |
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)) | ||
838 | return -EFAULT; | 834 | return -EFAULT; |
839 | 835 | ||
840 | if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) | 836 | if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) |
@@ -849,6 +845,10 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, | |||
849 | 845 | ||
850 | static void opl3_panning(int dev, int voice, int value) | 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 | devc->voc[voice].panning = value; | 852 | devc->voc[voice].panning = value; |
853 | } | 853 | } |
854 | 854 | ||
@@ -1066,8 +1066,15 @@ static int opl3_alloc_voice(int dev, int chn, int note, struct voice_alloc_info | |||
1066 | 1066 | ||
1067 | static void opl3_setup_voice(int dev, int voice, int chn) | 1067 | static void opl3_setup_voice(int dev, int voice, int chn) |
1068 | { | 1068 | { |
1069 | struct channel_info *info = | 1069 | struct channel_info *info; |
1070 | &synth_devs[dev]->chn_info[chn]; | 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 | opl3_set_instr(dev, voice, info->pgm_num); | 1079 | opl3_set_instr(dev, voice, info->pgm_num); |
1073 | 1080 | ||
diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c index 5ea1098ac427..30bcfe470f83 100644 --- a/sound/oss/sequencer.c +++ b/sound/oss/sequencer.c | |||
@@ -241,7 +241,7 @@ int sequencer_write(int dev, struct file *file, const char __user *buf, int coun | |||
241 | return -ENXIO; | 241 | return -ENXIO; |
242 | 242 | ||
243 | fmt = (*(short *) &event_rec[0]) & 0xffff; | 243 | fmt = (*(short *) &event_rec[0]) & 0xffff; |
244 | err = synth_devs[dev]->load_patch(dev, fmt, buf, p + 4, c, 0); | 244 | err = synth_devs[dev]->load_patch(dev, fmt, buf + p, c, 0); |
245 | if (err < 0) | 245 | if (err < 0) |
246 | return err; | 246 | return err; |
247 | 247 | ||
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 0ac1f98d91a1..f53a31e939c1 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -22,21 +22,6 @@ | |||
22 | * for any purpose including commercial applications. | 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 | #include "hpi_internal.h" | 25 | #include "hpi_internal.h" |
41 | #include "hpimsginit.h" | 26 | #include "hpimsginit.h" |
42 | #include "hpioctl.h" | 27 | #include "hpioctl.h" |
@@ -57,11 +42,25 @@ | |||
57 | #include <sound/tlv.h> | 42 | #include <sound/tlv.h> |
58 | #include <sound/hwdep.h> | 43 | #include <sound/hwdep.h> |
59 | 44 | ||
60 | |||
61 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
62 | MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); | 46 | MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); |
63 | MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); | 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 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ | 64 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ |
66 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 65 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
67 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 66 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
@@ -289,7 +288,6 @@ static u16 handle_error(u16 err, int line, char *filename) | |||
289 | #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) | 288 | #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) |
290 | 289 | ||
291 | /***************************** GENERAL PCM ****************/ | 290 | /***************************** GENERAL PCM ****************/ |
292 | #if REALLY_VERBOSE_LOGGING | ||
293 | static void print_hwparams(struct snd_pcm_hw_params *p) | 291 | static void print_hwparams(struct snd_pcm_hw_params *p) |
294 | { | 292 | { |
295 | snd_printd("HWPARAMS \n"); | 293 | snd_printd("HWPARAMS \n"); |
@@ -304,9 +302,6 @@ static void print_hwparams(struct snd_pcm_hw_params *p) | |||
304 | snd_printd("periods %d \n", params_periods(p)); | 302 | snd_printd("periods %d \n", params_periods(p)); |
305 | snd_printd("buffer_size %d \n", params_buffer_size(p)); | 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 | static snd_pcm_format_t hpi_to_alsa_formats[] = { | 306 | static snd_pcm_format_t hpi_to_alsa_formats[] = { |
312 | -1, /* INVALID */ | 307 | -1, /* INVALID */ |
@@ -381,13 +376,13 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, | |||
381 | "No local sampleclock, err %d\n", err); | 376 | "No local sampleclock, err %d\n", err); |
382 | } | 377 | } |
383 | 378 | ||
384 | for (idx = 0; idx < 100; idx++) { | 379 | for (idx = -1; idx < 100; idx++) { |
385 | if (hpi_sample_clock_query_local_rate( | 380 | if (idx == -1) { |
386 | h_control, idx, &sample_rate)) { | 381 | if (hpi_sample_clock_get_sample_rate(h_control, |
387 | if (!idx) | 382 | &sample_rate)) |
388 | snd_printk(KERN_ERR | 383 | continue; |
389 | "Local rate query failed\n"); | 384 | } else if (hpi_sample_clock_query_local_rate(h_control, |
390 | 385 | idx, &sample_rate)) { | |
391 | break; | 386 | break; |
392 | } | 387 | } |
393 | 388 | ||
@@ -440,8 +435,6 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, | |||
440 | } | 435 | } |
441 | } | 436 | } |
442 | 437 | ||
443 | /* printk(KERN_INFO "Supported rates %X %d %d\n", | ||
444 | rates, rate_min, rate_max); */ | ||
445 | pcmhw->rates = rates; | 438 | pcmhw->rates = rates; |
446 | pcmhw->rate_min = rate_min; | 439 | pcmhw->rate_min = rate_min; |
447 | pcmhw->rate_max = rate_max; | 440 | pcmhw->rate_max = rate_max; |
@@ -466,7 +459,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
466 | if (err) | 459 | if (err) |
467 | return err; | 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 | format, params_channels(params), | 463 | format, params_channels(params), |
471 | params_rate(params)); | 464 | params_rate(params)); |
472 | 465 | ||
@@ -489,13 +482,12 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
489 | err = hpi_stream_host_buffer_attach(dpcm->h_stream, | 482 | err = hpi_stream_host_buffer_attach(dpcm->h_stream, |
490 | params_buffer_bytes(params), runtime->dma_addr); | 483 | params_buffer_bytes(params), runtime->dma_addr); |
491 | if (err == 0) { | 484 | if (err == 0) { |
492 | VPRINTK1(KERN_INFO | 485 | snd_printdd( |
493 | "stream_host_buffer_attach succeeded %u %lu\n", | 486 | "stream_host_buffer_attach succeeded %u %lu\n", |
494 | params_buffer_bytes(params), | 487 | params_buffer_bytes(params), |
495 | (unsigned long)runtime->dma_addr); | 488 | (unsigned long)runtime->dma_addr); |
496 | } else { | 489 | } else { |
497 | snd_printd(KERN_INFO | 490 | snd_printd("stream_host_buffer_attach error %d\n", |
498 | "stream_host_buffer_attach error %d\n", | ||
499 | err); | 491 | err); |
500 | return -ENOMEM; | 492 | return -ENOMEM; |
501 | } | 493 | } |
@@ -504,7 +496,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
504 | &dpcm->hpi_buffer_attached, | 496 | &dpcm->hpi_buffer_attached, |
505 | NULL, NULL, NULL); | 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 | dpcm->hpi_buffer_attached); | 500 | dpcm->hpi_buffer_attached); |
509 | } | 501 | } |
510 | bytes_per_sec = params_rate(params) * params_channels(params); | 502 | bytes_per_sec = params_rate(params) * params_channels(params); |
@@ -517,7 +509,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
517 | dpcm->bytes_per_sec = bytes_per_sec; | 509 | dpcm->bytes_per_sec = bytes_per_sec; |
518 | dpcm->buffer_bytes = params_buffer_bytes(params); | 510 | dpcm->buffer_bytes = params_buffer_bytes(params); |
519 | dpcm->period_bytes = params_period_bytes(params); | 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 | dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec); | 513 | dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec); |
522 | 514 | ||
523 | return 0; | 515 | return 0; |
@@ -573,7 +565,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
573 | struct snd_pcm_substream *s; | 565 | struct snd_pcm_substream *s; |
574 | u16 e; | 566 | u16 e; |
575 | 567 | ||
576 | VPRINTK1(KERN_INFO "%c%d trigger\n", | 568 | snd_printdd("%c%d trigger\n", |
577 | SCHR(substream->stream), substream->number); | 569 | SCHR(substream->stream), substream->number); |
578 | switch (cmd) { | 570 | switch (cmd) { |
579 | case SNDRV_PCM_TRIGGER_START: | 571 | case SNDRV_PCM_TRIGGER_START: |
@@ -597,7 +589,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
597 | * data?? | 589 | * data?? |
598 | */ | 590 | */ |
599 | unsigned int preload = ds->period_bytes * 1; | 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 | hpi_handle_error(hpi_outstream_write_buf( | 593 | hpi_handle_error(hpi_outstream_write_buf( |
602 | ds->h_stream, | 594 | ds->h_stream, |
603 | &runtime->dma_area[0], | 595 | &runtime->dma_area[0], |
@@ -607,7 +599,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
607 | } | 599 | } |
608 | 600 | ||
609 | if (card->support_grouping) { | 601 | if (card->support_grouping) { |
610 | VPRINTK1(KERN_INFO "\t%c%d group\n", | 602 | snd_printdd("\t%c%d group\n", |
611 | SCHR(s->stream), | 603 | SCHR(s->stream), |
612 | s->number); | 604 | s->number); |
613 | e = hpi_stream_group_add( | 605 | e = hpi_stream_group_add( |
@@ -622,7 +614,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
622 | } else | 614 | } else |
623 | break; | 615 | break; |
624 | } | 616 | } |
625 | VPRINTK1(KERN_INFO "start\n"); | 617 | snd_printdd("start\n"); |
626 | /* start the master stream */ | 618 | /* start the master stream */ |
627 | snd_card_asihpi_pcm_timer_start(substream); | 619 | snd_card_asihpi_pcm_timer_start(substream); |
628 | if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || | 620 | if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || |
@@ -644,14 +636,14 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
644 | s->runtime->status->state = SNDRV_PCM_STATE_SETUP; | 636 | s->runtime->status->state = SNDRV_PCM_STATE_SETUP; |
645 | 637 | ||
646 | if (card->support_grouping) { | 638 | if (card->support_grouping) { |
647 | VPRINTK1(KERN_INFO "\t%c%d group\n", | 639 | snd_printdd("\t%c%d group\n", |
648 | SCHR(s->stream), | 640 | SCHR(s->stream), |
649 | s->number); | 641 | s->number); |
650 | snd_pcm_trigger_done(s, substream); | 642 | snd_pcm_trigger_done(s, substream); |
651 | } else | 643 | } else |
652 | break; | 644 | break; |
653 | } | 645 | } |
654 | VPRINTK1(KERN_INFO "stop\n"); | 646 | snd_printdd("stop\n"); |
655 | 647 | ||
656 | /* _prepare and _hwparams reset the stream */ | 648 | /* _prepare and _hwparams reset the stream */ |
657 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); | 649 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); |
@@ -664,12 +656,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
664 | break; | 656 | break; |
665 | 657 | ||
666 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 658 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
667 | VPRINTK1(KERN_INFO "pause release\n"); | 659 | snd_printdd("pause release\n"); |
668 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); | 660 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); |
669 | snd_card_asihpi_pcm_timer_start(substream); | 661 | snd_card_asihpi_pcm_timer_start(substream); |
670 | break; | 662 | break; |
671 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 663 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
672 | VPRINTK1(KERN_INFO "pause\n"); | 664 | snd_printdd("pause\n"); |
673 | snd_card_asihpi_pcm_timer_stop(substream); | 665 | snd_card_asihpi_pcm_timer_stop(substream); |
674 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); | 666 | hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); |
675 | break; | 667 | break; |
@@ -741,7 +733,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
741 | u16 state; | 733 | u16 state; |
742 | u32 buffer_size, bytes_avail, samples_played, on_card_bytes; | 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 | SCHR(substream->stream), substream->number); | 737 | SCHR(substream->stream), substream->number); |
746 | 738 | ||
747 | /* find minimum newdata and buffer pos in group */ | 739 | /* find minimum newdata and buffer pos in group */ |
@@ -770,10 +762,10 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
770 | if ((bytes_avail == 0) && | 762 | if ((bytes_avail == 0) && |
771 | (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { | 763 | (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { |
772 | hpi_handle_error(hpi_stream_start(ds->h_stream)); | 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 | } else if (state == HPI_STATE_DRAINED) { | 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 | s->number); | 769 | s->number); |
778 | /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); | 770 | /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); |
779 | continue; */ | 771 | continue; */ |
@@ -794,13 +786,13 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
794 | newdata); | 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 | (unsigned long)frames_to_bytes(runtime, | 790 | (unsigned long)frames_to_bytes(runtime, |
799 | runtime->status->hw_ptr), | 791 | runtime->status->hw_ptr), |
800 | (unsigned long)frames_to_bytes(runtime, | 792 | (unsigned long)frames_to_bytes(runtime, |
801 | runtime->control->appl_ptr)); | 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 | " aux=x%04X space=x%04X\n", | 796 | " aux=x%04X space=x%04X\n", |
805 | loops, SCHR(s->stream), s->number, | 797 | loops, SCHR(s->stream), s->number, |
806 | state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, | 798 | state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, |
@@ -822,7 +814,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
822 | 814 | ||
823 | next_jiffies = max(next_jiffies, 1U); | 815 | next_jiffies = max(next_jiffies, 1U); |
824 | dpcm->timer.expires = jiffies + next_jiffies; | 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 | next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); | 818 | next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); |
827 | 819 | ||
828 | snd_pcm_group_for_each_entry(s, substream) { | 820 | snd_pcm_group_for_each_entry(s, substream) { |
@@ -837,7 +829,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
837 | if (xfercount && (on_card_bytes <= ds->period_bytes)) { | 829 | if (xfercount && (on_card_bytes <= ds->period_bytes)) { |
838 | if (card->support_mmap) { | 830 | if (card->support_mmap) { |
839 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 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 | s->number, | 833 | s->number, |
842 | ds->period_bytes); | 834 | ds->period_bytes); |
843 | hpi_handle_error( | 835 | hpi_handle_error( |
@@ -848,7 +840,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
848 | xfercount, | 840 | xfercount, |
849 | &ds->format)); | 841 | &ds->format)); |
850 | } else { | 842 | } else { |
851 | VPRINTK2(KERN_INFO "C%d read x%04x\n", | 843 | snd_printddd("C%d read x%04x\n", |
852 | s->number, | 844 | s->number, |
853 | xfercount); | 845 | xfercount); |
854 | hpi_handle_error( | 846 | hpi_handle_error( |
@@ -871,7 +863,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
871 | static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, | 863 | static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, |
872 | unsigned int cmd, void *arg) | 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 | return snd_pcm_lib_ioctl(substream, cmd, arg); | 867 | return snd_pcm_lib_ioctl(substream, cmd, arg); |
876 | } | 868 | } |
877 | 869 | ||
@@ -881,7 +873,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream * | |||
881 | struct snd_pcm_runtime *runtime = substream->runtime; | 873 | struct snd_pcm_runtime *runtime = substream->runtime; |
882 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 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 | hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); | 878 | hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); |
887 | dpcm->pcm_buf_host_rw_ofs = 0; | 879 | dpcm->pcm_buf_host_rw_ofs = 0; |
@@ -898,7 +890,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) | |||
898 | snd_pcm_uframes_t ptr; | 890 | snd_pcm_uframes_t ptr; |
899 | 891 | ||
900 | ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); | 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 | return ptr; | 894 | return ptr; |
903 | } | 895 | } |
904 | 896 | ||
@@ -1014,12 +1006,13 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
1014 | 1006 | ||
1015 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 1007 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
1016 | card->update_interval_frames); | 1008 | card->update_interval_frames); |
1009 | |||
1017 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 1010 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
1018 | card->update_interval_frames * 2, UINT_MAX); | 1011 | card->update_interval_frames * 2, UINT_MAX); |
1019 | 1012 | ||
1020 | snd_pcm_set_sync(substream); | 1013 | snd_pcm_set_sync(substream); |
1021 | 1014 | ||
1022 | VPRINTK1(KERN_INFO "playback open\n"); | 1015 | snd_printdd("playback open\n"); |
1023 | 1016 | ||
1024 | return 0; | 1017 | return 0; |
1025 | } | 1018 | } |
@@ -1030,7 +1023,7 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream) | |||
1030 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 1023 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
1031 | 1024 | ||
1032 | hpi_handle_error(hpi_outstream_close(dpcm->h_stream)); | 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 | return 0; | 1028 | return 0; |
1036 | } | 1029 | } |
@@ -1050,13 +1043,13 @@ static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream, | |||
1050 | if (copy_from_user(runtime->dma_area, src, len)) | 1043 | if (copy_from_user(runtime->dma_area, src, len)) |
1051 | return -EFAULT; | 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 | substream->number, len); | 1047 | substream->number, len); |
1055 | 1048 | ||
1056 | hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, | 1049 | hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, |
1057 | runtime->dma_area, len, &dpcm->format)); | 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 | return 0; | 1054 | return 0; |
1062 | } | 1055 | } |
@@ -1066,16 +1059,11 @@ static int snd_card_asihpi_playback_silence(struct snd_pcm_substream * | |||
1066 | snd_pcm_uframes_t pos, | 1059 | snd_pcm_uframes_t pos, |
1067 | snd_pcm_uframes_t count) | 1060 | snd_pcm_uframes_t count) |
1068 | { | 1061 | { |
1069 | unsigned int len; | 1062 | /* Usually writes silence to DMA buffer, which should be overwritten |
1070 | struct snd_pcm_runtime *runtime = substream->runtime; | 1063 | by real audio later. Our fifos cannot be overwritten, and are not |
1071 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 1064 | free-running DMAs. Silence is output on fifo underflow. |
1072 | 1065 | This callback is still required to allow the copy callback to be used. | |
1073 | len = frames_to_bytes(runtime, count); | 1066 | */ |
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)); | ||
1079 | return 0; | 1067 | return 0; |
1080 | } | 1068 | } |
1081 | 1069 | ||
@@ -1110,7 +1098,7 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream) | |||
1110 | struct snd_pcm_runtime *runtime = substream->runtime; | 1098 | struct snd_pcm_runtime *runtime = substream->runtime; |
1111 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 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 | substream->number, dpcm->pcm_buf_dma_ofs); | 1102 | substream->number, dpcm->pcm_buf_dma_ofs); |
1115 | /* NOTE Unlike playback can't use actual samples_played | 1103 | /* NOTE Unlike playback can't use actual samples_played |
1116 | for the capture position, because those samples aren't yet in | 1104 | for the capture position, because those samples aren't yet in |
@@ -1135,7 +1123,7 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) | |||
1135 | dpcm->pcm_buf_dma_ofs = 0; | 1123 | dpcm->pcm_buf_dma_ofs = 0; |
1136 | dpcm->pcm_buf_elapsed_dma_ofs = 0; | 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 | return 0; | 1127 | return 0; |
1140 | } | 1128 | } |
1141 | 1129 | ||
@@ -1198,7 +1186,7 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | |||
1198 | if (dpcm == NULL) | 1186 | if (dpcm == NULL) |
1199 | return -ENOMEM; | 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 | card->adapter_index, substream->number); | 1190 | card->adapter_index, substream->number); |
1203 | 1191 | ||
1204 | err = hpi_handle_error( | 1192 | err = hpi_handle_error( |
@@ -1268,7 +1256,7 @@ static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream, | |||
1268 | 1256 | ||
1269 | len = frames_to_bytes(runtime, count); | 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 | hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, | 1260 | hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, |
1273 | runtime->dma_area, len)); | 1261 | runtime->dma_area, len)); |
1274 | 1262 | ||
@@ -2887,6 +2875,9 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2887 | if (err) | 2875 | if (err) |
2888 | asihpi->update_interval_frames = 512; | 2876 | asihpi->update_interval_frames = 512; |
2889 | 2877 | ||
2878 | if (!asihpi->support_mmap) | ||
2879 | asihpi->update_interval_frames *= 2; | ||
2880 | |||
2890 | hpi_handle_error(hpi_instream_open(asihpi->adapter_index, | 2881 | hpi_handle_error(hpi_instream_open(asihpi->adapter_index, |
2891 | 0, &h_stream)); | 2882 | 0, &h_stream)); |
2892 | 2883 | ||
@@ -2909,7 +2900,6 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2909 | asihpi->support_mrx | 2900 | asihpi->support_mrx |
2910 | ); | 2901 | ); |
2911 | 2902 | ||
2912 | |||
2913 | err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams); | 2903 | err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams); |
2914 | if (err < 0) { | 2904 | if (err < 0) { |
2915 | snd_printk(KERN_ERR "pcm_new failed\n"); | 2905 | snd_printk(KERN_ERR "pcm_new failed\n"); |
@@ -2944,6 +2934,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2944 | sprintf(card->longname, "%s %i", | 2934 | sprintf(card->longname, "%s %i", |
2945 | card->shortname, asihpi->adapter_index); | 2935 | card->shortname, asihpi->adapter_index); |
2946 | err = snd_card_register(card); | 2936 | err = snd_card_register(card); |
2937 | |||
2947 | if (!err) { | 2938 | if (!err) { |
2948 | hpi_card->snd_card_asihpi = card; | 2939 | hpi_card->snd_card_asihpi = card; |
2949 | dev++; | 2940 | dev++; |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 734c6ee55d8a..2942d2a9ea10 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -4256,6 +4256,84 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) | |||
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 | * HP Touchsmart | 4337 | * HP Touchsmart |
4260 | * port-A (0x11) - front hp-out | 4338 | * port-A (0x11) - front hp-out |
4261 | * port-B (0x14) - unused | 4339 | * port-B (0x14) - unused |
@@ -4384,6 +4462,7 @@ enum { | |||
4384 | AD1884A_MOBILE, | 4462 | AD1884A_MOBILE, |
4385 | AD1884A_THINKPAD, | 4463 | AD1884A_THINKPAD, |
4386 | AD1984A_TOUCHSMART, | 4464 | AD1984A_TOUCHSMART, |
4465 | AD1984A_PRECISION, | ||
4387 | AD1884A_MODELS | 4466 | AD1884A_MODELS |
4388 | }; | 4467 | }; |
4389 | 4468 | ||
@@ -4393,9 +4472,11 @@ static const char * const ad1884a_models[AD1884A_MODELS] = { | |||
4393 | [AD1884A_MOBILE] = "mobile", | 4472 | [AD1884A_MOBILE] = "mobile", |
4394 | [AD1884A_THINKPAD] = "thinkpad", | 4473 | [AD1884A_THINKPAD] = "thinkpad", |
4395 | [AD1984A_TOUCHSMART] = "touchsmart", | 4474 | [AD1984A_TOUCHSMART] = "touchsmart", |
4475 | [AD1984A_PRECISION] = "precision", | ||
4396 | }; | 4476 | }; |
4397 | 4477 | ||
4398 | static struct snd_pci_quirk ad1884a_cfg_tbl[] = { | 4478 | static struct snd_pci_quirk ad1884a_cfg_tbl[] = { |
4479 | SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), | ||
4399 | SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), | 4480 | SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), |
4400 | SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), | 4481 | SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), |
4401 | SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), | 4482 | SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), |
@@ -4489,6 +4570,14 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
4489 | codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; | 4570 | codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; |
4490 | codec->patch_ops.init = ad1984a_thinkpad_init; | 4571 | codec->patch_ops.init = ad1984a_thinkpad_init; |
4491 | break; | 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; | ||
4580 | break; | ||
4492 | case AD1984A_TOUCHSMART: | 4581 | case AD1984A_TOUCHSMART: |
4493 | spec->mixers[0] = ad1984a_touchsmart_mixers; | 4582 | spec->mixers[0] = ad1984a_touchsmart_mixers; |
4494 | spec->init_verbs[0] = ad1984a_touchsmart_verbs; | 4583 | spec->init_verbs[0] = ad1984a_touchsmart_verbs; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5d582de91c19..0ef0035fe99f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1290,7 +1290,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1290 | case 0x10ec0883: | 1290 | case 0x10ec0883: |
1291 | case 0x10ec0885: | 1291 | case 0x10ec0885: |
1292 | case 0x10ec0887: | 1292 | case 0x10ec0887: |
1293 | case 0x10ec0889: | 1293 | /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ |
1294 | alc889_coef_init(codec); | 1294 | alc889_coef_init(codec); |
1295 | break; | 1295 | break; |
1296 | case 0x10ec0888: | 1296 | case 0x10ec0888: |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index c0dcfca9b5b5..c66d3f64dcf8 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1568,6 +1568,46 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
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 | /* has ID 0x0110 when not in Advanced Driver mode */ | 1611 | /* has ID 0x0110 when not in Advanced Driver mode */ |
1572 | USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f), | 1612 | USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f), |
1573 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1613 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |