diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/compress_offload.c | 13 | ||||
-rw-r--r-- | sound/pci/hda/alc880_quirks.c | 17 | ||||
-rw-r--r-- | sound/pci/hda/alc882_quirks.c | 15 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 6 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.c | 24 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 101 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 19 | ||||
-rw-r--r-- | sound/pci/ymfpci/ymfpci.c | 21 | ||||
-rw-r--r-- | sound/pci/ymfpci/ymfpci_main.c | 21 |
10 files changed, 160 insertions, 79 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index dac3633507c9..a68aed7fce02 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c | |||
@@ -441,19 +441,22 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) | |||
441 | params = kmalloc(sizeof(*params), GFP_KERNEL); | 441 | params = kmalloc(sizeof(*params), GFP_KERNEL); |
442 | if (!params) | 442 | if (!params) |
443 | return -ENOMEM; | 443 | return -ENOMEM; |
444 | if (copy_from_user(params, (void __user *)arg, sizeof(*params))) | 444 | if (copy_from_user(params, (void __user *)arg, sizeof(*params))) { |
445 | return -EFAULT; | 445 | retval = -EFAULT; |
446 | goto out; | ||
447 | } | ||
446 | retval = snd_compr_allocate_buffer(stream, params); | 448 | retval = snd_compr_allocate_buffer(stream, params); |
447 | if (retval) { | 449 | if (retval) { |
448 | kfree(params); | 450 | retval = -ENOMEM; |
449 | return -ENOMEM; | 451 | goto out; |
450 | } | 452 | } |
451 | retval = stream->ops->set_params(stream, params); | 453 | retval = stream->ops->set_params(stream, params); |
452 | if (retval) | 454 | if (retval) |
453 | goto out; | 455 | goto out; |
454 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; | 456 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; |
455 | } else | 457 | } else { |
456 | return -EPERM; | 458 | return -EPERM; |
459 | } | ||
457 | out: | 460 | out: |
458 | kfree(params); | 461 | kfree(params); |
459 | return retval; | 462 | return retval; |
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c index 5b68435d195b..501501ef36a9 100644 --- a/sound/pci/hda/alc880_quirks.c +++ b/sound/pci/hda/alc880_quirks.c | |||
@@ -762,16 +762,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, | |||
762 | /* Looks like the unsol event is incompatible with the standard | 762 | /* Looks like the unsol event is incompatible with the standard |
763 | * definition. 4bit tag is placed at 28 bit! | 763 | * definition. 4bit tag is placed at 28 bit! |
764 | */ | 764 | */ |
765 | switch (res >> 28) { | 765 | res >>= 28; |
766 | switch (res) { | ||
766 | case ALC_MIC_EVENT: | 767 | case ALC_MIC_EVENT: |
767 | alc88x_simple_mic_automute(codec); | 768 | alc88x_simple_mic_automute(codec); |
768 | break; | 769 | break; |
769 | default: | 770 | default: |
770 | alc_sku_unsol_event(codec, res); | 771 | alc_exec_unsol_event(codec, res); |
771 | break; | 772 | break; |
772 | } | 773 | } |
773 | } | 774 | } |
774 | 775 | ||
776 | static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) | ||
777 | { | ||
778 | alc_exec_unsol_event(codec, res >> 28); | ||
779 | } | ||
780 | |||
775 | static void alc880_uniwill_p53_setup(struct hda_codec *codec) | 781 | static void alc880_uniwill_p53_setup(struct hda_codec *codec) |
776 | { | 782 | { |
777 | struct alc_spec *spec = codec->spec; | 783 | struct alc_spec *spec = codec->spec; |
@@ -800,10 +806,11 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | |||
800 | /* Looks like the unsol event is incompatible with the standard | 806 | /* Looks like the unsol event is incompatible with the standard |
801 | * definition. 4bit tag is placed at 28 bit! | 807 | * definition. 4bit tag is placed at 28 bit! |
802 | */ | 808 | */ |
803 | if ((res >> 28) == ALC_DCVOL_EVENT) | 809 | res >>= 28; |
810 | if (res == ALC_DCVOL_EVENT) | ||
804 | alc880_uniwill_p53_dcvol_automute(codec); | 811 | alc880_uniwill_p53_dcvol_automute(codec); |
805 | else | 812 | else |
806 | alc_sku_unsol_event(codec, res); | 813 | alc_exec_unsol_event(codec, res); |
807 | } | 814 | } |
808 | 815 | ||
809 | /* | 816 | /* |
@@ -1677,7 +1684,7 @@ static const struct alc_config_preset alc880_presets[] = { | |||
1677 | .channel_mode = alc880_lg_ch_modes, | 1684 | .channel_mode = alc880_lg_ch_modes, |
1678 | .need_dac_fix = 1, | 1685 | .need_dac_fix = 1, |
1679 | .input_mux = &alc880_lg_capture_source, | 1686 | .input_mux = &alc880_lg_capture_source, |
1680 | .unsol_event = alc_sku_unsol_event, | 1687 | .unsol_event = alc880_unsol_event, |
1681 | .setup = alc880_lg_setup, | 1688 | .setup = alc880_lg_setup, |
1682 | .init_hook = alc_hp_automute, | 1689 | .init_hook = alc_hp_automute, |
1683 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1690 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c index bdf0ed4ab3e2..bb364a53f546 100644 --- a/sound/pci/hda/alc882_quirks.c +++ b/sound/pci/hda/alc882_quirks.c | |||
@@ -730,6 +730,11 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) | |||
730 | alc889A_mb31_automute(codec); | 730 | alc889A_mb31_automute(codec); |
731 | } | 731 | } |
732 | 732 | ||
733 | static void alc882_unsol_event(struct hda_codec *codec, unsigned int res) | ||
734 | { | ||
735 | alc_exec_unsol_event(codec, res >> 26); | ||
736 | } | ||
737 | |||
733 | /* | 738 | /* |
734 | * configuration and preset | 739 | * configuration and preset |
735 | */ | 740 | */ |
@@ -775,7 +780,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
775 | .channel_mode = alc885_mba21_ch_modes, | 780 | .channel_mode = alc885_mba21_ch_modes, |
776 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), | 781 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), |
777 | .input_mux = &alc882_capture_source, | 782 | .input_mux = &alc882_capture_source, |
778 | .unsol_event = alc_sku_unsol_event, | 783 | .unsol_event = alc882_unsol_event, |
779 | .setup = alc885_mba21_setup, | 784 | .setup = alc885_mba21_setup, |
780 | .init_hook = alc_hp_automute, | 785 | .init_hook = alc_hp_automute, |
781 | }, | 786 | }, |
@@ -791,7 +796,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
791 | .input_mux = &alc882_capture_source, | 796 | .input_mux = &alc882_capture_source, |
792 | .dig_out_nid = ALC882_DIGOUT_NID, | 797 | .dig_out_nid = ALC882_DIGOUT_NID, |
793 | .dig_in_nid = ALC882_DIGIN_NID, | 798 | .dig_in_nid = ALC882_DIGIN_NID, |
794 | .unsol_event = alc_sku_unsol_event, | 799 | .unsol_event = alc882_unsol_event, |
795 | .setup = alc885_mbp3_setup, | 800 | .setup = alc885_mbp3_setup, |
796 | .init_hook = alc_hp_automute, | 801 | .init_hook = alc_hp_automute, |
797 | }, | 802 | }, |
@@ -806,7 +811,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
806 | .input_mux = &mb5_capture_source, | 811 | .input_mux = &mb5_capture_source, |
807 | .dig_out_nid = ALC882_DIGOUT_NID, | 812 | .dig_out_nid = ALC882_DIGOUT_NID, |
808 | .dig_in_nid = ALC882_DIGIN_NID, | 813 | .dig_in_nid = ALC882_DIGIN_NID, |
809 | .unsol_event = alc_sku_unsol_event, | 814 | .unsol_event = alc882_unsol_event, |
810 | .setup = alc885_mb5_setup, | 815 | .setup = alc885_mb5_setup, |
811 | .init_hook = alc_hp_automute, | 816 | .init_hook = alc_hp_automute, |
812 | }, | 817 | }, |
@@ -821,7 +826,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
821 | .input_mux = &macmini3_capture_source, | 826 | .input_mux = &macmini3_capture_source, |
822 | .dig_out_nid = ALC882_DIGOUT_NID, | 827 | .dig_out_nid = ALC882_DIGOUT_NID, |
823 | .dig_in_nid = ALC882_DIGIN_NID, | 828 | .dig_in_nid = ALC882_DIGIN_NID, |
824 | .unsol_event = alc_sku_unsol_event, | 829 | .unsol_event = alc882_unsol_event, |
825 | .setup = alc885_macmini3_setup, | 830 | .setup = alc885_macmini3_setup, |
826 | .init_hook = alc_hp_automute, | 831 | .init_hook = alc_hp_automute, |
827 | }, | 832 | }, |
@@ -836,7 +841,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
836 | .input_mux = &alc889A_imac91_capture_source, | 841 | .input_mux = &alc889A_imac91_capture_source, |
837 | .dig_out_nid = ALC882_DIGOUT_NID, | 842 | .dig_out_nid = ALC882_DIGOUT_NID, |
838 | .dig_in_nid = ALC882_DIGIN_NID, | 843 | .dig_in_nid = ALC882_DIGIN_NID, |
839 | .unsol_event = alc_sku_unsol_event, | 844 | .unsol_event = alc882_unsol_event, |
840 | .setup = alc885_imac91_setup, | 845 | .setup = alc885_imac91_setup, |
841 | .init_hook = alc_hp_automute, | 846 | .init_hook = alc_hp_automute, |
842 | }, | 847 | }, |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fb35474c1203..95dfb6874941 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -469,6 +469,7 @@ struct azx { | |||
469 | unsigned int irq_pending_warned :1; | 469 | unsigned int irq_pending_warned :1; |
470 | unsigned int probing :1; /* codec probing phase */ | 470 | unsigned int probing :1; /* codec probing phase */ |
471 | unsigned int snoop:1; | 471 | unsigned int snoop:1; |
472 | unsigned int align_buffer_size:1; | ||
472 | 473 | ||
473 | /* for debugging */ | 474 | /* for debugging */ |
474 | unsigned int last_cmd[AZX_MAX_CODECS]; | 475 | unsigned int last_cmd[AZX_MAX_CODECS]; |
@@ -1690,7 +1691,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1690 | runtime->hw.rates = hinfo->rates; | 1691 | runtime->hw.rates = hinfo->rates; |
1691 | snd_pcm_limit_hw_rates(runtime); | 1692 | snd_pcm_limit_hw_rates(runtime); |
1692 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | 1693 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); |
1693 | if (align_buffer_size) | 1694 | if (chip->align_buffer_size) |
1694 | /* constrain buffer sizes to be multiple of 128 | 1695 | /* constrain buffer sizes to be multiple of 128 |
1695 | bytes. This is more efficient in terms of memory | 1696 | bytes. This is more efficient in terms of memory |
1696 | access but isn't required by the HDA spec and | 1697 | access but isn't required by the HDA spec and |
@@ -2773,8 +2774,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2773 | } | 2774 | } |
2774 | 2775 | ||
2775 | /* disable buffer size rounding to 128-byte multiples if supported */ | 2776 | /* disable buffer size rounding to 128-byte multiples if supported */ |
2777 | chip->align_buffer_size = align_buffer_size; | ||
2776 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) | 2778 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) |
2777 | align_buffer_size = 0; | 2779 | chip->align_buffer_size = 0; |
2778 | 2780 | ||
2779 | /* allow 64bit DMA address if supported by H/W */ | 2781 | /* allow 64bit DMA address if supported by H/W */ |
2780 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2782 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index d8a35da0803f..9d819c4b4923 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -282,7 +282,8 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
282 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); | 282 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); |
283 | 283 | ||
284 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | 284 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, |
285 | const struct auto_pin_cfg *cfg) | 285 | const struct auto_pin_cfg *cfg, |
286 | char *lastname, int *lastidx) | ||
286 | { | 287 | { |
287 | unsigned int def_conf, conn; | 288 | unsigned int def_conf, conn; |
288 | char name[44]; | 289 | char name[44]; |
@@ -298,6 +299,10 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
298 | return 0; | 299 | return 0; |
299 | 300 | ||
300 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); | 301 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); |
302 | if (!strcmp(name, lastname) && idx == *lastidx) | ||
303 | idx++; | ||
304 | strncpy(lastname, name, 44); | ||
305 | *lastidx = idx; | ||
301 | err = snd_hda_jack_add_kctl(codec, nid, name, idx); | 306 | err = snd_hda_jack_add_kctl(codec, nid, name, idx); |
302 | if (err < 0) | 307 | if (err < 0) |
303 | return err; | 308 | return err; |
@@ -311,41 +316,42 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, | |||
311 | const struct auto_pin_cfg *cfg) | 316 | const struct auto_pin_cfg *cfg) |
312 | { | 317 | { |
313 | const hda_nid_t *p; | 318 | const hda_nid_t *p; |
314 | int i, err; | 319 | int i, err, lastidx = 0; |
320 | char lastname[44] = ""; | ||
315 | 321 | ||
316 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { | 322 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { |
317 | err = add_jack_kctl(codec, *p, cfg); | 323 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); |
318 | if (err < 0) | 324 | if (err < 0) |
319 | return err; | 325 | return err; |
320 | } | 326 | } |
321 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { | 327 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { |
322 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 328 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
323 | break; | 329 | break; |
324 | err = add_jack_kctl(codec, *p, cfg); | 330 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); |
325 | if (err < 0) | 331 | if (err < 0) |
326 | return err; | 332 | return err; |
327 | } | 333 | } |
328 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { | 334 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { |
329 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 335 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
330 | break; | 336 | break; |
331 | err = add_jack_kctl(codec, *p, cfg); | 337 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); |
332 | if (err < 0) | 338 | if (err < 0) |
333 | return err; | 339 | return err; |
334 | } | 340 | } |
335 | for (i = 0; i < cfg->num_inputs; i++) { | 341 | for (i = 0; i < cfg->num_inputs; i++) { |
336 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); | 342 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); |
337 | if (err < 0) | 343 | if (err < 0) |
338 | return err; | 344 | return err; |
339 | } | 345 | } |
340 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { | 346 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { |
341 | err = add_jack_kctl(codec, *p, cfg); | 347 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); |
342 | if (err < 0) | 348 | if (err < 0) |
343 | return err; | 349 | return err; |
344 | } | 350 | } |
345 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); | 351 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); |
346 | if (err < 0) | 352 | if (err < 0) |
347 | return err; | 353 | return err; |
348 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); | 354 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); |
349 | if (err < 0) | 355 | if (err < 0) |
350 | return err; | 356 | return err; |
351 | return 0; | 357 | return 0; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 8a32a69c83c3..a7a5733aa4d2 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -3027,7 +3027,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3027 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | 3027 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), |
3028 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), | 3028 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), |
3029 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), | 3029 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), |
3030 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 3030 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO), |
3031 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO), | 3031 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO), |
3032 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), | 3032 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), |
3033 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), | 3033 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5e82acf77c5a..a8e82be3d2fc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -177,6 +177,7 @@ struct alc_spec { | |||
177 | unsigned int detect_lo:1; /* Line-out detection enabled */ | 177 | unsigned int detect_lo:1; /* Line-out detection enabled */ |
178 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ | 178 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ |
179 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ | 179 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ |
180 | unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ | ||
180 | 181 | ||
181 | /* other flags */ | 182 | /* other flags */ |
182 | unsigned int no_analog :1; /* digital I/O only */ | 183 | unsigned int no_analog :1; /* digital I/O only */ |
@@ -185,7 +186,6 @@ struct alc_spec { | |||
185 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ | 186 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ |
186 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ | 187 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ |
187 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ | 188 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ |
188 | unsigned int use_jack_tbl:1; /* 1 for model=auto */ | ||
189 | 189 | ||
190 | /* auto-mute control */ | 190 | /* auto-mute control */ |
191 | int automute_mode; | 191 | int automute_mode; |
@@ -496,13 +496,24 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
496 | 496 | ||
497 | for (i = 0; i < num_pins; i++) { | 497 | for (i = 0; i < num_pins; i++) { |
498 | hda_nid_t nid = pins[i]; | 498 | hda_nid_t nid = pins[i]; |
499 | unsigned int val; | ||
499 | if (!nid) | 500 | if (!nid) |
500 | break; | 501 | break; |
501 | switch (spec->automute_mode) { | 502 | switch (spec->automute_mode) { |
502 | case ALC_AUTOMUTE_PIN: | 503 | case ALC_AUTOMUTE_PIN: |
504 | /* don't reset VREF value in case it's controlling | ||
505 | * the amp (see alc861_fixup_asus_amp_vref_0f()) | ||
506 | */ | ||
507 | if (spec->keep_vref_in_automute) { | ||
508 | val = snd_hda_codec_read(codec, nid, 0, | ||
509 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
510 | val &= ~PIN_HP; | ||
511 | } else | ||
512 | val = 0; | ||
513 | val |= pin_bits; | ||
503 | snd_hda_codec_write(codec, nid, 0, | 514 | snd_hda_codec_write(codec, nid, 0, |
504 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 515 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
505 | pin_bits); | 516 | val); |
506 | break; | 517 | break; |
507 | case ALC_AUTOMUTE_AMP: | 518 | case ALC_AUTOMUTE_AMP: |
508 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | 519 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
@@ -621,17 +632,10 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
621 | alc_mux_select(codec, 0, spec->int_mic_idx, false); | 632 | alc_mux_select(codec, 0, spec->int_mic_idx, false); |
622 | } | 633 | } |
623 | 634 | ||
624 | /* unsolicited event for HP jack sensing */ | 635 | /* handle the specified unsol action (ALC_XXX_EVENT) */ |
625 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 636 | static void alc_exec_unsol_event(struct hda_codec *codec, int action) |
626 | { | 637 | { |
627 | struct alc_spec *spec = codec->spec; | 638 | switch (action) { |
628 | if (codec->vendor_id == 0x10ec0880) | ||
629 | res >>= 28; | ||
630 | else | ||
631 | res >>= 26; | ||
632 | if (spec->use_jack_tbl) | ||
633 | res = snd_hda_jack_get_action(codec, res); | ||
634 | switch (res) { | ||
635 | case ALC_HP_EVENT: | 639 | case ALC_HP_EVENT: |
636 | alc_hp_automute(codec); | 640 | alc_hp_automute(codec); |
637 | break; | 641 | break; |
@@ -645,6 +649,17 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
645 | snd_hda_jack_report_sync(codec); | 649 | snd_hda_jack_report_sync(codec); |
646 | } | 650 | } |
647 | 651 | ||
652 | /* unsolicited event for HP jack sensing */ | ||
653 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | ||
654 | { | ||
655 | if (codec->vendor_id == 0x10ec0880) | ||
656 | res >>= 28; | ||
657 | else | ||
658 | res >>= 26; | ||
659 | res = snd_hda_jack_get_action(codec, res); | ||
660 | alc_exec_unsol_event(codec, res); | ||
661 | } | ||
662 | |||
648 | /* call init functions of standard auto-mute helpers */ | 663 | /* call init functions of standard auto-mute helpers */ |
649 | static void alc_inithook(struct hda_codec *codec) | 664 | static void alc_inithook(struct hda_codec *codec) |
650 | { | 665 | { |
@@ -1883,7 +1898,7 @@ static const struct snd_kcontrol_new alc_beep_mixer[] = { | |||
1883 | }; | 1898 | }; |
1884 | #endif | 1899 | #endif |
1885 | 1900 | ||
1886 | static int alc_build_controls(struct hda_codec *codec) | 1901 | static int __alc_build_controls(struct hda_codec *codec) |
1887 | { | 1902 | { |
1888 | struct alc_spec *spec = codec->spec; | 1903 | struct alc_spec *spec = codec->spec; |
1889 | struct snd_kcontrol *kctl = NULL; | 1904 | struct snd_kcontrol *kctl = NULL; |
@@ -2029,11 +2044,16 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2029 | 2044 | ||
2030 | alc_free_kctls(codec); /* no longer needed */ | 2045 | alc_free_kctls(codec); /* no longer needed */ |
2031 | 2046 | ||
2032 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 2047 | return 0; |
2048 | } | ||
2049 | |||
2050 | static int alc_build_controls(struct hda_codec *codec) | ||
2051 | { | ||
2052 | struct alc_spec *spec = codec->spec; | ||
2053 | int err = __alc_build_controls(codec); | ||
2033 | if (err < 0) | 2054 | if (err < 0) |
2034 | return err; | 2055 | return err; |
2035 | 2056 | return snd_hda_jack_add_kctls(codec, &spec->autocfg); | |
2036 | return 0; | ||
2037 | } | 2057 | } |
2038 | 2058 | ||
2039 | 2059 | ||
@@ -3233,7 +3253,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3233 | int i, err, noutputs; | 3253 | int i, err, noutputs; |
3234 | 3254 | ||
3235 | noutputs = cfg->line_outs; | 3255 | noutputs = cfg->line_outs; |
3236 | if (spec->multi_ios > 0) | 3256 | if (spec->multi_ios > 0 && cfg->line_outs < 3) |
3237 | noutputs += spec->multi_ios; | 3257 | noutputs += spec->multi_ios; |
3238 | 3258 | ||
3239 | for (i = 0; i < noutputs; i++) { | 3259 | for (i = 0; i < noutputs; i++) { |
@@ -3904,7 +3924,6 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
3904 | static void alc_auto_init_std(struct hda_codec *codec) | 3924 | static void alc_auto_init_std(struct hda_codec *codec) |
3905 | { | 3925 | { |
3906 | struct alc_spec *spec = codec->spec; | 3926 | struct alc_spec *spec = codec->spec; |
3907 | spec->use_jack_tbl = 1; | ||
3908 | alc_auto_init_multi_out(codec); | 3927 | alc_auto_init_multi_out(codec); |
3909 | alc_auto_init_extra_out(codec); | 3928 | alc_auto_init_extra_out(codec); |
3910 | alc_auto_init_analog_input(codec); | 3929 | alc_auto_init_analog_input(codec); |
@@ -4168,6 +4187,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
4168 | codec->patch_ops = alc_patch_ops; | 4187 | codec->patch_ops = alc_patch_ops; |
4169 | if (board_config == ALC_MODEL_AUTO) | 4188 | if (board_config == ALC_MODEL_AUTO) |
4170 | spec->init_hook = alc_auto_init_std; | 4189 | spec->init_hook = alc_auto_init_std; |
4190 | else | ||
4191 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4171 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4192 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4172 | if (!spec->loopback.amplist) | 4193 | if (!spec->loopback.amplist) |
4173 | spec->loopback.amplist = alc880_loopbacks; | 4194 | spec->loopback.amplist = alc880_loopbacks; |
@@ -4297,6 +4318,8 @@ static int patch_alc260(struct hda_codec *codec) | |||
4297 | codec->patch_ops = alc_patch_ops; | 4318 | codec->patch_ops = alc_patch_ops; |
4298 | if (board_config == ALC_MODEL_AUTO) | 4319 | if (board_config == ALC_MODEL_AUTO) |
4299 | spec->init_hook = alc_auto_init_std; | 4320 | spec->init_hook = alc_auto_init_std; |
4321 | else | ||
4322 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4300 | spec->shutup = alc_eapd_shutup; | 4323 | spec->shutup = alc_eapd_shutup; |
4301 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4324 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4302 | if (!spec->loopback.amplist) | 4325 | if (!spec->loopback.amplist) |
@@ -4691,6 +4714,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
4691 | codec->patch_ops = alc_patch_ops; | 4714 | codec->patch_ops = alc_patch_ops; |
4692 | if (board_config == ALC_MODEL_AUTO) | 4715 | if (board_config == ALC_MODEL_AUTO) |
4693 | spec->init_hook = alc_auto_init_std; | 4716 | spec->init_hook = alc_auto_init_std; |
4717 | else | ||
4718 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4694 | 4719 | ||
4695 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4720 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4696 | if (!spec->loopback.amplist) | 4721 | if (!spec->loopback.amplist) |
@@ -4722,7 +4747,6 @@ enum { | |||
4722 | ALC262_FIXUP_FSC_H270, | 4747 | ALC262_FIXUP_FSC_H270, |
4723 | ALC262_FIXUP_HP_Z200, | 4748 | ALC262_FIXUP_HP_Z200, |
4724 | ALC262_FIXUP_TYAN, | 4749 | ALC262_FIXUP_TYAN, |
4725 | ALC262_FIXUP_TOSHIBA_RX1, | ||
4726 | ALC262_FIXUP_LENOVO_3000, | 4750 | ALC262_FIXUP_LENOVO_3000, |
4727 | ALC262_FIXUP_BENQ, | 4751 | ALC262_FIXUP_BENQ, |
4728 | ALC262_FIXUP_BENQ_T31, | 4752 | ALC262_FIXUP_BENQ_T31, |
@@ -4752,16 +4776,6 @@ static const struct alc_fixup alc262_fixups[] = { | |||
4752 | { } | 4776 | { } |
4753 | } | 4777 | } |
4754 | }, | 4778 | }, |
4755 | [ALC262_FIXUP_TOSHIBA_RX1] = { | ||
4756 | .type = ALC_FIXUP_PINS, | ||
4757 | .v.pins = (const struct alc_pincfg[]) { | ||
4758 | { 0x14, 0x90170110 }, /* speaker */ | ||
4759 | { 0x15, 0x0421101f }, /* HP */ | ||
4760 | { 0x1a, 0x40f000f0 }, /* N/A */ | ||
4761 | { 0x1b, 0x40f000f0 }, /* N/A */ | ||
4762 | { 0x1e, 0x40f000f0 }, /* N/A */ | ||
4763 | } | ||
4764 | }, | ||
4765 | [ALC262_FIXUP_LENOVO_3000] = { | 4779 | [ALC262_FIXUP_LENOVO_3000] = { |
4766 | .type = ALC_FIXUP_VERBS, | 4780 | .type = ALC_FIXUP_VERBS, |
4767 | .v.verbs = (const struct hda_verb[]) { | 4781 | .v.verbs = (const struct hda_verb[]) { |
@@ -4794,8 +4808,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { | |||
4794 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), | 4808 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), |
4795 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), | 4809 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), |
4796 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), | 4810 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), |
4797 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", | ||
4798 | ALC262_FIXUP_TOSHIBA_RX1), | ||
4799 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), | 4811 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), |
4800 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), | 4812 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), |
4801 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), | 4813 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), |
@@ -5364,7 +5376,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5364 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 5376 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
5365 | ALC269_FIXUP_AMIC), | 5377 | ALC269_FIXUP_AMIC), |
5366 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), | 5378 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), |
5367 | SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC), | ||
5368 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), | 5379 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), |
5369 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), | 5380 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), |
5370 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), | 5381 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), |
@@ -5573,8 +5584,28 @@ static const struct hda_amp_list alc861_loopbacks[] = { | |||
5573 | /* Pin config fixes */ | 5584 | /* Pin config fixes */ |
5574 | enum { | 5585 | enum { |
5575 | PINFIX_FSC_AMILO_PI1505, | 5586 | PINFIX_FSC_AMILO_PI1505, |
5587 | PINFIX_ASUS_A6RP, | ||
5576 | }; | 5588 | }; |
5577 | 5589 | ||
5590 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | ||
5591 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | ||
5592 | const struct alc_fixup *fix, int action) | ||
5593 | { | ||
5594 | struct alc_spec *spec = codec->spec; | ||
5595 | unsigned int val; | ||
5596 | |||
5597 | if (action != ALC_FIXUP_ACT_INIT) | ||
5598 | return; | ||
5599 | val = snd_hda_codec_read(codec, 0x0f, 0, | ||
5600 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5601 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) | ||
5602 | val |= AC_PINCTL_IN_EN; | ||
5603 | val |= AC_PINCTL_VREF_50; | ||
5604 | snd_hda_codec_write(codec, 0x0f, 0, | ||
5605 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); | ||
5606 | spec->keep_vref_in_automute = 1; | ||
5607 | } | ||
5608 | |||
5578 | static const struct alc_fixup alc861_fixups[] = { | 5609 | static const struct alc_fixup alc861_fixups[] = { |
5579 | [PINFIX_FSC_AMILO_PI1505] = { | 5610 | [PINFIX_FSC_AMILO_PI1505] = { |
5580 | .type = ALC_FIXUP_PINS, | 5611 | .type = ALC_FIXUP_PINS, |
@@ -5584,9 +5615,15 @@ static const struct alc_fixup alc861_fixups[] = { | |||
5584 | { } | 5615 | { } |
5585 | } | 5616 | } |
5586 | }, | 5617 | }, |
5618 | [PINFIX_ASUS_A6RP] = { | ||
5619 | .type = ALC_FIXUP_FUNC, | ||
5620 | .v.func = alc861_fixup_asus_amp_vref_0f, | ||
5621 | }, | ||
5587 | }; | 5622 | }; |
5588 | 5623 | ||
5589 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { | 5624 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
5625 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), | ||
5626 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), | ||
5590 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), | 5627 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), |
5591 | {} | 5628 | {} |
5592 | }; | 5629 | }; |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3556408d6ece..948f0be2f4f3 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1608,7 +1608,7 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { | |||
1608 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, | 1608 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, |
1609 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1609 | "Alienware M17x", STAC_ALIENWARE_M17X), |
1610 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, | 1610 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, |
1611 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1611 | "Alienware M17x R3", STAC_DELL_EQ), |
1612 | {} /* terminator */ | 1612 | {} /* terminator */ |
1613 | }; | 1613 | }; |
1614 | 1614 | ||
@@ -4163,13 +4163,15 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | |||
4163 | return 1; | 4163 | return 1; |
4164 | } | 4164 | } |
4165 | 4165 | ||
4166 | static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) | 4166 | static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) |
4167 | { | 4167 | { |
4168 | int i; | 4168 | int i; |
4169 | for (i = 0; i < cfg->hp_outs; i++) | 4169 | for (i = 0; i < cfg->hp_outs; i++) |
4170 | if (cfg->hp_pins[i] == nid) | 4170 | if (cfg->hp_pins[i] == nid) |
4171 | return 1; /* nid is a HP-Out */ | 4171 | return 1; /* nid is a HP-Out */ |
4172 | 4172 | for (i = 0; i < cfg->line_outs; i++) | |
4173 | if (cfg->line_out_pins[i] == nid) | ||
4174 | return 1; /* nid is a line-Out */ | ||
4173 | return 0; /* nid is not a HP-Out */ | 4175 | return 0; /* nid is not a HP-Out */ |
4174 | }; | 4176 | }; |
4175 | 4177 | ||
@@ -4375,7 +4377,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4375 | continue; | 4377 | continue; |
4376 | } | 4378 | } |
4377 | 4379 | ||
4378 | if (is_nid_hp_pin(cfg, nid)) | 4380 | if (is_nid_out_jack_pin(cfg, nid)) |
4379 | continue; /* already has an unsol event */ | 4381 | continue; /* already has an unsol event */ |
4380 | 4382 | ||
4381 | pinctl = snd_hda_codec_read(codec, nid, 0, | 4383 | pinctl = snd_hda_codec_read(codec, nid, 0, |
@@ -4868,7 +4870,14 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) | |||
4868 | /* BIOS bug: unfilled OEM string */ | 4870 | /* BIOS bug: unfilled OEM string */ |
4869 | if (strstr(dev->name, "HP_Mute_LED_P_G")) { | 4871 | if (strstr(dev->name, "HP_Mute_LED_P_G")) { |
4870 | set_hp_led_gpio(codec); | 4872 | set_hp_led_gpio(codec); |
4871 | spec->gpio_led_polarity = 1; | 4873 | switch (codec->subsystem_id) { |
4874 | case 0x103c148a: | ||
4875 | spec->gpio_led_polarity = 0; | ||
4876 | break; | ||
4877 | default: | ||
4878 | spec->gpio_led_polarity = 1; | ||
4879 | break; | ||
4880 | } | ||
4872 | return 1; | 4881 | return 1; |
4873 | } | 4882 | } |
4874 | } | 4883 | } |
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index e57b89e8aa89..94ab728f5ca8 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c | |||
@@ -286,17 +286,22 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, | |||
286 | snd_card_free(card); | 286 | snd_card_free(card); |
287 | return err; | 287 | return err; |
288 | } | 288 | } |
289 | if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) { | 289 | err = snd_ymfpci_mixer(chip, rear_switch[dev]); |
290 | if (err < 0) { | ||
290 | snd_card_free(card); | 291 | snd_card_free(card); |
291 | return err; | 292 | return err; |
292 | } | 293 | } |
293 | if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) { | 294 | if (chip->ac97->ext_id & AC97_EI_SDAC) { |
294 | snd_card_free(card); | 295 | err = snd_ymfpci_pcm_4ch(chip, 2, NULL); |
295 | return err; | 296 | if (err < 0) { |
296 | } | 297 | snd_card_free(card); |
297 | if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) { | 298 | return err; |
298 | snd_card_free(card); | 299 | } |
299 | return err; | 300 | err = snd_ymfpci_pcm2(chip, 3, NULL); |
301 | if (err < 0) { | ||
302 | snd_card_free(card); | ||
303 | return err; | ||
304 | } | ||
300 | } | 305 | } |
301 | if ((err = snd_ymfpci_timer(chip, 0)) < 0) { | 306 | if ((err = snd_ymfpci_timer(chip, 0)) < 0) { |
302 | snd_card_free(card); | 307 | snd_card_free(card); |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 03ee4e365311..12a9a2b03387 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
@@ -1614,6 +1614,14 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1614 | return change; | 1614 | return change; |
1615 | } | 1615 | } |
1616 | 1616 | ||
1617 | static struct snd_kcontrol_new snd_ymfpci_dup4ch __devinitdata = { | ||
1618 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1619 | .name = "4ch Duplication", | ||
1620 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
1621 | .info = snd_ymfpci_info_dup4ch, | ||
1622 | .get = snd_ymfpci_get_dup4ch, | ||
1623 | .put = snd_ymfpci_put_dup4ch, | ||
1624 | }; | ||
1617 | 1625 | ||
1618 | static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { | 1626 | static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { |
1619 | { | 1627 | { |
@@ -1642,13 +1650,6 @@ YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL), | |||
1642 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0), | 1650 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0), |
1643 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0), | 1651 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0), |
1644 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4), | 1652 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4), |
1645 | { | ||
1646 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1647 | .name = "4ch Duplication", | ||
1648 | .info = snd_ymfpci_info_dup4ch, | ||
1649 | .get = snd_ymfpci_get_dup4ch, | ||
1650 | .put = snd_ymfpci_put_dup4ch, | ||
1651 | }, | ||
1652 | }; | 1653 | }; |
1653 | 1654 | ||
1654 | 1655 | ||
@@ -1838,6 +1839,12 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) | |||
1838 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0) | 1839 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0) |
1839 | return err; | 1840 | return err; |
1840 | } | 1841 | } |
1842 | if (chip->ac97->ext_id & AC97_EI_SDAC) { | ||
1843 | kctl = snd_ctl_new1(&snd_ymfpci_dup4ch, chip); | ||
1844 | err = snd_ctl_add(chip->card, kctl); | ||
1845 | if (err < 0) | ||
1846 | return err; | ||
1847 | } | ||
1841 | 1848 | ||
1842 | /* add S/PDIF control */ | 1849 | /* add S/PDIF control */ |
1843 | if (snd_BUG_ON(!chip->pcm_spdif)) | 1850 | if (snd_BUG_ON(!chip->pcm_spdif)) |