diff options
Diffstat (limited to 'sound')
38 files changed, 567 insertions, 461 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/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c index e09f144177f5..c99c6078be33 100644 --- a/sound/isa/sb/emu8000_patch.c +++ b/sound/isa/sb/emu8000_patch.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "emu8000_local.h" | 22 | #include "emu8000_local.h" |
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
25 | #include <linux/moduleparam.h> | ||
26 | 25 | ||
27 | static int emu8000_reset_addr; | 26 | static int emu8000_reset_addr; |
28 | module_param(emu8000_reset_addr, int, 0444); | 27 | module_param(emu8000_reset_addr, int, 0444); |
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_codec.c b/sound/pci/hda/hda_codec.c index 4df72c0e8c37..c2c65f63bf06 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1447,7 +1447,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1447 | for (i = 0; i < c->cvt_setups.used; i++) { | 1447 | for (i = 0; i < c->cvt_setups.used; i++) { |
1448 | p = snd_array_elem(&c->cvt_setups, i); | 1448 | p = snd_array_elem(&c->cvt_setups, i); |
1449 | if (!p->active && p->stream_tag == stream_tag && | 1449 | if (!p->active && p->stream_tag == stream_tag && |
1450 | get_wcaps_type(get_wcaps(codec, p->nid)) == type) | 1450 | get_wcaps_type(get_wcaps(c, p->nid)) == type) |
1451 | p->dirty = 1; | 1451 | p->dirty = 1; |
1452 | } | 1452 | } |
1453 | } | 1453 | } |
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_ca0132.c b/sound/pci/hda/patch_ca0132.c index 35abe3c62908..21d91d580da8 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -728,18 +728,19 @@ static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol, | |||
728 | 728 | ||
729 | err = chipio_read(codec, REG_CODEC_MUTE, &data); | 729 | err = chipio_read(codec, REG_CODEC_MUTE, &data); |
730 | if (err < 0) | 730 | if (err < 0) |
731 | return err; | 731 | goto exit; |
732 | 732 | ||
733 | /* *valp 0 is mute, 1 is unmute */ | 733 | /* *valp 0 is mute, 1 is unmute */ |
734 | data = (data & 0x7f) | (*valp ? 0 : 0x80); | 734 | data = (data & 0x7f) | (*valp ? 0 : 0x80); |
735 | chipio_write(codec, REG_CODEC_MUTE, data); | 735 | err = chipio_write(codec, REG_CODEC_MUTE, data); |
736 | if (err < 0) | 736 | if (err < 0) |
737 | return err; | 737 | goto exit; |
738 | 738 | ||
739 | spec->curr_hp_switch = *valp; | 739 | spec->curr_hp_switch = *valp; |
740 | 740 | ||
741 | exit: | ||
741 | snd_hda_power_down(codec); | 742 | snd_hda_power_down(codec); |
742 | return 1; | 743 | return err < 0 ? err : 1; |
743 | } | 744 | } |
744 | 745 | ||
745 | static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol, | 746 | static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol, |
@@ -770,18 +771,19 @@ static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol, | |||
770 | 771 | ||
771 | err = chipio_read(codec, REG_CODEC_MUTE, &data); | 772 | err = chipio_read(codec, REG_CODEC_MUTE, &data); |
772 | if (err < 0) | 773 | if (err < 0) |
773 | return err; | 774 | goto exit; |
774 | 775 | ||
775 | /* *valp 0 is mute, 1 is unmute */ | 776 | /* *valp 0 is mute, 1 is unmute */ |
776 | data = (data & 0xef) | (*valp ? 0 : 0x10); | 777 | data = (data & 0xef) | (*valp ? 0 : 0x10); |
777 | chipio_write(codec, REG_CODEC_MUTE, data); | 778 | err = chipio_write(codec, REG_CODEC_MUTE, data); |
778 | if (err < 0) | 779 | if (err < 0) |
779 | return err; | 780 | goto exit; |
780 | 781 | ||
781 | spec->curr_speaker_switch = *valp; | 782 | spec->curr_speaker_switch = *valp; |
782 | 783 | ||
784 | exit: | ||
783 | snd_hda_power_down(codec); | 785 | snd_hda_power_down(codec); |
784 | return 1; | 786 | return err < 0 ? err : 1; |
785 | } | 787 | } |
786 | 788 | ||
787 | static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol, | 789 | static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol, |
@@ -819,25 +821,26 @@ static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol, | |||
819 | 821 | ||
820 | err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data); | 822 | err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data); |
821 | if (err < 0) | 823 | if (err < 0) |
822 | return err; | 824 | goto exit; |
823 | 825 | ||
824 | val = 31 - left_vol; | 826 | val = 31 - left_vol; |
825 | data = (data & 0xe0) | val; | 827 | data = (data & 0xe0) | val; |
826 | chipio_write(codec, REG_CODEC_HP_VOL_L, data); | 828 | err = chipio_write(codec, REG_CODEC_HP_VOL_L, data); |
827 | if (err < 0) | 829 | if (err < 0) |
828 | return err; | 830 | goto exit; |
829 | 831 | ||
830 | val = 31 - right_vol; | 832 | val = 31 - right_vol; |
831 | data = (data & 0xe0) | val; | 833 | data = (data & 0xe0) | val; |
832 | chipio_write(codec, REG_CODEC_HP_VOL_R, data); | 834 | err = chipio_write(codec, REG_CODEC_HP_VOL_R, data); |
833 | if (err < 0) | 835 | if (err < 0) |
834 | return err; | 836 | goto exit; |
835 | 837 | ||
836 | spec->curr_hp_volume[0] = left_vol; | 838 | spec->curr_hp_volume[0] = left_vol; |
837 | spec->curr_hp_volume[1] = right_vol; | 839 | spec->curr_hp_volume[1] = right_vol; |
838 | 840 | ||
841 | exit: | ||
839 | snd_hda_power_down(codec); | 842 | snd_hda_power_down(codec); |
840 | return 1; | 843 | return err < 0 ? err : 1; |
841 | } | 844 | } |
842 | 845 | ||
843 | static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid) | 846 | static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid) |
@@ -936,6 +939,8 @@ static int ca0132_build_controls(struct hda_codec *codec) | |||
936 | if (err < 0) | 939 | if (err < 0) |
937 | return err; | 940 | return err; |
938 | err = add_in_volume(codec, spec->dig_in, "IEC958"); | 941 | err = add_in_volume(codec, spec->dig_in, "IEC958"); |
942 | if (err < 0) | ||
943 | return err; | ||
939 | } | 944 | } |
940 | return 0; | 945 | return 0; |
941 | } | 946 | } |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 0e99357e822c..bc5a993d1146 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -988,8 +988,10 @@ static void cs_automic(struct hda_codec *codec) | |||
988 | change_cur_input(codec, !spec->automic_idx, 0); | 988 | change_cur_input(codec, !spec->automic_idx, 0); |
989 | } else { | 989 | } else { |
990 | if (present) { | 990 | if (present) { |
991 | spec->last_input = spec->cur_input; | 991 | if (spec->cur_input != spec->automic_idx) { |
992 | spec->cur_input = spec->automic_idx; | 992 | spec->last_input = spec->cur_input; |
993 | spec->cur_input = spec->automic_idx; | ||
994 | } | ||
993 | } else { | 995 | } else { |
994 | spec->cur_input = spec->last_input; | 996 | spec->cur_input = spec->last_input; |
995 | } | 997 | } |
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..3647baa9bfed 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -80,6 +80,8 @@ enum { | |||
80 | ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ | 80 | ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ |
81 | }; | 81 | }; |
82 | 82 | ||
83 | #define MAX_VOL_NIDS 0x40 | ||
84 | |||
83 | struct alc_spec { | 85 | struct alc_spec { |
84 | /* codec parameterization */ | 86 | /* codec parameterization */ |
85 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 87 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
@@ -118,8 +120,8 @@ struct alc_spec { | |||
118 | const hda_nid_t *capsrc_nids; | 120 | const hda_nid_t *capsrc_nids; |
119 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 121 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
120 | hda_nid_t mixer_nid; /* analog-mixer NID */ | 122 | hda_nid_t mixer_nid; /* analog-mixer NID */ |
121 | DECLARE_BITMAP(vol_ctls, 0x20 << 1); | 123 | DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1); |
122 | DECLARE_BITMAP(sw_ctls, 0x20 << 1); | 124 | DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1); |
123 | 125 | ||
124 | /* capture setup for dynamic dual-adc switch */ | 126 | /* capture setup for dynamic dual-adc switch */ |
125 | hda_nid_t cur_adc; | 127 | hda_nid_t cur_adc; |
@@ -177,6 +179,7 @@ struct alc_spec { | |||
177 | unsigned int detect_lo:1; /* Line-out detection enabled */ | 179 | unsigned int detect_lo:1; /* Line-out detection enabled */ |
178 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ | 180 | 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 */ | 181 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ |
182 | unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ | ||
180 | 183 | ||
181 | /* other flags */ | 184 | /* other flags */ |
182 | unsigned int no_analog :1; /* digital I/O only */ | 185 | unsigned int no_analog :1; /* digital I/O only */ |
@@ -185,7 +188,6 @@ struct alc_spec { | |||
185 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ | 188 | 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() */ | 189 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ |
187 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ | 190 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ |
188 | unsigned int use_jack_tbl:1; /* 1 for model=auto */ | ||
189 | 191 | ||
190 | /* auto-mute control */ | 192 | /* auto-mute control */ |
191 | int automute_mode; | 193 | int automute_mode; |
@@ -496,13 +498,24 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
496 | 498 | ||
497 | for (i = 0; i < num_pins; i++) { | 499 | for (i = 0; i < num_pins; i++) { |
498 | hda_nid_t nid = pins[i]; | 500 | hda_nid_t nid = pins[i]; |
501 | unsigned int val; | ||
499 | if (!nid) | 502 | if (!nid) |
500 | break; | 503 | break; |
501 | switch (spec->automute_mode) { | 504 | switch (spec->automute_mode) { |
502 | case ALC_AUTOMUTE_PIN: | 505 | case ALC_AUTOMUTE_PIN: |
506 | /* don't reset VREF value in case it's controlling | ||
507 | * the amp (see alc861_fixup_asus_amp_vref_0f()) | ||
508 | */ | ||
509 | if (spec->keep_vref_in_automute) { | ||
510 | val = snd_hda_codec_read(codec, nid, 0, | ||
511 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
512 | val &= ~PIN_HP; | ||
513 | } else | ||
514 | val = 0; | ||
515 | val |= pin_bits; | ||
503 | snd_hda_codec_write(codec, nid, 0, | 516 | snd_hda_codec_write(codec, nid, 0, |
504 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 517 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
505 | pin_bits); | 518 | val); |
506 | break; | 519 | break; |
507 | case ALC_AUTOMUTE_AMP: | 520 | case ALC_AUTOMUTE_AMP: |
508 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | 521 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
@@ -621,17 +634,10 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
621 | alc_mux_select(codec, 0, spec->int_mic_idx, false); | 634 | alc_mux_select(codec, 0, spec->int_mic_idx, false); |
622 | } | 635 | } |
623 | 636 | ||
624 | /* unsolicited event for HP jack sensing */ | 637 | /* handle the specified unsol action (ALC_XXX_EVENT) */ |
625 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 638 | static void alc_exec_unsol_event(struct hda_codec *codec, int action) |
626 | { | 639 | { |
627 | struct alc_spec *spec = codec->spec; | 640 | 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: | 641 | case ALC_HP_EVENT: |
636 | alc_hp_automute(codec); | 642 | alc_hp_automute(codec); |
637 | break; | 643 | break; |
@@ -645,6 +651,17 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
645 | snd_hda_jack_report_sync(codec); | 651 | snd_hda_jack_report_sync(codec); |
646 | } | 652 | } |
647 | 653 | ||
654 | /* unsolicited event for HP jack sensing */ | ||
655 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | ||
656 | { | ||
657 | if (codec->vendor_id == 0x10ec0880) | ||
658 | res >>= 28; | ||
659 | else | ||
660 | res >>= 26; | ||
661 | res = snd_hda_jack_get_action(codec, res); | ||
662 | alc_exec_unsol_event(codec, res); | ||
663 | } | ||
664 | |||
648 | /* call init functions of standard auto-mute helpers */ | 665 | /* call init functions of standard auto-mute helpers */ |
649 | static void alc_inithook(struct hda_codec *codec) | 666 | static void alc_inithook(struct hda_codec *codec) |
650 | { | 667 | { |
@@ -1840,6 +1857,8 @@ static const char * const alc_slave_vols[] = { | |||
1840 | "Speaker Playback Volume", | 1857 | "Speaker Playback Volume", |
1841 | "Mono Playback Volume", | 1858 | "Mono Playback Volume", |
1842 | "Line-Out Playback Volume", | 1859 | "Line-Out Playback Volume", |
1860 | "CLFE Playback Volume", | ||
1861 | "Bass Speaker Playback Volume", | ||
1843 | "PCM Playback Volume", | 1862 | "PCM Playback Volume", |
1844 | NULL, | 1863 | NULL, |
1845 | }; | 1864 | }; |
@@ -1855,6 +1874,8 @@ static const char * const alc_slave_sws[] = { | |||
1855 | "Mono Playback Switch", | 1874 | "Mono Playback Switch", |
1856 | "IEC958 Playback Switch", | 1875 | "IEC958 Playback Switch", |
1857 | "Line-Out Playback Switch", | 1876 | "Line-Out Playback Switch", |
1877 | "CLFE Playback Switch", | ||
1878 | "Bass Speaker Playback Switch", | ||
1858 | "PCM Playback Switch", | 1879 | "PCM Playback Switch", |
1859 | NULL, | 1880 | NULL, |
1860 | }; | 1881 | }; |
@@ -1883,7 +1904,7 @@ static const struct snd_kcontrol_new alc_beep_mixer[] = { | |||
1883 | }; | 1904 | }; |
1884 | #endif | 1905 | #endif |
1885 | 1906 | ||
1886 | static int alc_build_controls(struct hda_codec *codec) | 1907 | static int __alc_build_controls(struct hda_codec *codec) |
1887 | { | 1908 | { |
1888 | struct alc_spec *spec = codec->spec; | 1909 | struct alc_spec *spec = codec->spec; |
1889 | struct snd_kcontrol *kctl = NULL; | 1910 | struct snd_kcontrol *kctl = NULL; |
@@ -2029,11 +2050,16 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2029 | 2050 | ||
2030 | alc_free_kctls(codec); /* no longer needed */ | 2051 | alc_free_kctls(codec); /* no longer needed */ |
2031 | 2052 | ||
2032 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 2053 | return 0; |
2054 | } | ||
2055 | |||
2056 | static int alc_build_controls(struct hda_codec *codec) | ||
2057 | { | ||
2058 | struct alc_spec *spec = codec->spec; | ||
2059 | int err = __alc_build_controls(codec); | ||
2033 | if (err < 0) | 2060 | if (err < 0) |
2034 | return err; | 2061 | return err; |
2035 | 2062 | return snd_hda_jack_add_kctls(codec, &spec->autocfg); | |
2036 | return 0; | ||
2037 | } | 2063 | } |
2038 | 2064 | ||
2039 | 2065 | ||
@@ -2298,7 +2324,7 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
2298 | "%s Analog", codec->chip_name); | 2324 | "%s Analog", codec->chip_name); |
2299 | info->name = spec->stream_name_analog; | 2325 | info->name = spec->stream_name_analog; |
2300 | 2326 | ||
2301 | if (spec->multiout.dac_nids > 0) { | 2327 | if (spec->multiout.num_dacs > 0) { |
2302 | p = spec->stream_analog_playback; | 2328 | p = spec->stream_analog_playback; |
2303 | if (!p) | 2329 | if (!p) |
2304 | p = &alc_pcm_analog_playback; | 2330 | p = &alc_pcm_analog_playback; |
@@ -3125,7 +3151,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3125 | static inline unsigned int get_ctl_pos(unsigned int data) | 3151 | static inline unsigned int get_ctl_pos(unsigned int data) |
3126 | { | 3152 | { |
3127 | hda_nid_t nid = get_amp_nid_(data); | 3153 | hda_nid_t nid = get_amp_nid_(data); |
3128 | unsigned int dir = get_amp_direction_(data); | 3154 | unsigned int dir; |
3155 | if (snd_BUG_ON(nid >= MAX_VOL_NIDS)) | ||
3156 | return 0; | ||
3157 | dir = get_amp_direction_(data); | ||
3129 | return (nid << 1) | dir; | 3158 | return (nid << 1) | dir; |
3130 | } | 3159 | } |
3131 | 3160 | ||
@@ -3233,7 +3262,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3233 | int i, err, noutputs; | 3262 | int i, err, noutputs; |
3234 | 3263 | ||
3235 | noutputs = cfg->line_outs; | 3264 | noutputs = cfg->line_outs; |
3236 | if (spec->multi_ios > 0) | 3265 | if (spec->multi_ios > 0 && cfg->line_outs < 3) |
3237 | noutputs += spec->multi_ios; | 3266 | noutputs += spec->multi_ios; |
3238 | 3267 | ||
3239 | for (i = 0; i < noutputs; i++) { | 3268 | for (i = 0; i < noutputs; i++) { |
@@ -3904,7 +3933,6 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
3904 | static void alc_auto_init_std(struct hda_codec *codec) | 3933 | static void alc_auto_init_std(struct hda_codec *codec) |
3905 | { | 3934 | { |
3906 | struct alc_spec *spec = codec->spec; | 3935 | struct alc_spec *spec = codec->spec; |
3907 | spec->use_jack_tbl = 1; | ||
3908 | alc_auto_init_multi_out(codec); | 3936 | alc_auto_init_multi_out(codec); |
3909 | alc_auto_init_extra_out(codec); | 3937 | alc_auto_init_extra_out(codec); |
3910 | alc_auto_init_analog_input(codec); | 3938 | alc_auto_init_analog_input(codec); |
@@ -4168,6 +4196,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
4168 | codec->patch_ops = alc_patch_ops; | 4196 | codec->patch_ops = alc_patch_ops; |
4169 | if (board_config == ALC_MODEL_AUTO) | 4197 | if (board_config == ALC_MODEL_AUTO) |
4170 | spec->init_hook = alc_auto_init_std; | 4198 | spec->init_hook = alc_auto_init_std; |
4199 | else | ||
4200 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4171 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4201 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4172 | if (!spec->loopback.amplist) | 4202 | if (!spec->loopback.amplist) |
4173 | spec->loopback.amplist = alc880_loopbacks; | 4203 | spec->loopback.amplist = alc880_loopbacks; |
@@ -4297,6 +4327,8 @@ static int patch_alc260(struct hda_codec *codec) | |||
4297 | codec->patch_ops = alc_patch_ops; | 4327 | codec->patch_ops = alc_patch_ops; |
4298 | if (board_config == ALC_MODEL_AUTO) | 4328 | if (board_config == ALC_MODEL_AUTO) |
4299 | spec->init_hook = alc_auto_init_std; | 4329 | spec->init_hook = alc_auto_init_std; |
4330 | else | ||
4331 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4300 | spec->shutup = alc_eapd_shutup; | 4332 | spec->shutup = alc_eapd_shutup; |
4301 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4333 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4302 | if (!spec->loopback.amplist) | 4334 | if (!spec->loopback.amplist) |
@@ -4347,6 +4379,7 @@ enum { | |||
4347 | ALC882_FIXUP_ACER_ASPIRE_8930G, | 4379 | ALC882_FIXUP_ACER_ASPIRE_8930G, |
4348 | ALC882_FIXUP_ASPIRE_8930G_VERBS, | 4380 | ALC882_FIXUP_ASPIRE_8930G_VERBS, |
4349 | ALC885_FIXUP_MACPRO_GPIO, | 4381 | ALC885_FIXUP_MACPRO_GPIO, |
4382 | ALC889_FIXUP_DAC_ROUTE, | ||
4350 | }; | 4383 | }; |
4351 | 4384 | ||
4352 | static void alc889_fixup_coef(struct hda_codec *codec, | 4385 | static void alc889_fixup_coef(struct hda_codec *codec, |
@@ -4400,6 +4433,31 @@ static void alc885_fixup_macpro_gpio(struct hda_codec *codec, | |||
4400 | alc882_gpio_mute(codec, 1, 0); | 4433 | alc882_gpio_mute(codec, 1, 0); |
4401 | } | 4434 | } |
4402 | 4435 | ||
4436 | /* Fix the connection of some pins for ALC889: | ||
4437 | * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't | ||
4438 | * work correctly (bko#42740) | ||
4439 | */ | ||
4440 | static void alc889_fixup_dac_route(struct hda_codec *codec, | ||
4441 | const struct alc_fixup *fix, int action) | ||
4442 | { | ||
4443 | if (action == ALC_FIXUP_ACT_PRE_PROBE) { | ||
4444 | /* fake the connections during parsing the tree */ | ||
4445 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; | ||
4446 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; | ||
4447 | snd_hda_override_conn_list(codec, 0x14, 2, conn1); | ||
4448 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); | ||
4449 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); | ||
4450 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); | ||
4451 | } else if (action == ALC_FIXUP_ACT_PROBE) { | ||
4452 | /* restore the connections */ | ||
4453 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; | ||
4454 | snd_hda_override_conn_list(codec, 0x14, 5, conn); | ||
4455 | snd_hda_override_conn_list(codec, 0x15, 5, conn); | ||
4456 | snd_hda_override_conn_list(codec, 0x18, 5, conn); | ||
4457 | snd_hda_override_conn_list(codec, 0x1a, 5, conn); | ||
4458 | } | ||
4459 | } | ||
4460 | |||
4403 | static const struct alc_fixup alc882_fixups[] = { | 4461 | static const struct alc_fixup alc882_fixups[] = { |
4404 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { | 4462 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { |
4405 | .type = ALC_FIXUP_PINS, | 4463 | .type = ALC_FIXUP_PINS, |
@@ -4547,6 +4605,10 @@ static const struct alc_fixup alc882_fixups[] = { | |||
4547 | .type = ALC_FIXUP_FUNC, | 4605 | .type = ALC_FIXUP_FUNC, |
4548 | .v.func = alc885_fixup_macpro_gpio, | 4606 | .v.func = alc885_fixup_macpro_gpio, |
4549 | }, | 4607 | }, |
4608 | [ALC889_FIXUP_DAC_ROUTE] = { | ||
4609 | .type = ALC_FIXUP_FUNC, | ||
4610 | .v.func = alc889_fixup_dac_route, | ||
4611 | }, | ||
4550 | }; | 4612 | }; |
4551 | 4613 | ||
4552 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 4614 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
@@ -4571,6 +4633,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
4571 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", | 4633 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", |
4572 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 4634 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
4573 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), | 4635 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), |
4636 | SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), | ||
4574 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), | 4637 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), |
4575 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), | 4638 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), |
4576 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), | 4639 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), |
@@ -4691,6 +4754,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
4691 | codec->patch_ops = alc_patch_ops; | 4754 | codec->patch_ops = alc_patch_ops; |
4692 | if (board_config == ALC_MODEL_AUTO) | 4755 | if (board_config == ALC_MODEL_AUTO) |
4693 | spec->init_hook = alc_auto_init_std; | 4756 | spec->init_hook = alc_auto_init_std; |
4757 | else | ||
4758 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4694 | 4759 | ||
4695 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4760 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4696 | if (!spec->loopback.amplist) | 4761 | if (!spec->loopback.amplist) |
@@ -4722,7 +4787,6 @@ enum { | |||
4722 | ALC262_FIXUP_FSC_H270, | 4787 | ALC262_FIXUP_FSC_H270, |
4723 | ALC262_FIXUP_HP_Z200, | 4788 | ALC262_FIXUP_HP_Z200, |
4724 | ALC262_FIXUP_TYAN, | 4789 | ALC262_FIXUP_TYAN, |
4725 | ALC262_FIXUP_TOSHIBA_RX1, | ||
4726 | ALC262_FIXUP_LENOVO_3000, | 4790 | ALC262_FIXUP_LENOVO_3000, |
4727 | ALC262_FIXUP_BENQ, | 4791 | ALC262_FIXUP_BENQ, |
4728 | ALC262_FIXUP_BENQ_T31, | 4792 | ALC262_FIXUP_BENQ_T31, |
@@ -4752,16 +4816,6 @@ static const struct alc_fixup alc262_fixups[] = { | |||
4752 | { } | 4816 | { } |
4753 | } | 4817 | } |
4754 | }, | 4818 | }, |
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] = { | 4819 | [ALC262_FIXUP_LENOVO_3000] = { |
4766 | .type = ALC_FIXUP_VERBS, | 4820 | .type = ALC_FIXUP_VERBS, |
4767 | .v.verbs = (const struct hda_verb[]) { | 4821 | .v.verbs = (const struct hda_verb[]) { |
@@ -4794,8 +4848,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { | |||
4794 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), | 4848 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), |
4795 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), | 4849 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), |
4796 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), | 4850 | 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), | 4851 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), |
4800 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), | 4852 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), |
4801 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), | 4853 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), |
@@ -5364,7 +5416,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5364 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 5416 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
5365 | ALC269_FIXUP_AMIC), | 5417 | ALC269_FIXUP_AMIC), |
5366 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), | 5418 | 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), | 5419 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), |
5369 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), | 5420 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), |
5370 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), | 5421 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), |
@@ -5573,8 +5624,28 @@ static const struct hda_amp_list alc861_loopbacks[] = { | |||
5573 | /* Pin config fixes */ | 5624 | /* Pin config fixes */ |
5574 | enum { | 5625 | enum { |
5575 | PINFIX_FSC_AMILO_PI1505, | 5626 | PINFIX_FSC_AMILO_PI1505, |
5627 | PINFIX_ASUS_A6RP, | ||
5576 | }; | 5628 | }; |
5577 | 5629 | ||
5630 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | ||
5631 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | ||
5632 | const struct alc_fixup *fix, int action) | ||
5633 | { | ||
5634 | struct alc_spec *spec = codec->spec; | ||
5635 | unsigned int val; | ||
5636 | |||
5637 | if (action != ALC_FIXUP_ACT_INIT) | ||
5638 | return; | ||
5639 | val = snd_hda_codec_read(codec, 0x0f, 0, | ||
5640 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5641 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) | ||
5642 | val |= AC_PINCTL_IN_EN; | ||
5643 | val |= AC_PINCTL_VREF_50; | ||
5644 | snd_hda_codec_write(codec, 0x0f, 0, | ||
5645 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); | ||
5646 | spec->keep_vref_in_automute = 1; | ||
5647 | } | ||
5648 | |||
5578 | static const struct alc_fixup alc861_fixups[] = { | 5649 | static const struct alc_fixup alc861_fixups[] = { |
5579 | [PINFIX_FSC_AMILO_PI1505] = { | 5650 | [PINFIX_FSC_AMILO_PI1505] = { |
5580 | .type = ALC_FIXUP_PINS, | 5651 | .type = ALC_FIXUP_PINS, |
@@ -5584,9 +5655,16 @@ static const struct alc_fixup alc861_fixups[] = { | |||
5584 | { } | 5655 | { } |
5585 | } | 5656 | } |
5586 | }, | 5657 | }, |
5658 | [PINFIX_ASUS_A6RP] = { | ||
5659 | .type = ALC_FIXUP_FUNC, | ||
5660 | .v.func = alc861_fixup_asus_amp_vref_0f, | ||
5661 | }, | ||
5587 | }; | 5662 | }; |
5588 | 5663 | ||
5589 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { | 5664 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
5665 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), | ||
5666 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP), | ||
5667 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), | ||
5590 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), | 5668 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), |
5591 | {} | 5669 | {} |
5592 | }; | 5670 | }; |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3556408d6ece..6345df131a00 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 | } |
@@ -5069,9 +5078,9 @@ static int stac92xx_update_led_status(struct hda_codec *codec) | |||
5069 | spec->gpio_dir, spec->gpio_data); | 5078 | spec->gpio_dir, spec->gpio_data); |
5070 | } else { | 5079 | } else { |
5071 | notmtd_lvl = spec->gpio_led_polarity ? | 5080 | notmtd_lvl = spec->gpio_led_polarity ? |
5072 | AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD; | 5081 | AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD; |
5073 | muted_lvl = spec->gpio_led_polarity ? | 5082 | muted_lvl = spec->gpio_led_polarity ? |
5074 | AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; | 5083 | AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_50; |
5075 | spec->vref_led = muted ? muted_lvl : notmtd_lvl; | 5084 | spec->vref_led = muted ? muted_lvl : notmtd_lvl; |
5076 | stac_vrefout_set(codec, spec->vref_mute_led_nid, | 5085 | stac_vrefout_set(codec, spec->vref_mute_led_nid, |
5077 | spec->vref_led); | 5086 | spec->vref_led); |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 03e63fed9caf..dff9a00ee8fb 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -199,6 +199,9 @@ struct via_spec { | |||
199 | unsigned int no_pin_power_ctl; | 199 | unsigned int no_pin_power_ctl; |
200 | enum VIA_HDA_CODEC codec_type; | 200 | enum VIA_HDA_CODEC codec_type; |
201 | 201 | ||
202 | /* analog low-power control */ | ||
203 | bool alc_mode; | ||
204 | |||
202 | /* smart51 setup */ | 205 | /* smart51 setup */ |
203 | unsigned int smart51_nums; | 206 | unsigned int smart51_nums; |
204 | hda_nid_t smart51_pins[2]; | 207 | hda_nid_t smart51_pins[2]; |
@@ -663,6 +666,9 @@ static void via_auto_init_analog_input(struct hda_codec *codec) | |||
663 | /* init input-src */ | 666 | /* init input-src */ |
664 | for (i = 0; i < spec->num_adc_nids; i++) { | 667 | for (i = 0; i < spec->num_adc_nids; i++) { |
665 | int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx; | 668 | int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx; |
669 | /* secondary ADCs must have the unique MUX */ | ||
670 | if (i > 0 && !spec->mux_nids[i]) | ||
671 | break; | ||
666 | if (spec->mux_nids[adc_idx]) { | 672 | if (spec->mux_nids[adc_idx]) { |
667 | int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx; | 673 | int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx; |
668 | snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, | 674 | snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, |
@@ -687,6 +693,15 @@ static void via_auto_init_analog_input(struct hda_codec *codec) | |||
687 | } | 693 | } |
688 | } | 694 | } |
689 | 695 | ||
696 | static void update_power_state(struct hda_codec *codec, hda_nid_t nid, | ||
697 | unsigned int parm) | ||
698 | { | ||
699 | if (snd_hda_codec_read(codec, nid, 0, | ||
700 | AC_VERB_GET_POWER_STATE, 0) == parm) | ||
701 | return; | ||
702 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); | ||
703 | } | ||
704 | |||
690 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | 705 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, |
691 | unsigned int *affected_parm) | 706 | unsigned int *affected_parm) |
692 | { | 707 | { |
@@ -709,7 +724,7 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | |||
709 | } else | 724 | } else |
710 | parm = AC_PWRST_D3; | 725 | parm = AC_PWRST_D3; |
711 | 726 | ||
712 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); | 727 | update_power_state(codec, nid, parm); |
713 | } | 728 | } |
714 | 729 | ||
715 | static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol, | 730 | static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol, |
@@ -749,6 +764,7 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol, | |||
749 | return 0; | 764 | return 0; |
750 | spec->no_pin_power_ctl = val; | 765 | spec->no_pin_power_ctl = val; |
751 | set_widgets_power_state(codec); | 766 | set_widgets_power_state(codec); |
767 | analog_low_current_mode(codec); | ||
752 | return 1; | 768 | return 1; |
753 | } | 769 | } |
754 | 770 | ||
@@ -1036,13 +1052,19 @@ static bool is_aa_path_mute(struct hda_codec *codec) | |||
1036 | } | 1052 | } |
1037 | 1053 | ||
1038 | /* enter/exit analog low-current mode */ | 1054 | /* enter/exit analog low-current mode */ |
1039 | static void analog_low_current_mode(struct hda_codec *codec) | 1055 | static void __analog_low_current_mode(struct hda_codec *codec, bool force) |
1040 | { | 1056 | { |
1041 | struct via_spec *spec = codec->spec; | 1057 | struct via_spec *spec = codec->spec; |
1042 | bool enable; | 1058 | bool enable; |
1043 | unsigned int verb, parm; | 1059 | unsigned int verb, parm; |
1044 | 1060 | ||
1045 | enable = is_aa_path_mute(codec) && (spec->opened_streams != 0); | 1061 | if (spec->no_pin_power_ctl) |
1062 | enable = false; | ||
1063 | else | ||
1064 | enable = is_aa_path_mute(codec) && !spec->opened_streams; | ||
1065 | if (enable == spec->alc_mode && !force) | ||
1066 | return; | ||
1067 | spec->alc_mode = enable; | ||
1046 | 1068 | ||
1047 | /* decide low current mode's verb & parameter */ | 1069 | /* decide low current mode's verb & parameter */ |
1048 | switch (spec->codec_type) { | 1070 | switch (spec->codec_type) { |
@@ -1074,6 +1096,11 @@ static void analog_low_current_mode(struct hda_codec *codec) | |||
1074 | snd_hda_codec_write(codec, codec->afg, 0, verb, parm); | 1096 | snd_hda_codec_write(codec, codec->afg, 0, verb, parm); |
1075 | } | 1097 | } |
1076 | 1098 | ||
1099 | static void analog_low_current_mode(struct hda_codec *codec) | ||
1100 | { | ||
1101 | return __analog_low_current_mode(codec, false); | ||
1102 | } | ||
1103 | |||
1077 | /* | 1104 | /* |
1078 | * generic initialization of ADC, input mixers and output mixers | 1105 | * generic initialization of ADC, input mixers and output mixers |
1079 | */ | 1106 | */ |
@@ -1446,6 +1473,7 @@ static int via_build_controls(struct hda_codec *codec) | |||
1446 | struct snd_kcontrol *kctl; | 1473 | struct snd_kcontrol *kctl; |
1447 | int err, i; | 1474 | int err, i; |
1448 | 1475 | ||
1476 | spec->no_pin_power_ctl = 1; | ||
1449 | if (spec->set_widgets_power_state) | 1477 | if (spec->set_widgets_power_state) |
1450 | if (!via_clone_control(spec, &via_pin_power_ctl_enum)) | 1478 | if (!via_clone_control(spec, &via_pin_power_ctl_enum)) |
1451 | return -ENOMEM; | 1479 | return -ENOMEM; |
@@ -1499,10 +1527,6 @@ static int via_build_controls(struct hda_codec *codec) | |||
1499 | return err; | 1527 | return err; |
1500 | } | 1528 | } |
1501 | 1529 | ||
1502 | /* init power states */ | ||
1503 | set_widgets_power_state(codec); | ||
1504 | analog_low_current_mode(codec); | ||
1505 | |||
1506 | via_free_kctls(codec); /* no longer needed */ | 1530 | via_free_kctls(codec); /* no longer needed */ |
1507 | 1531 | ||
1508 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 1532 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); |
@@ -2295,10 +2319,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
2295 | 2319 | ||
2296 | if (mux) { | 2320 | if (mux) { |
2297 | /* switch to D0 beofre change index */ | 2321 | /* switch to D0 beofre change index */ |
2298 | if (snd_hda_codec_read(codec, mux, 0, | 2322 | update_power_state(codec, mux, AC_PWRST_D0); |
2299 | AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) | ||
2300 | snd_hda_codec_write(codec, mux, 0, | ||
2301 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
2302 | snd_hda_codec_write(codec, mux, 0, | 2323 | snd_hda_codec_write(codec, mux, 0, |
2303 | AC_VERB_SET_CONNECT_SEL, | 2324 | AC_VERB_SET_CONNECT_SEL, |
2304 | spec->inputs[cur].mux_idx); | 2325 | spec->inputs[cur].mux_idx); |
@@ -2776,6 +2797,10 @@ static int via_init(struct hda_codec *codec) | |||
2776 | for (i = 0; i < spec->num_iverbs; i++) | 2797 | for (i = 0; i < spec->num_iverbs; i++) |
2777 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 2798 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
2778 | 2799 | ||
2800 | /* init power states */ | ||
2801 | set_widgets_power_state(codec); | ||
2802 | __analog_low_current_mode(codec, true); | ||
2803 | |||
2779 | via_auto_init_multi_out(codec); | 2804 | via_auto_init_multi_out(codec); |
2780 | via_auto_init_hp_out(codec); | 2805 | via_auto_init_hp_out(codec); |
2781 | via_auto_init_speaker_out(codec); | 2806 | via_auto_init_speaker_out(codec); |
@@ -2922,9 +2947,9 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2922 | if (imux_is_smixer) | 2947 | if (imux_is_smixer) |
2923 | parm = AC_PWRST_D0; | 2948 | parm = AC_PWRST_D0; |
2924 | /* SW0 (17h), AIW 0/1 (13h/14h) */ | 2949 | /* SW0 (17h), AIW 0/1 (13h/14h) */ |
2925 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); | 2950 | update_power_state(codec, 0x17, parm); |
2926 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | 2951 | update_power_state(codec, 0x13, parm); |
2927 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); | 2952 | update_power_state(codec, 0x14, parm); |
2928 | 2953 | ||
2929 | /* outputs */ | 2954 | /* outputs */ |
2930 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | 2955 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ |
@@ -2932,8 +2957,8 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2932 | set_pin_power_state(codec, 0x19, &parm); | 2957 | set_pin_power_state(codec, 0x19, &parm); |
2933 | if (spec->smart51_enabled) | 2958 | if (spec->smart51_enabled) |
2934 | set_pin_power_state(codec, 0x1b, &parm); | 2959 | set_pin_power_state(codec, 0x1b, &parm); |
2935 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | 2960 | update_power_state(codec, 0x18, parm); |
2936 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 2961 | update_power_state(codec, 0x11, parm); |
2937 | 2962 | ||
2938 | /* PW6 (22h), SW2 (26h), AOW2 (24h) */ | 2963 | /* PW6 (22h), SW2 (26h), AOW2 (24h) */ |
2939 | if (is_8ch) { | 2964 | if (is_8ch) { |
@@ -2941,20 +2966,16 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2941 | set_pin_power_state(codec, 0x22, &parm); | 2966 | set_pin_power_state(codec, 0x22, &parm); |
2942 | if (spec->smart51_enabled) | 2967 | if (spec->smart51_enabled) |
2943 | set_pin_power_state(codec, 0x1a, &parm); | 2968 | set_pin_power_state(codec, 0x1a, &parm); |
2944 | snd_hda_codec_write(codec, 0x26, 0, | 2969 | update_power_state(codec, 0x26, parm); |
2945 | AC_VERB_SET_POWER_STATE, parm); | 2970 | update_power_state(codec, 0x24, parm); |
2946 | snd_hda_codec_write(codec, 0x24, 0, | ||
2947 | AC_VERB_SET_POWER_STATE, parm); | ||
2948 | } else if (codec->vendor_id == 0x11064397) { | 2971 | } else if (codec->vendor_id == 0x11064397) { |
2949 | /* PW7(23h), SW2(27h), AOW2(25h) */ | 2972 | /* PW7(23h), SW2(27h), AOW2(25h) */ |
2950 | parm = AC_PWRST_D3; | 2973 | parm = AC_PWRST_D3; |
2951 | set_pin_power_state(codec, 0x23, &parm); | 2974 | set_pin_power_state(codec, 0x23, &parm); |
2952 | if (spec->smart51_enabled) | 2975 | if (spec->smart51_enabled) |
2953 | set_pin_power_state(codec, 0x1a, &parm); | 2976 | set_pin_power_state(codec, 0x1a, &parm); |
2954 | snd_hda_codec_write(codec, 0x27, 0, | 2977 | update_power_state(codec, 0x27, parm); |
2955 | AC_VERB_SET_POWER_STATE, parm); | 2978 | update_power_state(codec, 0x25, parm); |
2956 | snd_hda_codec_write(codec, 0x25, 0, | ||
2957 | AC_VERB_SET_POWER_STATE, parm); | ||
2958 | } | 2979 | } |
2959 | 2980 | ||
2960 | /* PW 3/4/7 (1ch/1dh/23h) */ | 2981 | /* PW 3/4/7 (1ch/1dh/23h) */ |
@@ -2966,17 +2987,13 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2966 | set_pin_power_state(codec, 0x23, &parm); | 2987 | set_pin_power_state(codec, 0x23, &parm); |
2967 | 2988 | ||
2968 | /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ | 2989 | /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ |
2969 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, | 2990 | update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm); |
2970 | imux_is_smixer ? AC_PWRST_D0 : parm); | 2991 | update_power_state(codec, 0x10, parm); |
2971 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | ||
2972 | if (is_8ch) { | 2992 | if (is_8ch) { |
2973 | snd_hda_codec_write(codec, 0x25, 0, | 2993 | update_power_state(codec, 0x25, parm); |
2974 | AC_VERB_SET_POWER_STATE, parm); | 2994 | update_power_state(codec, 0x27, parm); |
2975 | snd_hda_codec_write(codec, 0x27, 0, | ||
2976 | AC_VERB_SET_POWER_STATE, parm); | ||
2977 | } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) | 2995 | } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) |
2978 | snd_hda_codec_write(codec, 0x25, 0, | 2996 | update_power_state(codec, 0x25, parm); |
2979 | AC_VERB_SET_POWER_STATE, parm); | ||
2980 | } | 2997 | } |
2981 | 2998 | ||
2982 | static int patch_vt1708S(struct hda_codec *codec); | 2999 | static int patch_vt1708S(struct hda_codec *codec); |
@@ -3149,10 +3166,10 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec) | |||
3149 | if (imux_is_smixer) | 3166 | if (imux_is_smixer) |
3150 | parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ | 3167 | parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ |
3151 | /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ | 3168 | /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ |
3152 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | 3169 | update_power_state(codec, 0x13, parm); |
3153 | snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm); | 3170 | update_power_state(codec, 0x12, parm); |
3154 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | 3171 | update_power_state(codec, 0x1f, parm); |
3155 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm); | 3172 | update_power_state(codec, 0x20, parm); |
3156 | 3173 | ||
3157 | /* outputs */ | 3174 | /* outputs */ |
3158 | /* PW 3/4 (16h/17h) */ | 3175 | /* PW 3/4 (16h/17h) */ |
@@ -3160,10 +3177,9 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec) | |||
3160 | set_pin_power_state(codec, 0x17, &parm); | 3177 | set_pin_power_state(codec, 0x17, &parm); |
3161 | set_pin_power_state(codec, 0x16, &parm); | 3178 | set_pin_power_state(codec, 0x16, &parm); |
3162 | /* MW0 (1ah), AOW 0/1 (10h/1dh) */ | 3179 | /* MW0 (1ah), AOW 0/1 (10h/1dh) */ |
3163 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, | 3180 | update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm); |
3164 | imux_is_smixer ? AC_PWRST_D0 : parm); | 3181 | update_power_state(codec, 0x10, parm); |
3165 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | 3182 | update_power_state(codec, 0x1d, parm); |
3166 | snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3167 | } | 3183 | } |
3168 | 3184 | ||
3169 | static int patch_vt1702(struct hda_codec *codec) | 3185 | static int patch_vt1702(struct hda_codec *codec) |
@@ -3228,52 +3244,48 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) | |||
3228 | if (imux_is_smixer) | 3244 | if (imux_is_smixer) |
3229 | parm = AC_PWRST_D0; | 3245 | parm = AC_PWRST_D0; |
3230 | /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ | 3246 | /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ |
3231 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | 3247 | update_power_state(codec, 0x1e, parm); |
3232 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | 3248 | update_power_state(codec, 0x1f, parm); |
3233 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | 3249 | update_power_state(codec, 0x10, parm); |
3234 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 3250 | update_power_state(codec, 0x11, parm); |
3235 | 3251 | ||
3236 | /* outputs */ | 3252 | /* outputs */ |
3237 | /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ | 3253 | /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ |
3238 | parm = AC_PWRST_D3; | 3254 | parm = AC_PWRST_D3; |
3239 | set_pin_power_state(codec, 0x27, &parm); | 3255 | set_pin_power_state(codec, 0x27, &parm); |
3240 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm); | 3256 | update_power_state(codec, 0x1a, parm); |
3241 | snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); | 3257 | update_power_state(codec, 0xb, parm); |
3242 | 3258 | ||
3243 | /* PW2 (26h), AOW2 (ah) */ | 3259 | /* PW2 (26h), AOW2 (ah) */ |
3244 | parm = AC_PWRST_D3; | 3260 | parm = AC_PWRST_D3; |
3245 | set_pin_power_state(codec, 0x26, &parm); | 3261 | set_pin_power_state(codec, 0x26, &parm); |
3246 | if (spec->smart51_enabled) | 3262 | if (spec->smart51_enabled) |
3247 | set_pin_power_state(codec, 0x2b, &parm); | 3263 | set_pin_power_state(codec, 0x2b, &parm); |
3248 | snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm); | 3264 | update_power_state(codec, 0xa, parm); |
3249 | 3265 | ||
3250 | /* PW0 (24h), AOW0 (8h) */ | 3266 | /* PW0 (24h), AOW0 (8h) */ |
3251 | parm = AC_PWRST_D3; | 3267 | parm = AC_PWRST_D3; |
3252 | set_pin_power_state(codec, 0x24, &parm); | 3268 | set_pin_power_state(codec, 0x24, &parm); |
3253 | if (!spec->hp_independent_mode) /* check for redirected HP */ | 3269 | if (!spec->hp_independent_mode) /* check for redirected HP */ |
3254 | set_pin_power_state(codec, 0x28, &parm); | 3270 | set_pin_power_state(codec, 0x28, &parm); |
3255 | snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); | 3271 | update_power_state(codec, 0x8, parm); |
3256 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ | 3272 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ |
3257 | snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, | 3273 | update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm); |
3258 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
3259 | 3274 | ||
3260 | /* PW1 (25h), AOW1 (9h) */ | 3275 | /* PW1 (25h), AOW1 (9h) */ |
3261 | parm = AC_PWRST_D3; | 3276 | parm = AC_PWRST_D3; |
3262 | set_pin_power_state(codec, 0x25, &parm); | 3277 | set_pin_power_state(codec, 0x25, &parm); |
3263 | if (spec->smart51_enabled) | 3278 | if (spec->smart51_enabled) |
3264 | set_pin_power_state(codec, 0x2a, &parm); | 3279 | set_pin_power_state(codec, 0x2a, &parm); |
3265 | snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm); | 3280 | update_power_state(codec, 0x9, parm); |
3266 | 3281 | ||
3267 | if (spec->hp_independent_mode) { | 3282 | if (spec->hp_independent_mode) { |
3268 | /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ | 3283 | /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ |
3269 | parm = AC_PWRST_D3; | 3284 | parm = AC_PWRST_D3; |
3270 | set_pin_power_state(codec, 0x28, &parm); | 3285 | set_pin_power_state(codec, 0x28, &parm); |
3271 | snd_hda_codec_write(codec, 0x1b, 0, | 3286 | update_power_state(codec, 0x1b, parm); |
3272 | AC_VERB_SET_POWER_STATE, parm); | 3287 | update_power_state(codec, 0x34, parm); |
3273 | snd_hda_codec_write(codec, 0x34, 0, | 3288 | update_power_state(codec, 0xc, parm); |
3274 | AC_VERB_SET_POWER_STATE, parm); | ||
3275 | snd_hda_codec_write(codec, 0xc, 0, | ||
3276 | AC_VERB_SET_POWER_STATE, parm); | ||
3277 | } | 3289 | } |
3278 | } | 3290 | } |
3279 | 3291 | ||
@@ -3433,8 +3445,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3433 | if (imux_is_smixer) | 3445 | if (imux_is_smixer) |
3434 | parm = AC_PWRST_D0; | 3446 | parm = AC_PWRST_D0; |
3435 | /* SW0 (17h), AIW0(13h) */ | 3447 | /* SW0 (17h), AIW0(13h) */ |
3436 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); | 3448 | update_power_state(codec, 0x17, parm); |
3437 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | 3449 | update_power_state(codec, 0x13, parm); |
3438 | 3450 | ||
3439 | parm = AC_PWRST_D3; | 3451 | parm = AC_PWRST_D3; |
3440 | set_pin_power_state(codec, 0x1e, &parm); | 3452 | set_pin_power_state(codec, 0x1e, &parm); |
@@ -3442,12 +3454,11 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3442 | if (spec->dmic_enabled) | 3454 | if (spec->dmic_enabled) |
3443 | set_pin_power_state(codec, 0x22, &parm); | 3455 | set_pin_power_state(codec, 0x22, &parm); |
3444 | else | 3456 | else |
3445 | snd_hda_codec_write(codec, 0x22, 0, | 3457 | update_power_state(codec, 0x22, AC_PWRST_D3); |
3446 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3447 | 3458 | ||
3448 | /* SW2(26h), AIW1(14h) */ | 3459 | /* SW2(26h), AIW1(14h) */ |
3449 | snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm); | 3460 | update_power_state(codec, 0x26, parm); |
3450 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); | 3461 | update_power_state(codec, 0x14, parm); |
3451 | 3462 | ||
3452 | /* outputs */ | 3463 | /* outputs */ |
3453 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | 3464 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ |
@@ -3456,8 +3467,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3456 | /* Smart 5.1 PW2(1bh) */ | 3467 | /* Smart 5.1 PW2(1bh) */ |
3457 | if (spec->smart51_enabled) | 3468 | if (spec->smart51_enabled) |
3458 | set_pin_power_state(codec, 0x1b, &parm); | 3469 | set_pin_power_state(codec, 0x1b, &parm); |
3459 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | 3470 | update_power_state(codec, 0x18, parm); |
3460 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 3471 | update_power_state(codec, 0x11, parm); |
3461 | 3472 | ||
3462 | /* PW7 (23h), SW3 (27h), AOW3 (25h) */ | 3473 | /* PW7 (23h), SW3 (27h), AOW3 (25h) */ |
3463 | parm = AC_PWRST_D3; | 3474 | parm = AC_PWRST_D3; |
@@ -3465,12 +3476,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3465 | /* Smart 5.1 PW1(1ah) */ | 3476 | /* Smart 5.1 PW1(1ah) */ |
3466 | if (spec->smart51_enabled) | 3477 | if (spec->smart51_enabled) |
3467 | set_pin_power_state(codec, 0x1a, &parm); | 3478 | set_pin_power_state(codec, 0x1a, &parm); |
3468 | snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm); | 3479 | update_power_state(codec, 0x27, parm); |
3469 | 3480 | ||
3470 | /* Smart 5.1 PW5(1eh) */ | 3481 | /* Smart 5.1 PW5(1eh) */ |
3471 | if (spec->smart51_enabled) | 3482 | if (spec->smart51_enabled) |
3472 | set_pin_power_state(codec, 0x1e, &parm); | 3483 | set_pin_power_state(codec, 0x1e, &parm); |
3473 | snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm); | 3484 | update_power_state(codec, 0x25, parm); |
3474 | 3485 | ||
3475 | /* Mono out */ | 3486 | /* Mono out */ |
3476 | /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ | 3487 | /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ |
@@ -3486,9 +3497,9 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3486 | mono_out = 1; | 3497 | mono_out = 1; |
3487 | } | 3498 | } |
3488 | parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; | 3499 | parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; |
3489 | snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm); | 3500 | update_power_state(codec, 0x28, parm); |
3490 | snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm); | 3501 | update_power_state(codec, 0x29, parm); |
3491 | snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm); | 3502 | update_power_state(codec, 0x2a, parm); |
3492 | 3503 | ||
3493 | /* PW 3/4 (1ch/1dh) */ | 3504 | /* PW 3/4 (1ch/1dh) */ |
3494 | parm = AC_PWRST_D3; | 3505 | parm = AC_PWRST_D3; |
@@ -3496,15 +3507,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3496 | set_pin_power_state(codec, 0x1d, &parm); | 3507 | set_pin_power_state(codec, 0x1d, &parm); |
3497 | /* HP Independent Mode, power on AOW3 */ | 3508 | /* HP Independent Mode, power on AOW3 */ |
3498 | if (spec->hp_independent_mode) | 3509 | if (spec->hp_independent_mode) |
3499 | snd_hda_codec_write(codec, 0x25, 0, | 3510 | update_power_state(codec, 0x25, parm); |
3500 | AC_VERB_SET_POWER_STATE, parm); | ||
3501 | 3511 | ||
3502 | /* force to D0 for internal Speaker */ | 3512 | /* force to D0 for internal Speaker */ |
3503 | /* MW0 (16h), AOW0 (10h) */ | 3513 | /* MW0 (16h), AOW0 (10h) */ |
3504 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, | 3514 | update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm); |
3505 | imux_is_smixer ? AC_PWRST_D0 : parm); | 3515 | update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm); |
3506 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, | ||
3507 | mono_out ? AC_PWRST_D0 : parm); | ||
3508 | } | 3516 | } |
3509 | 3517 | ||
3510 | static int patch_vt1716S(struct hda_codec *codec) | 3518 | static int patch_vt1716S(struct hda_codec *codec) |
@@ -3580,54 +3588,45 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | |||
3580 | set_pin_power_state(codec, 0x2b, &parm); | 3588 | set_pin_power_state(codec, 0x2b, &parm); |
3581 | parm = AC_PWRST_D0; | 3589 | parm = AC_PWRST_D0; |
3582 | /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ | 3590 | /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ |
3583 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | 3591 | update_power_state(codec, 0x1e, parm); |
3584 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | 3592 | update_power_state(codec, 0x1f, parm); |
3585 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | 3593 | update_power_state(codec, 0x10, parm); |
3586 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 3594 | update_power_state(codec, 0x11, parm); |
3587 | 3595 | ||
3588 | /* outputs */ | 3596 | /* outputs */ |
3589 | /* AOW0 (8h)*/ | 3597 | /* AOW0 (8h)*/ |
3590 | snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); | 3598 | update_power_state(codec, 0x8, parm); |
3591 | 3599 | ||
3592 | if (spec->codec_type == VT1802) { | 3600 | if (spec->codec_type == VT1802) { |
3593 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ | 3601 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ |
3594 | parm = AC_PWRST_D3; | 3602 | parm = AC_PWRST_D3; |
3595 | set_pin_power_state(codec, 0x28, &parm); | 3603 | set_pin_power_state(codec, 0x28, &parm); |
3596 | snd_hda_codec_write(codec, 0x18, 0, | 3604 | update_power_state(codec, 0x18, parm); |
3597 | AC_VERB_SET_POWER_STATE, parm); | 3605 | update_power_state(codec, 0x38, parm); |
3598 | snd_hda_codec_write(codec, 0x38, 0, | ||
3599 | AC_VERB_SET_POWER_STATE, parm); | ||
3600 | } else { | 3606 | } else { |
3601 | /* PW4 (26h), MW4 (1ch), MUX4(37h) */ | 3607 | /* PW4 (26h), MW4 (1ch), MUX4(37h) */ |
3602 | parm = AC_PWRST_D3; | 3608 | parm = AC_PWRST_D3; |
3603 | set_pin_power_state(codec, 0x26, &parm); | 3609 | set_pin_power_state(codec, 0x26, &parm); |
3604 | snd_hda_codec_write(codec, 0x1c, 0, | 3610 | update_power_state(codec, 0x1c, parm); |
3605 | AC_VERB_SET_POWER_STATE, parm); | 3611 | update_power_state(codec, 0x37, parm); |
3606 | snd_hda_codec_write(codec, 0x37, 0, | ||
3607 | AC_VERB_SET_POWER_STATE, parm); | ||
3608 | } | 3612 | } |
3609 | 3613 | ||
3610 | if (spec->codec_type == VT1802) { | 3614 | if (spec->codec_type == VT1802) { |
3611 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ | 3615 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ |
3612 | parm = AC_PWRST_D3; | 3616 | parm = AC_PWRST_D3; |
3613 | set_pin_power_state(codec, 0x25, &parm); | 3617 | set_pin_power_state(codec, 0x25, &parm); |
3614 | snd_hda_codec_write(codec, 0x15, 0, | 3618 | update_power_state(codec, 0x15, parm); |
3615 | AC_VERB_SET_POWER_STATE, parm); | 3619 | update_power_state(codec, 0x35, parm); |
3616 | snd_hda_codec_write(codec, 0x35, 0, | ||
3617 | AC_VERB_SET_POWER_STATE, parm); | ||
3618 | } else { | 3620 | } else { |
3619 | /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ | 3621 | /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ |
3620 | parm = AC_PWRST_D3; | 3622 | parm = AC_PWRST_D3; |
3621 | set_pin_power_state(codec, 0x25, &parm); | 3623 | set_pin_power_state(codec, 0x25, &parm); |
3622 | snd_hda_codec_write(codec, 0x19, 0, | 3624 | update_power_state(codec, 0x19, parm); |
3623 | AC_VERB_SET_POWER_STATE, parm); | 3625 | update_power_state(codec, 0x35, parm); |
3624 | snd_hda_codec_write(codec, 0x35, 0, | ||
3625 | AC_VERB_SET_POWER_STATE, parm); | ||
3626 | } | 3626 | } |
3627 | 3627 | ||
3628 | if (spec->hp_independent_mode) | 3628 | if (spec->hp_independent_mode) |
3629 | snd_hda_codec_write(codec, 0x9, 0, | 3629 | update_power_state(codec, 0x9, AC_PWRST_D0); |
3630 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3631 | 3630 | ||
3632 | /* Class-D */ | 3631 | /* Class-D */ |
3633 | /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ | 3632 | /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ |
@@ -3637,12 +3636,10 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | |||
3637 | set_pin_power_state(codec, 0x24, &parm); | 3636 | set_pin_power_state(codec, 0x24, &parm); |
3638 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; | 3637 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; |
3639 | if (spec->codec_type == VT1802) | 3638 | if (spec->codec_type == VT1802) |
3640 | snd_hda_codec_write(codec, 0x14, 0, | 3639 | update_power_state(codec, 0x14, parm); |
3641 | AC_VERB_SET_POWER_STATE, parm); | ||
3642 | else | 3640 | else |
3643 | snd_hda_codec_write(codec, 0x18, 0, | 3641 | update_power_state(codec, 0x18, parm); |
3644 | AC_VERB_SET_POWER_STATE, parm); | 3642 | update_power_state(codec, 0x34, parm); |
3645 | snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3646 | 3643 | ||
3647 | /* Mono Out */ | 3644 | /* Mono Out */ |
3648 | present = snd_hda_jack_detect(codec, 0x26); | 3645 | present = snd_hda_jack_detect(codec, 0x26); |
@@ -3650,28 +3647,20 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | |||
3650 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; | 3647 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; |
3651 | if (spec->codec_type == VT1802) { | 3648 | if (spec->codec_type == VT1802) { |
3652 | /* PW15 (33h), MW8(1ch), MUX8(3ch) */ | 3649 | /* PW15 (33h), MW8(1ch), MUX8(3ch) */ |
3653 | snd_hda_codec_write(codec, 0x33, 0, | 3650 | update_power_state(codec, 0x33, parm); |
3654 | AC_VERB_SET_POWER_STATE, parm); | 3651 | update_power_state(codec, 0x1c, parm); |
3655 | snd_hda_codec_write(codec, 0x1c, 0, | 3652 | update_power_state(codec, 0x3c, parm); |
3656 | AC_VERB_SET_POWER_STATE, parm); | ||
3657 | snd_hda_codec_write(codec, 0x3c, 0, | ||
3658 | AC_VERB_SET_POWER_STATE, parm); | ||
3659 | } else { | 3653 | } else { |
3660 | /* PW15 (31h), MW8(17h), MUX8(3bh) */ | 3654 | /* PW15 (31h), MW8(17h), MUX8(3bh) */ |
3661 | snd_hda_codec_write(codec, 0x31, 0, | 3655 | update_power_state(codec, 0x31, parm); |
3662 | AC_VERB_SET_POWER_STATE, parm); | 3656 | update_power_state(codec, 0x17, parm); |
3663 | snd_hda_codec_write(codec, 0x17, 0, | 3657 | update_power_state(codec, 0x3b, parm); |
3664 | AC_VERB_SET_POWER_STATE, parm); | ||
3665 | snd_hda_codec_write(codec, 0x3b, 0, | ||
3666 | AC_VERB_SET_POWER_STATE, parm); | ||
3667 | } | 3658 | } |
3668 | /* MW9 (21h) */ | 3659 | /* MW9 (21h) */ |
3669 | if (imux_is_smixer || !is_aa_path_mute(codec)) | 3660 | if (imux_is_smixer || !is_aa_path_mute(codec)) |
3670 | snd_hda_codec_write(codec, 0x21, 0, | 3661 | update_power_state(codec, 0x21, AC_PWRST_D0); |
3671 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3672 | else | 3662 | else |
3673 | snd_hda_codec_write(codec, 0x21, 0, | 3663 | update_power_state(codec, 0x21, AC_PWRST_D3); |
3674 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3675 | } | 3664 | } |
3676 | 3665 | ||
3677 | /* patch for vt2002P */ | 3666 | /* patch for vt2002P */ |
@@ -3731,30 +3720,28 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) | |||
3731 | set_pin_power_state(codec, 0x2b, &parm); | 3720 | set_pin_power_state(codec, 0x2b, &parm); |
3732 | parm = AC_PWRST_D0; | 3721 | parm = AC_PWRST_D0; |
3733 | /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ | 3722 | /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ |
3734 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | 3723 | update_power_state(codec, 0x1e, parm); |
3735 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | 3724 | update_power_state(codec, 0x1f, parm); |
3736 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | 3725 | update_power_state(codec, 0x10, parm); |
3737 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 3726 | update_power_state(codec, 0x11, parm); |
3738 | 3727 | ||
3739 | /* outputs */ | 3728 | /* outputs */ |
3740 | /* AOW0 (8h)*/ | 3729 | /* AOW0 (8h)*/ |
3741 | snd_hda_codec_write(codec, 0x8, 0, | 3730 | update_power_state(codec, 0x8, AC_PWRST_D0); |
3742 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3743 | 3731 | ||
3744 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ | 3732 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ |
3745 | parm = AC_PWRST_D3; | 3733 | parm = AC_PWRST_D3; |
3746 | set_pin_power_state(codec, 0x28, &parm); | 3734 | set_pin_power_state(codec, 0x28, &parm); |
3747 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | 3735 | update_power_state(codec, 0x18, parm); |
3748 | snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm); | 3736 | update_power_state(codec, 0x38, parm); |
3749 | 3737 | ||
3750 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ | 3738 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ |
3751 | parm = AC_PWRST_D3; | 3739 | parm = AC_PWRST_D3; |
3752 | set_pin_power_state(codec, 0x25, &parm); | 3740 | set_pin_power_state(codec, 0x25, &parm); |
3753 | snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm); | 3741 | update_power_state(codec, 0x15, parm); |
3754 | snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm); | 3742 | update_power_state(codec, 0x35, parm); |
3755 | if (spec->hp_independent_mode) | 3743 | if (spec->hp_independent_mode) |
3756 | snd_hda_codec_write(codec, 0x9, 0, | 3744 | update_power_state(codec, 0x9, AC_PWRST_D0); |
3757 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3758 | 3745 | ||
3759 | /* Internal Speaker */ | 3746 | /* Internal Speaker */ |
3760 | /* PW0 (24h), MW0(14h), MUX0(34h) */ | 3747 | /* PW0 (24h), MW0(14h), MUX0(34h) */ |
@@ -3763,15 +3750,11 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) | |||
3763 | parm = AC_PWRST_D3; | 3750 | parm = AC_PWRST_D3; |
3764 | set_pin_power_state(codec, 0x24, &parm); | 3751 | set_pin_power_state(codec, 0x24, &parm); |
3765 | if (present) { | 3752 | if (present) { |
3766 | snd_hda_codec_write(codec, 0x14, 0, | 3753 | update_power_state(codec, 0x14, AC_PWRST_D3); |
3767 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 3754 | update_power_state(codec, 0x34, AC_PWRST_D3); |
3768 | snd_hda_codec_write(codec, 0x34, 0, | ||
3769 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3770 | } else { | 3755 | } else { |
3771 | snd_hda_codec_write(codec, 0x14, 0, | 3756 | update_power_state(codec, 0x14, AC_PWRST_D0); |
3772 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | 3757 | update_power_state(codec, 0x34, AC_PWRST_D0); |
3773 | snd_hda_codec_write(codec, 0x34, 0, | ||
3774 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3775 | } | 3758 | } |
3776 | 3759 | ||
3777 | 3760 | ||
@@ -3782,26 +3765,20 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) | |||
3782 | parm = AC_PWRST_D3; | 3765 | parm = AC_PWRST_D3; |
3783 | set_pin_power_state(codec, 0x31, &parm); | 3766 | set_pin_power_state(codec, 0x31, &parm); |
3784 | if (present) { | 3767 | if (present) { |
3785 | snd_hda_codec_write(codec, 0x1c, 0, | 3768 | update_power_state(codec, 0x1c, AC_PWRST_D3); |
3786 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 3769 | update_power_state(codec, 0x3c, AC_PWRST_D3); |
3787 | snd_hda_codec_write(codec, 0x3c, 0, | 3770 | update_power_state(codec, 0x3e, AC_PWRST_D3); |
3788 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3789 | snd_hda_codec_write(codec, 0x3e, 0, | ||
3790 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3791 | } else { | 3771 | } else { |
3792 | snd_hda_codec_write(codec, 0x1c, 0, | 3772 | update_power_state(codec, 0x1c, AC_PWRST_D0); |
3793 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | 3773 | update_power_state(codec, 0x3c, AC_PWRST_D0); |
3794 | snd_hda_codec_write(codec, 0x3c, 0, | 3774 | update_power_state(codec, 0x3e, AC_PWRST_D0); |
3795 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3796 | snd_hda_codec_write(codec, 0x3e, 0, | ||
3797 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3798 | } | 3775 | } |
3799 | 3776 | ||
3800 | /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ | 3777 | /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ |
3801 | parm = AC_PWRST_D3; | 3778 | parm = AC_PWRST_D3; |
3802 | set_pin_power_state(codec, 0x33, &parm); | 3779 | set_pin_power_state(codec, 0x33, &parm); |
3803 | snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); | 3780 | update_power_state(codec, 0x1d, parm); |
3804 | snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm); | 3781 | update_power_state(codec, 0x3d, parm); |
3805 | 3782 | ||
3806 | } | 3783 | } |
3807 | 3784 | ||
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 9f3b01bb72c8..e0a4263baa20 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -2102,6 +2102,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { | |||
2102 | }, | 2102 | }, |
2103 | { | 2103 | { |
2104 | .subvendor = 0x161f, | 2104 | .subvendor = 0x161f, |
2105 | .subdevice = 0x202f, | ||
2106 | .name = "Gateway M520", | ||
2107 | .type = AC97_TUNE_INV_EAPD | ||
2108 | }, | ||
2109 | { | ||
2110 | .subvendor = 0x161f, | ||
2105 | .subdevice = 0x203a, | 2111 | .subdevice = 0x203a, |
2106 | .name = "Gateway 4525GZ", /* AD1981B */ | 2112 | .name = "Gateway 4525GZ", /* AD1981B */ |
2107 | .type = AC97_TUNE_INV_EAPD | 2113 | .type = AC97_TUNE_INV_EAPD |
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 26c7e8bcb229..c0dbb52d45be 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -618,9 +618,12 @@ static int ac97_volume_get(struct snd_kcontrol *ctl, | |||
618 | mutex_lock(&chip->mutex); | 618 | mutex_lock(&chip->mutex); |
619 | reg = oxygen_read_ac97(chip, codec, index); | 619 | reg = oxygen_read_ac97(chip, codec, index); |
620 | mutex_unlock(&chip->mutex); | 620 | mutex_unlock(&chip->mutex); |
621 | value->value.integer.value[0] = 31 - (reg & 0x1f); | 621 | if (!stereo) { |
622 | if (stereo) | 622 | value->value.integer.value[0] = 31 - (reg & 0x1f); |
623 | value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); | 623 | } else { |
624 | value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f); | ||
625 | value->value.integer.value[1] = 31 - (reg & 0x1f); | ||
626 | } | ||
624 | return 0; | 627 | return 0; |
625 | } | 628 | } |
626 | 629 | ||
@@ -636,14 +639,14 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, | |||
636 | 639 | ||
637 | mutex_lock(&chip->mutex); | 640 | mutex_lock(&chip->mutex); |
638 | oldreg = oxygen_read_ac97(chip, codec, index); | 641 | oldreg = oxygen_read_ac97(chip, codec, index); |
639 | newreg = oldreg; | 642 | if (!stereo) { |
640 | newreg = (newreg & ~0x1f) | | 643 | newreg = oldreg & ~0x1f; |
641 | (31 - (value->value.integer.value[0] & 0x1f)); | 644 | newreg |= 31 - (value->value.integer.value[0] & 0x1f); |
642 | if (stereo) | 645 | } else { |
643 | newreg = (newreg & ~0x1f00) | | 646 | newreg = oldreg & ~0x1f1f; |
644 | ((31 - (value->value.integer.value[1] & 0x1f)) << 8); | 647 | newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8; |
645 | else | 648 | newreg |= 31 - (value->value.integer.value[1] & 0x1f); |
646 | newreg = (newreg & ~0x1f00) | ((newreg & 0x1f) << 8); | 649 | } |
647 | change = newreg != oldreg; | 650 | change = newreg != oldreg; |
648 | if (change) | 651 | if (change) |
649 | oxygen_write_ac97(chip, codec, index, newreg); | 652 | oxygen_write_ac97(chip, codec, index, newreg); |
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)) |
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 5ef70b5d27e4..278c0a0575f5 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -146,13 +146,10 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = { | |||
146 | 146 | ||
147 | SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC, | 147 | SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC, |
148 | 0, 0xFF, 1, out_tlv), | 148 | 0, 0xFF, 1, out_tlv), |
149 | |||
150 | SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0), | ||
151 | }; | 149 | }; |
152 | 150 | ||
153 | static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = { | 151 | static const struct snd_kcontrol_new ak4642_headphone_control = |
154 | SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0), | 152 | SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0); |
155 | }; | ||
156 | 153 | ||
157 | static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = { | 154 | static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = { |
158 | SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0), | 155 | SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0), |
@@ -165,13 +162,12 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = { | |||
165 | SND_SOC_DAPM_OUTPUT("HPOUTR"), | 162 | SND_SOC_DAPM_OUTPUT("HPOUTR"), |
166 | SND_SOC_DAPM_OUTPUT("LINEOUT"), | 163 | SND_SOC_DAPM_OUTPUT("LINEOUT"), |
167 | 164 | ||
168 | SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0, | 165 | SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0), |
169 | &ak4642_hpout_mixer_controls[0], | 166 | SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0), |
170 | ARRAY_SIZE(ak4642_hpout_mixer_controls)), | 167 | SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0, |
168 | &ak4642_headphone_control), | ||
171 | 169 | ||
172 | SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0, | 170 | SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0), |
173 | &ak4642_hpout_mixer_controls[0], | ||
174 | ARRAY_SIZE(ak4642_hpout_mixer_controls)), | ||
175 | 171 | ||
176 | SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0, | 172 | SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0, |
177 | &ak4642_lout_mixer_controls[0], | 173 | &ak4642_lout_mixer_controls[0], |
@@ -184,12 +180,17 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = { | |||
184 | static const struct snd_soc_dapm_route ak4642_intercon[] = { | 180 | static const struct snd_soc_dapm_route ak4642_intercon[] = { |
185 | 181 | ||
186 | /* Outputs */ | 182 | /* Outputs */ |
187 | {"HPOUTL", NULL, "HPOUTL Mixer"}, | 183 | {"HPOUTL", NULL, "HPL Out"}, |
188 | {"HPOUTR", NULL, "HPOUTR Mixer"}, | 184 | {"HPOUTR", NULL, "HPR Out"}, |
189 | {"LINEOUT", NULL, "LINEOUT Mixer"}, | 185 | {"LINEOUT", NULL, "LINEOUT Mixer"}, |
190 | 186 | ||
191 | {"HPOUTL Mixer", "DACH", "DAC"}, | 187 | {"HPL Out", NULL, "Headphone Enable"}, |
192 | {"HPOUTR Mixer", "DACH", "DAC"}, | 188 | {"HPR Out", NULL, "Headphone Enable"}, |
189 | |||
190 | {"Headphone Enable", "Switch", "DACH"}, | ||
191 | |||
192 | {"DACH", NULL, "DAC"}, | ||
193 | |||
193 | {"LINEOUT Mixer", "DACL", "DAC"}, | 194 | {"LINEOUT Mixer", "DACL", "DAC"}, |
194 | }; | 195 | }; |
195 | 196 | ||
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 9d38db8f1919..78979b3e0e95 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1113,7 +1113,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, | |||
1113 | priv->config[id].mmcc &= 0xC0; | 1113 | priv->config[id].mmcc &= 0xC0; |
1114 | priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; | 1114 | priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; |
1115 | priv->config[id].spc &= 0xFC; | 1115 | priv->config[id].spc &= 0xFC; |
1116 | priv->config[id].spc &= MCK_SCLK_64FS; | 1116 | priv->config[id].spc |= MCK_SCLK_MCLK; |
1117 | } else { | 1117 | } else { |
1118 | /* CS42L73 Slave */ | 1118 | /* CS42L73 Slave */ |
1119 | priv->config[id].spc &= 0xFC; | 1119 | priv->config[id].spc &= 0xFC; |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index f8863ebb4304..7f4ba819a9f6 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -987,12 +987,12 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) | |||
987 | /* restore regular registers */ | 987 | /* restore regular registers */ |
988 | for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { | 988 | for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { |
989 | 989 | ||
990 | /* this regs depends on the others */ | 990 | /* These regs should restore in particular order */ |
991 | if (reg == SGTL5000_CHIP_ANA_POWER || | 991 | if (reg == SGTL5000_CHIP_ANA_POWER || |
992 | reg == SGTL5000_CHIP_CLK_CTRL || | 992 | reg == SGTL5000_CHIP_CLK_CTRL || |
993 | reg == SGTL5000_CHIP_LINREG_CTRL || | 993 | reg == SGTL5000_CHIP_LINREG_CTRL || |
994 | reg == SGTL5000_CHIP_LINE_OUT_CTRL || | 994 | reg == SGTL5000_CHIP_LINE_OUT_CTRL || |
995 | reg == SGTL5000_CHIP_CLK_CTRL) | 995 | reg == SGTL5000_CHIP_REF_CTRL) |
996 | continue; | 996 | continue; |
997 | 997 | ||
998 | snd_soc_write(codec, reg, cache[reg]); | 998 | snd_soc_write(codec, reg, cache[reg]); |
@@ -1003,8 +1003,17 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) | |||
1003 | snd_soc_write(codec, reg, cache[reg]); | 1003 | snd_soc_write(codec, reg, cache[reg]); |
1004 | 1004 | ||
1005 | /* | 1005 | /* |
1006 | * restore power and other regs according | 1006 | * restore these regs according to the power setting sequence in |
1007 | * to set_power() and set_clock() | 1007 | * sgtl5000_set_power_regs() and clock setting sequence in |
1008 | * sgtl5000_set_clock(). | ||
1009 | * | ||
1010 | * The order of restore is: | ||
1011 | * 1. SGTL5000_CHIP_CLK_CTRL MCLK_FREQ bits (1:0) should be restore after | ||
1012 | * SGTL5000_CHIP_ANA_POWER PLL bits set | ||
1013 | * 2. SGTL5000_CHIP_LINREG_CTRL should be set before | ||
1014 | * SGTL5000_CHIP_ANA_POWER LINREG_D restored | ||
1015 | * 3. SGTL5000_CHIP_REF_CTRL controls Analog Ground Voltage, | ||
1016 | * prefer to resotre it after SGTL5000_CHIP_ANA_POWER restored | ||
1008 | */ | 1017 | */ |
1009 | snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, | 1018 | snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, |
1010 | cache[SGTL5000_CHIP_LINREG_CTRL]); | 1019 | cache[SGTL5000_CHIP_LINREG_CTRL]); |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index eb401ef021fb..372b0b83bd9f 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -60,7 +60,6 @@ struct aic32x4_rate_divs { | |||
60 | 60 | ||
61 | struct aic32x4_priv { | 61 | struct aic32x4_priv { |
62 | u32 sysclk; | 62 | u32 sysclk; |
63 | s32 master; | ||
64 | u8 page_no; | 63 | u8 page_no; |
65 | void *control_data; | 64 | void *control_data; |
66 | u32 power_cfg; | 65 | u32 power_cfg; |
@@ -369,7 +368,6 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
369 | static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | 368 | static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) |
370 | { | 369 | { |
371 | struct snd_soc_codec *codec = codec_dai->codec; | 370 | struct snd_soc_codec *codec = codec_dai->codec; |
372 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | ||
373 | u8 iface_reg_1; | 371 | u8 iface_reg_1; |
374 | u8 iface_reg_2; | 372 | u8 iface_reg_2; |
375 | u8 iface_reg_3; | 373 | u8 iface_reg_3; |
@@ -384,11 +382,9 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
384 | /* set master/slave audio interface */ | 382 | /* set master/slave audio interface */ |
385 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 383 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
386 | case SND_SOC_DAIFMT_CBM_CFM: | 384 | case SND_SOC_DAIFMT_CBM_CFM: |
387 | aic32x4->master = 1; | ||
388 | iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER; | 385 | iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER; |
389 | break; | 386 | break; |
390 | case SND_SOC_DAIFMT_CBS_CFS: | 387 | case SND_SOC_DAIFMT_CBS_CFS: |
391 | aic32x4->master = 0; | ||
392 | break; | 388 | break; |
393 | default: | 389 | default: |
394 | printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n"); | 390 | printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n"); |
@@ -526,64 +522,58 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute) | |||
526 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | 522 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, |
527 | enum snd_soc_bias_level level) | 523 | enum snd_soc_bias_level level) |
528 | { | 524 | { |
529 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | ||
530 | |||
531 | switch (level) { | 525 | switch (level) { |
532 | case SND_SOC_BIAS_ON: | 526 | case SND_SOC_BIAS_ON: |
533 | if (aic32x4->master) { | 527 | /* Switch on PLL */ |
534 | /* Switch on PLL */ | 528 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
535 | snd_soc_update_bits(codec, AIC32X4_PLLPR, | 529 | AIC32X4_PLLEN, AIC32X4_PLLEN); |
536 | AIC32X4_PLLEN, AIC32X4_PLLEN); | 530 | |
537 | 531 | /* Switch on NDAC Divider */ | |
538 | /* Switch on NDAC Divider */ | 532 | snd_soc_update_bits(codec, AIC32X4_NDAC, |
539 | snd_soc_update_bits(codec, AIC32X4_NDAC, | 533 | AIC32X4_NDACEN, AIC32X4_NDACEN); |
540 | AIC32X4_NDACEN, AIC32X4_NDACEN); | 534 | |
541 | 535 | /* Switch on MDAC Divider */ | |
542 | /* Switch on MDAC Divider */ | 536 | snd_soc_update_bits(codec, AIC32X4_MDAC, |
543 | snd_soc_update_bits(codec, AIC32X4_MDAC, | 537 | AIC32X4_MDACEN, AIC32X4_MDACEN); |
544 | AIC32X4_MDACEN, AIC32X4_MDACEN); | 538 | |
545 | 539 | /* Switch on NADC Divider */ | |
546 | /* Switch on NADC Divider */ | 540 | snd_soc_update_bits(codec, AIC32X4_NADC, |
547 | snd_soc_update_bits(codec, AIC32X4_NADC, | 541 | AIC32X4_NADCEN, AIC32X4_NADCEN); |
548 | AIC32X4_NADCEN, AIC32X4_NADCEN); | 542 | |
549 | 543 | /* Switch on MADC Divider */ | |
550 | /* Switch on MADC Divider */ | 544 | snd_soc_update_bits(codec, AIC32X4_MADC, |
551 | snd_soc_update_bits(codec, AIC32X4_MADC, | 545 | AIC32X4_MADCEN, AIC32X4_MADCEN); |
552 | AIC32X4_MADCEN, AIC32X4_MADCEN); | 546 | |
553 | 547 | /* Switch on BCLK_N Divider */ | |
554 | /* Switch on BCLK_N Divider */ | 548 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
555 | snd_soc_update_bits(codec, AIC32X4_BCLKN, | 549 | AIC32X4_BCLKEN, AIC32X4_BCLKEN); |
556 | AIC32X4_BCLKEN, AIC32X4_BCLKEN); | ||
557 | } | ||
558 | break; | 550 | break; |
559 | case SND_SOC_BIAS_PREPARE: | 551 | case SND_SOC_BIAS_PREPARE: |
560 | break; | 552 | break; |
561 | case SND_SOC_BIAS_STANDBY: | 553 | case SND_SOC_BIAS_STANDBY: |
562 | if (aic32x4->master) { | 554 | /* Switch off PLL */ |
563 | /* Switch off PLL */ | 555 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
564 | snd_soc_update_bits(codec, AIC32X4_PLLPR, | 556 | AIC32X4_PLLEN, 0); |
565 | AIC32X4_PLLEN, 0); | 557 | |
566 | 558 | /* Switch off NDAC Divider */ | |
567 | /* Switch off NDAC Divider */ | 559 | snd_soc_update_bits(codec, AIC32X4_NDAC, |
568 | snd_soc_update_bits(codec, AIC32X4_NDAC, | 560 | AIC32X4_NDACEN, 0); |
569 | AIC32X4_NDACEN, 0); | 561 | |
570 | 562 | /* Switch off MDAC Divider */ | |
571 | /* Switch off MDAC Divider */ | 563 | snd_soc_update_bits(codec, AIC32X4_MDAC, |
572 | snd_soc_update_bits(codec, AIC32X4_MDAC, | 564 | AIC32X4_MDACEN, 0); |
573 | AIC32X4_MDACEN, 0); | 565 | |
574 | 566 | /* Switch off NADC Divider */ | |
575 | /* Switch off NADC Divider */ | 567 | snd_soc_update_bits(codec, AIC32X4_NADC, |
576 | snd_soc_update_bits(codec, AIC32X4_NADC, | 568 | AIC32X4_NADCEN, 0); |
577 | AIC32X4_NADCEN, 0); | 569 | |
578 | 570 | /* Switch off MADC Divider */ | |
579 | /* Switch off MADC Divider */ | 571 | snd_soc_update_bits(codec, AIC32X4_MADC, |
580 | snd_soc_update_bits(codec, AIC32X4_MADC, | 572 | AIC32X4_MADCEN, 0); |
581 | AIC32X4_MADCEN, 0); | 573 | |
582 | 574 | /* Switch off BCLK_N Divider */ | |
583 | /* Switch off BCLK_N Divider */ | 575 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
584 | snd_soc_update_bits(codec, AIC32X4_BCLKN, | 576 | AIC32X4_BCLKEN, 0); |
585 | AIC32X4_BCLKEN, 0); | ||
586 | } | ||
587 | break; | 577 | break; |
588 | case SND_SOC_BIAS_OFF: | 578 | case SND_SOC_BIAS_OFF: |
589 | break; | 579 | break; |
@@ -651,9 +641,11 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
651 | if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) { | 641 | if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) { |
652 | snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); | 642 | snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); |
653 | } | 643 | } |
654 | if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) { | 644 | |
655 | snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN); | 645 | tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ? |
656 | } | 646 | AIC32X4_LDOCTLEN : 0; |
647 | snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg); | ||
648 | |||
657 | tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE); | 649 | tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE); |
658 | if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) { | 650 | if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) { |
659 | tmp_reg |= AIC32X4_LDOIN_18_36; | 651 | tmp_reg |= AIC32X4_LDOIN_18_36; |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index c2880907fced..a75c3766aede 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -733,8 +733,9 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
733 | struct wm2000_priv *wm2000; | 733 | struct wm2000_priv *wm2000; |
734 | struct wm2000_platform_data *pdata; | 734 | struct wm2000_platform_data *pdata; |
735 | const char *filename; | 735 | const char *filename; |
736 | const struct firmware *fw; | 736 | const struct firmware *fw = NULL; |
737 | int reg, ret; | 737 | int ret; |
738 | int reg; | ||
738 | u16 id; | 739 | u16 id; |
739 | 740 | ||
740 | wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), | 741 | wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), |
@@ -751,7 +752,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
751 | ret = PTR_ERR(wm2000->regmap); | 752 | ret = PTR_ERR(wm2000->regmap); |
752 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 753 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
753 | ret); | 754 | ret); |
754 | goto err; | 755 | goto out; |
755 | } | 756 | } |
756 | 757 | ||
757 | /* Verify that this is a WM2000 */ | 758 | /* Verify that this is a WM2000 */ |
@@ -763,7 +764,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
763 | if (id != 0x2000) { | 764 | if (id != 0x2000) { |
764 | dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); | 765 | dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); |
765 | ret = -ENODEV; | 766 | ret = -ENODEV; |
766 | goto err_regmap; | 767 | goto out_regmap_exit; |
767 | } | 768 | } |
768 | 769 | ||
769 | reg = wm2000_read(i2c, WM2000_REG_REVISON); | 770 | reg = wm2000_read(i2c, WM2000_REG_REVISON); |
@@ -782,7 +783,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
782 | ret = request_firmware(&fw, filename, &i2c->dev); | 783 | ret = request_firmware(&fw, filename, &i2c->dev); |
783 | if (ret != 0) { | 784 | if (ret != 0) { |
784 | dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); | 785 | dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); |
785 | goto err_regmap; | 786 | goto out_regmap_exit; |
786 | } | 787 | } |
787 | 788 | ||
788 | /* Pre-cook the concatenation of the register address onto the image */ | 789 | /* Pre-cook the concatenation of the register address onto the image */ |
@@ -793,15 +794,13 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
793 | if (wm2000->anc_download == NULL) { | 794 | if (wm2000->anc_download == NULL) { |
794 | dev_err(&i2c->dev, "Out of memory\n"); | 795 | dev_err(&i2c->dev, "Out of memory\n"); |
795 | ret = -ENOMEM; | 796 | ret = -ENOMEM; |
796 | goto err_fw; | 797 | goto out_regmap_exit; |
797 | } | 798 | } |
798 | 799 | ||
799 | wm2000->anc_download[0] = 0x80; | 800 | wm2000->anc_download[0] = 0x80; |
800 | wm2000->anc_download[1] = 0x00; | 801 | wm2000->anc_download[1] = 0x00; |
801 | memcpy(wm2000->anc_download + 2, fw->data, fw->size); | 802 | memcpy(wm2000->anc_download + 2, fw->data, fw->size); |
802 | 803 | ||
803 | release_firmware(fw); | ||
804 | |||
805 | wm2000->anc_eng_ena = 1; | 804 | wm2000->anc_eng_ena = 1; |
806 | wm2000->anc_active = 1; | 805 | wm2000->anc_active = 1; |
807 | wm2000->spk_ena = 1; | 806 | wm2000->spk_ena = 1; |
@@ -809,18 +808,14 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
809 | 808 | ||
810 | wm2000_reset(wm2000); | 809 | wm2000_reset(wm2000); |
811 | 810 | ||
812 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, | 811 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); |
813 | NULL, 0); | 812 | if (!ret) |
814 | if (ret != 0) | 813 | goto out; |
815 | goto err_fw; | ||
816 | 814 | ||
817 | return 0; | 815 | out_regmap_exit: |
818 | |||
819 | err_fw: | ||
820 | release_firmware(fw); | ||
821 | err_regmap: | ||
822 | regmap_exit(wm2000->regmap); | 816 | regmap_exit(wm2000->regmap); |
823 | err: | 817 | out: |
818 | release_firmware(fw); | ||
824 | return ret; | 819 | return ret; |
825 | } | 820 | } |
826 | 821 | ||
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 8b24323d6b2c..89f2af77b1c3 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -1377,6 +1377,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, | |||
1377 | 1377 | ||
1378 | switch (wm5100->rev) { | 1378 | switch (wm5100->rev) { |
1379 | case 0: | 1379 | case 0: |
1380 | regcache_cache_bypass(wm5100->regmap, true); | ||
1380 | snd_soc_write(codec, 0x11, 0x3); | 1381 | snd_soc_write(codec, 0x11, 0x3); |
1381 | snd_soc_write(codec, 0x203, 0xc); | 1382 | snd_soc_write(codec, 0x203, 0xc); |
1382 | snd_soc_write(codec, 0x206, 0); | 1383 | snd_soc_write(codec, 0x206, 0); |
@@ -1392,6 +1393,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, | |||
1392 | snd_soc_write(codec, | 1393 | snd_soc_write(codec, |
1393 | wm5100_reva_patches[i].reg, | 1394 | wm5100_reva_patches[i].reg, |
1394 | wm5100_reva_patches[i].val); | 1395 | wm5100_reva_patches[i].val); |
1396 | regcache_cache_bypass(wm5100->regmap, false); | ||
1395 | break; | 1397 | break; |
1396 | default: | 1398 | default: |
1397 | break; | 1399 | break; |
@@ -1402,6 +1404,8 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, | |||
1402 | break; | 1404 | break; |
1403 | 1405 | ||
1404 | case SND_SOC_BIAS_OFF: | 1406 | case SND_SOC_BIAS_OFF: |
1407 | regcache_cache_only(wm5100->regmap, true); | ||
1408 | regcache_mark_dirty(wm5100->regmap); | ||
1405 | if (wm5100->pdata.ldo_ena) | 1409 | if (wm5100->pdata.ldo_ena) |
1406 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | 1410 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); |
1407 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), | 1411 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), |
@@ -2180,6 +2184,7 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) | |||
2180 | if (wm5100->jack_detecting) { | 2184 | if (wm5100->jack_detecting) { |
2181 | dev_dbg(codec->dev, "Microphone detected\n"); | 2185 | dev_dbg(codec->dev, "Microphone detected\n"); |
2182 | wm5100->jack_mic = true; | 2186 | wm5100->jack_mic = true; |
2187 | wm5100->jack_detecting = false; | ||
2183 | snd_soc_jack_report(wm5100->jack, | 2188 | snd_soc_jack_report(wm5100->jack, |
2184 | SND_JACK_HEADSET, | 2189 | SND_JACK_HEADSET, |
2185 | SND_JACK_HEADSET | SND_JACK_BTN_0); | 2190 | SND_JACK_HEADSET | SND_JACK_BTN_0); |
@@ -2218,6 +2223,7 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) | |||
2218 | SND_JACK_BTN_0); | 2223 | SND_JACK_BTN_0); |
2219 | } else if (wm5100->jack_detecting) { | 2224 | } else if (wm5100->jack_detecting) { |
2220 | dev_dbg(codec->dev, "Headphone detected\n"); | 2225 | dev_dbg(codec->dev, "Headphone detected\n"); |
2226 | wm5100->jack_detecting = false; | ||
2221 | snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, | 2227 | snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, |
2222 | SND_JACK_HEADPHONE); | 2228 | SND_JACK_HEADPHONE); |
2223 | 2229 | ||
@@ -2607,6 +2613,13 @@ static const struct regmap_config wm5100_regmap = { | |||
2607 | .cache_type = REGCACHE_RBTREE, | 2613 | .cache_type = REGCACHE_RBTREE, |
2608 | }; | 2614 | }; |
2609 | 2615 | ||
2616 | static const unsigned int wm5100_mic_ctrl_reg[] = { | ||
2617 | WM5100_IN1L_CONTROL, | ||
2618 | WM5100_IN2L_CONTROL, | ||
2619 | WM5100_IN3L_CONTROL, | ||
2620 | WM5100_IN4L_CONTROL, | ||
2621 | }; | ||
2622 | |||
2610 | static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | 2623 | static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, |
2611 | const struct i2c_device_id *id) | 2624 | const struct i2c_device_id *id) |
2612 | { | 2625 | { |
@@ -2739,7 +2752,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | |||
2739 | } | 2752 | } |
2740 | 2753 | ||
2741 | for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { | 2754 | for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { |
2742 | regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL, | 2755 | regmap_update_bits(wm5100->regmap, wm5100_mic_ctrl_reg[i], |
2743 | WM5100_IN1_MODE_MASK | | 2756 | WM5100_IN1_MODE_MASK | |
2744 | WM5100_IN1_DMIC_SUP_MASK, | 2757 | WM5100_IN1_DMIC_SUP_MASK, |
2745 | (wm5100->pdata.in_mode[i] << | 2758 | (wm5100->pdata.in_mode[i] << |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 8d4ea43d40a3..40ac888faf3d 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -55,7 +55,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, | |||
55 | return 0; | 55 | return 0; |
56 | 56 | ||
57 | if (fw->size < 32) { | 57 | if (fw->size < 32) { |
58 | dev_err(codec->dev, "%s: firmware too short (%d bytes)\n", | 58 | dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n", |
59 | name, fw->size); | 59 | name, fw->size); |
60 | goto err; | 60 | goto err; |
61 | } | 61 | } |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 296de4e30d26..0ac228b7dc04 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -96,7 +96,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \ | |||
96 | struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ | 96 | struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ |
97 | disable_nb[n]); \ | 97 | disable_nb[n]); \ |
98 | if (event & REGULATOR_EVENT_DISABLE) { \ | 98 | if (event & REGULATOR_EVENT_DISABLE) { \ |
99 | regcache_cache_only(wm8962->regmap, true); \ | 99 | regcache_mark_dirty(wm8962->regmap); \ |
100 | } \ | 100 | } \ |
101 | return 0; \ | 101 | return 0; \ |
102 | } | 102 | } |
@@ -2564,7 +2564,7 @@ static int dsp2_event(struct snd_soc_dapm_widget *w, | |||
2564 | return 0; | 2564 | return 0; |
2565 | } | 2565 | } |
2566 | 2566 | ||
2567 | static const char *st_text[] = { "None", "Right", "Left" }; | 2567 | static const char *st_text[] = { "None", "Left", "Right" }; |
2568 | 2568 | ||
2569 | static const struct soc_enum str_enum = | 2569 | static const struct soc_enum str_enum = |
2570 | SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text); | 2570 | SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text); |
@@ -3159,13 +3159,13 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, | |||
3159 | case SNDRV_PCM_FORMAT_S16_LE: | 3159 | case SNDRV_PCM_FORMAT_S16_LE: |
3160 | break; | 3160 | break; |
3161 | case SNDRV_PCM_FORMAT_S20_3LE: | 3161 | case SNDRV_PCM_FORMAT_S20_3LE: |
3162 | aif0 |= 0x40; | 3162 | aif0 |= 0x4; |
3163 | break; | 3163 | break; |
3164 | case SNDRV_PCM_FORMAT_S24_LE: | 3164 | case SNDRV_PCM_FORMAT_S24_LE: |
3165 | aif0 |= 0x80; | 3165 | aif0 |= 0x8; |
3166 | break; | 3166 | break; |
3167 | case SNDRV_PCM_FORMAT_S32_LE: | 3167 | case SNDRV_PCM_FORMAT_S32_LE: |
3168 | aif0 |= 0xc0; | 3168 | aif0 |= 0xc; |
3169 | break; | 3169 | break; |
3170 | default: | 3170 | default: |
3171 | return -EINVAL; | 3171 | return -EINVAL; |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 93d27b660257..ec69a6c152fe 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -770,6 +770,8 @@ static void vmid_reference(struct snd_soc_codec *codec) | |||
770 | { | 770 | { |
771 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 771 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
772 | 772 | ||
773 | pm_runtime_get_sync(codec->dev); | ||
774 | |||
773 | wm8994->vmid_refcount++; | 775 | wm8994->vmid_refcount++; |
774 | 776 | ||
775 | dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n", | 777 | dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n", |
@@ -783,7 +785,12 @@ static void vmid_reference(struct snd_soc_codec *codec) | |||
783 | WM8994_VMID_RAMP_MASK, | 785 | WM8994_VMID_RAMP_MASK, |
784 | WM8994_STARTUP_BIAS_ENA | | 786 | WM8994_STARTUP_BIAS_ENA | |
785 | WM8994_VMID_BUF_ENA | | 787 | WM8994_VMID_BUF_ENA | |
786 | (0x11 << WM8994_VMID_RAMP_SHIFT)); | 788 | (0x3 << WM8994_VMID_RAMP_SHIFT)); |
789 | |||
790 | /* Remove discharge for line out */ | ||
791 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, | ||
792 | WM8994_LINEOUT1_DISCH | | ||
793 | WM8994_LINEOUT2_DISCH, 0); | ||
787 | 794 | ||
788 | /* Main bias enable, VMID=2x40k */ | 795 | /* Main bias enable, VMID=2x40k */ |
789 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | 796 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, |
@@ -837,6 +844,8 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
837 | WM8994_VMID_BUF_ENA | | 844 | WM8994_VMID_BUF_ENA | |
838 | WM8994_VMID_RAMP_MASK, 0); | 845 | WM8994_VMID_RAMP_MASK, 0); |
839 | } | 846 | } |
847 | |||
848 | pm_runtime_put(codec->dev); | ||
840 | } | 849 | } |
841 | 850 | ||
842 | static int vmid_event(struct snd_soc_dapm_widget *w, | 851 | static int vmid_event(struct snd_soc_dapm_widget *w, |
@@ -2753,11 +2762,6 @@ static int wm8994_resume(struct snd_soc_codec *codec) | |||
2753 | codec->cache_only = 0; | 2762 | codec->cache_only = 0; |
2754 | } | 2763 | } |
2755 | 2764 | ||
2756 | /* Restore the registers */ | ||
2757 | ret = snd_soc_cache_sync(codec); | ||
2758 | if (ret != 0) | ||
2759 | dev_err(codec->dev, "Failed to sync cache: %d\n", ret); | ||
2760 | |||
2761 | wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 2765 | wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
2762 | 2766 | ||
2763 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { | 2767 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index d8da10fe5b52..61f7daa4d0e6 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -108,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \ | |||
108 | struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ | 108 | struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ |
109 | disable_nb[n]); \ | 109 | disable_nb[n]); \ |
110 | if (event & REGULATOR_EVENT_DISABLE) { \ | 110 | if (event & REGULATOR_EVENT_DISABLE) { \ |
111 | regcache_cache_only(wm8996->regmap, true); \ | 111 | regcache_mark_dirty(wm8996->regmap); \ |
112 | } \ | 112 | } \ |
113 | return 0; \ | 113 | return 0; \ |
114 | } | 114 | } |
@@ -1120,7 +1120,8 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), | |||
1120 | SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), | 1120 | SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), |
1121 | SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), | 1121 | SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), |
1122 | SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, | 1122 | SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, |
1123 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 1123 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
1124 | SND_SOC_DAPM_POST_PMD), | ||
1124 | SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, | 1125 | SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, |
1125 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 1126 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1126 | SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), | 1127 | SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), |
@@ -2007,6 +2008,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, | |||
2007 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 2008 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
2008 | int lfclk = 0; | 2009 | int lfclk = 0; |
2009 | int ratediv = 0; | 2010 | int ratediv = 0; |
2011 | int sync = WM8996_REG_SYNC; | ||
2010 | int src; | 2012 | int src; |
2011 | int old; | 2013 | int old; |
2012 | 2014 | ||
@@ -2051,6 +2053,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, | |||
2051 | case 32000: | 2053 | case 32000: |
2052 | case 32768: | 2054 | case 32768: |
2053 | lfclk = WM8996_LFCLK_ENA; | 2055 | lfclk = WM8996_LFCLK_ENA; |
2056 | sync = 0; | ||
2054 | break; | 2057 | break; |
2055 | default: | 2058 | default: |
2056 | dev_warn(codec->dev, "Unsupported clock rate %dHz\n", | 2059 | dev_warn(codec->dev, "Unsupported clock rate %dHz\n", |
@@ -2064,6 +2067,8 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, | |||
2064 | WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK, | 2067 | WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK, |
2065 | src << WM8996_SYSCLK_SRC_SHIFT | ratediv); | 2068 | src << WM8996_SYSCLK_SRC_SHIFT | ratediv); |
2066 | snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk); | 2069 | snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk); |
2070 | snd_soc_update_bits(codec, WM8996_CONTROL_INTERFACE_1, | ||
2071 | WM8996_REG_SYNC, sync); | ||
2067 | snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1, | 2072 | snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1, |
2068 | WM8996_SYSCLK_ENA, old); | 2073 | WM8996_SYSCLK_ENA, old); |
2069 | 2074 | ||
diff --git a/sound/soc/codecs/wm8996.h b/sound/soc/codecs/wm8996.h index 0fde643194ce..de9ac3e44aec 100644 --- a/sound/soc/codecs/wm8996.h +++ b/sound/soc/codecs/wm8996.h | |||
@@ -1567,6 +1567,10 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
1567 | /* | 1567 | /* |
1568 | * R257 (0x101) - Control Interface (1) | 1568 | * R257 (0x101) - Control Interface (1) |
1569 | */ | 1569 | */ |
1570 | #define WM8996_REG_SYNC 0x8000 /* REG_SYNC */ | ||
1571 | #define WM8996_REG_SYNC_MASK 0x8000 /* REG_SYNC */ | ||
1572 | #define WM8996_REG_SYNC_SHIFT 15 /* REG_SYNC */ | ||
1573 | #define WM8996_REG_SYNC_WIDTH 1 /* REG_SYNC */ | ||
1570 | #define WM8996_AUTO_INC 0x0004 /* AUTO_INC */ | 1574 | #define WM8996_AUTO_INC 0x0004 /* AUTO_INC */ |
1571 | #define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */ | 1575 | #define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */ |
1572 | #define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */ | 1576 | #define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */ |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 2a61094075f8..8a68cea4a3ee 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -586,14 +586,14 @@ SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0), | |||
586 | }; | 586 | }; |
587 | 587 | ||
588 | static const struct snd_kcontrol_new line2_mix[] = { | 588 | static const struct snd_kcontrol_new line2_mix[] = { |
589 | SOC_DAPM_SINGLE("IN2R Switch", WM8993_LINE_MIXER2, 2, 1, 0), | 589 | SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER2, 2, 1, 0), |
590 | SOC_DAPM_SINGLE("IN2L Switch", WM8993_LINE_MIXER2, 1, 1, 0), | 590 | SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER2, 1, 1, 0), |
591 | SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0), | 591 | SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0), |
592 | }; | 592 | }; |
593 | 593 | ||
594 | static const struct snd_kcontrol_new line2n_mix[] = { | 594 | static const struct snd_kcontrol_new line2n_mix[] = { |
595 | SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), | 595 | SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), |
596 | SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), | 596 | SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), |
597 | }; | 597 | }; |
598 | 598 | ||
599 | static const struct snd_kcontrol_new line2p_mix[] = { | 599 | static const struct snd_kcontrol_new line2p_mix[] = { |
@@ -613,6 +613,8 @@ SND_SOC_DAPM_INPUT("IN2RP:VXRP"), | |||
613 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), | 613 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), |
614 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), | 614 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), |
615 | 615 | ||
616 | SND_SOC_DAPM_SUPPLY("LINEOUT_VMID_BUF", WM8993_ANTIPOP1, 7, 0, NULL, 0), | ||
617 | |||
616 | SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, | 618 | SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, |
617 | in1l_pga, ARRAY_SIZE(in1l_pga)), | 619 | in1l_pga, ARRAY_SIZE(in1l_pga)), |
618 | SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0, | 620 | SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0, |
@@ -834,9 +836,11 @@ static const struct snd_soc_dapm_route lineout1_diff_routes[] = { | |||
834 | }; | 836 | }; |
835 | 837 | ||
836 | static const struct snd_soc_dapm_route lineout1_se_routes[] = { | 838 | static const struct snd_soc_dapm_route lineout1_se_routes[] = { |
839 | { "LINEOUT1N Mixer", NULL, "LINEOUT_VMID_BUF" }, | ||
837 | { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, | 840 | { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, |
838 | { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, | 841 | { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, |
839 | 842 | ||
843 | { "LINEOUT1P Mixer", NULL, "LINEOUT_VMID_BUF" }, | ||
840 | { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, | 844 | { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, |
841 | 845 | ||
842 | { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, | 846 | { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, |
@@ -844,8 +848,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = { | |||
844 | }; | 848 | }; |
845 | 849 | ||
846 | static const struct snd_soc_dapm_route lineout2_diff_routes[] = { | 850 | static const struct snd_soc_dapm_route lineout2_diff_routes[] = { |
847 | { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, | 851 | { "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" }, |
848 | { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, | 852 | { "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" }, |
849 | { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, | 853 | { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, |
850 | 854 | ||
851 | { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, | 855 | { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, |
@@ -853,9 +857,11 @@ static const struct snd_soc_dapm_route lineout2_diff_routes[] = { | |||
853 | }; | 857 | }; |
854 | 858 | ||
855 | static const struct snd_soc_dapm_route lineout2_se_routes[] = { | 859 | static const struct snd_soc_dapm_route lineout2_se_routes[] = { |
860 | { "LINEOUT2N Mixer", NULL, "LINEOUT_VMID_BUF" }, | ||
856 | { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, | 861 | { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, |
857 | { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, | 862 | { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, |
858 | 863 | ||
864 | { "LINEOUT2P Mixer", NULL, "LINEOUT_VMID_BUF" }, | ||
859 | { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, | 865 | { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, |
860 | 866 | ||
861 | { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, | 867 | { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, |
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index dccfb37a9626..f204dbac11d4 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -124,6 +124,8 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, | |||
124 | * | 124 | * |
125 | * If MCLK is not used, we just set saif clk to 512*fs. | 125 | * If MCLK is not used, we just set saif clk to 512*fs. |
126 | */ | 126 | */ |
127 | clk_prepare_enable(master_saif->clk); | ||
128 | |||
127 | if (master_saif->mclk_in_use) { | 129 | if (master_saif->mclk_in_use) { |
128 | if (mclk % 32 == 0) { | 130 | if (mclk % 32 == 0) { |
129 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; | 131 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; |
@@ -133,6 +135,7 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, | |||
133 | ret = clk_set_rate(master_saif->clk, 384 * rate); | 135 | ret = clk_set_rate(master_saif->clk, 384 * rate); |
134 | } else { | 136 | } else { |
135 | /* SAIF MCLK should be either 32x or 48x */ | 137 | /* SAIF MCLK should be either 32x or 48x */ |
138 | clk_disable_unprepare(master_saif->clk); | ||
136 | return -EINVAL; | 139 | return -EINVAL; |
137 | } | 140 | } |
138 | } else { | 141 | } else { |
@@ -140,6 +143,8 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, | |||
140 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; | 143 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; |
141 | } | 144 | } |
142 | 145 | ||
146 | clk_disable_unprepare(master_saif->clk); | ||
147 | |||
143 | if (ret) | 148 | if (ret) |
144 | return ret; | 149 | return ret; |
145 | 150 | ||
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 7ac0ba2025c3..c6012ff5bd3e 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c | |||
@@ -230,8 +230,6 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { | |||
230 | 230 | ||
231 | /* GTA02 specific routes and controls */ | 231 | /* GTA02 specific routes and controls */ |
232 | 232 | ||
233 | #ifdef CONFIG_MACH_NEO1973_GTA02 | ||
234 | |||
235 | static int gta02_speaker_enabled; | 233 | static int gta02_speaker_enabled; |
236 | 234 | ||
237 | static int lm4853_set_spk(struct snd_kcontrol *kcontrol, | 235 | static int lm4853_set_spk(struct snd_kcontrol *kcontrol, |
@@ -311,10 +309,6 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) | |||
311 | return 0; | 309 | return 0; |
312 | } | 310 | } |
313 | 311 | ||
314 | #else | ||
315 | static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; } | ||
316 | #endif | ||
317 | |||
318 | static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | 312 | static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) |
319 | { | 313 | { |
320 | struct snd_soc_codec *codec = rtd->codec; | 314 | struct snd_soc_codec *codec = rtd->codec; |
@@ -322,10 +316,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | |||
322 | int ret; | 316 | int ret; |
323 | 317 | ||
324 | /* set up NC codec pins */ | 318 | /* set up NC codec pins */ |
325 | if (machine_is_neo1973_gta01()) { | ||
326 | snd_soc_dapm_nc_pin(dapm, "LOUT2"); | ||
327 | snd_soc_dapm_nc_pin(dapm, "ROUT2"); | ||
328 | } | ||
329 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | 319 | snd_soc_dapm_nc_pin(dapm, "OUT3"); |
330 | snd_soc_dapm_nc_pin(dapm, "OUT4"); | 320 | snd_soc_dapm_nc_pin(dapm, "OUT4"); |
331 | snd_soc_dapm_nc_pin(dapm, "LINE1"); | 321 | snd_soc_dapm_nc_pin(dapm, "LINE1"); |
@@ -370,50 +360,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | |||
370 | return 0; | 360 | return 0; |
371 | } | 361 | } |
372 | 362 | ||
373 | /* GTA01 specific controls */ | ||
374 | |||
375 | #ifdef CONFIG_MACH_NEO1973_GTA01 | ||
376 | |||
377 | static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = { | ||
378 | {"Amp IN", NULL, "ROUT1"}, | ||
379 | {"Amp IN", NULL, "LOUT1"}, | ||
380 | |||
381 | {"Handset Spk", NULL, "Amp EP"}, | ||
382 | {"Stereo Out", NULL, "Amp LS"}, | ||
383 | {"Headphone", NULL, "Amp HP"}, | ||
384 | }; | ||
385 | |||
386 | static const struct snd_soc_dapm_widget neo1973_lm4857_dapm_widgets[] = { | ||
387 | SND_SOC_DAPM_SPK("Handset Spk", NULL), | ||
388 | SND_SOC_DAPM_SPK("Stereo Out", NULL), | ||
389 | SND_SOC_DAPM_HP("Headphone", NULL), | ||
390 | }; | ||
391 | |||
392 | static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) | ||
393 | { | ||
394 | int ret; | ||
395 | |||
396 | ret = snd_soc_dapm_new_controls(dapm, neo1973_lm4857_dapm_widgets, | ||
397 | ARRAY_SIZE(neo1973_lm4857_dapm_widgets)); | ||
398 | if (ret) | ||
399 | return ret; | ||
400 | |||
401 | ret = snd_soc_dapm_add_routes(dapm, neo1973_lm4857_routes, | ||
402 | ARRAY_SIZE(neo1973_lm4857_routes)); | ||
403 | if (ret) | ||
404 | return ret; | ||
405 | |||
406 | snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); | ||
407 | snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); | ||
408 | snd_soc_dapm_ignore_suspend(dapm, "Headphone"); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | #else | ||
414 | static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; }; | ||
415 | #endif | ||
416 | |||
417 | static struct snd_soc_dai_link neo1973_dai[] = { | 363 | static struct snd_soc_dai_link neo1973_dai[] = { |
418 | { /* Hifi Playback - for similatious use with voice below */ | 364 | { /* Hifi Playback - for similatious use with voice below */ |
419 | .name = "WM8753", | 365 | .name = "WM8753", |
@@ -440,11 +386,6 @@ static struct snd_soc_aux_dev neo1973_aux_devs[] = { | |||
440 | .name = "dfbmcs320", | 386 | .name = "dfbmcs320", |
441 | .codec_name = "dfbmcs320.0", | 387 | .codec_name = "dfbmcs320.0", |
442 | }, | 388 | }, |
443 | { | ||
444 | .name = "lm4857", | ||
445 | .codec_name = "lm4857.0-007c", | ||
446 | .init = neo1973_lm4857_init, | ||
447 | }, | ||
448 | }; | 389 | }; |
449 | 390 | ||
450 | static struct snd_soc_codec_conf neo1973_codec_conf[] = { | 391 | static struct snd_soc_codec_conf neo1973_codec_conf[] = { |
@@ -454,14 +395,10 @@ static struct snd_soc_codec_conf neo1973_codec_conf[] = { | |||
454 | }, | 395 | }, |
455 | }; | 396 | }; |
456 | 397 | ||
457 | #ifdef CONFIG_MACH_NEO1973_GTA02 | ||
458 | static const struct gpio neo1973_gta02_gpios[] = { | 398 | static const struct gpio neo1973_gta02_gpios[] = { |
459 | { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, | 399 | { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, |
460 | { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, | 400 | { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, |
461 | }; | 401 | }; |
462 | #else | ||
463 | static const struct gpio neo1973_gta02_gpios[] = {}; | ||
464 | #endif | ||
465 | 402 | ||
466 | static struct snd_soc_card neo1973 = { | 403 | static struct snd_soc_card neo1973 = { |
467 | .name = "neo1973", | 404 | .name = "neo1973", |
@@ -480,7 +417,7 @@ static int __init neo1973_init(void) | |||
480 | { | 417 | { |
481 | int ret; | 418 | int ret; |
482 | 419 | ||
483 | if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02()) | 420 | if (!machine_is_neo1973_gta02()) |
484 | return -ENODEV; | 421 | return -ENODEV; |
485 | 422 | ||
486 | if (machine_is_neo1973_gta02()) { | 423 | if (machine_is_neo1973_gta02()) { |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index db6c89a28bda..ea4a82d01160 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -1152,12 +1152,8 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) | |||
1152 | { | 1152 | { |
1153 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1153 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1154 | struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream)); | 1154 | struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream)); |
1155 | int samples_pos = io->buff_sample_pos - 1; | ||
1156 | 1155 | ||
1157 | if (samples_pos < 0) | 1156 | return fsi_sample2frame(fsi, io->buff_sample_pos); |
1158 | samples_pos = 0; | ||
1159 | |||
1160 | return fsi_sample2frame(fsi, samples_pos); | ||
1161 | } | 1157 | } |
1162 | 1158 | ||
1163 | static struct snd_pcm_ops fsi_pcm_ops = { | 1159 | static struct snd_pcm_ops fsi_pcm_ops = { |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b5ecf6d23214..92cee24ed2dc 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -567,6 +567,17 @@ int snd_soc_suspend(struct device *dev) | |||
567 | if (!codec->suspended && codec->driver->suspend) { | 567 | if (!codec->suspended && codec->driver->suspend) { |
568 | switch (codec->dapm.bias_level) { | 568 | switch (codec->dapm.bias_level) { |
569 | case SND_SOC_BIAS_STANDBY: | 569 | case SND_SOC_BIAS_STANDBY: |
570 | /* | ||
571 | * If the CODEC is capable of idle | ||
572 | * bias off then being in STANDBY | ||
573 | * means it's doing something, | ||
574 | * otherwise fall through. | ||
575 | */ | ||
576 | if (codec->dapm.idle_bias_off) { | ||
577 | dev_dbg(codec->dev, | ||
578 | "idle_bias_off CODEC on over suspend\n"); | ||
579 | break; | ||
580 | } | ||
570 | case SND_SOC_BIAS_OFF: | 581 | case SND_SOC_BIAS_OFF: |
571 | codec->driver->suspend(codec); | 582 | codec->driver->suspend(codec); |
572 | codec->suspended = 1; | 583 | codec->suspended = 1; |
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 2cf87f5afed4..fde9a7a29cb6 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c | |||
@@ -311,8 +311,10 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) | |||
311 | 311 | ||
312 | spin_lock(&dev->spinlock); | 312 | spin_lock(&dev->spinlock); |
313 | 313 | ||
314 | if (dev->input_panic || dev->output_panic) | 314 | if (dev->input_panic || dev->output_panic) { |
315 | ptr = SNDRV_PCM_POS_XRUN; | 315 | ptr = SNDRV_PCM_POS_XRUN; |
316 | goto unlock; | ||
317 | } | ||
316 | 318 | ||
317 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | 319 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
318 | ptr = bytes_to_frames(sub->runtime, | 320 | ptr = bytes_to_frames(sub->runtime, |
@@ -321,6 +323,7 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) | |||
321 | ptr = bytes_to_frames(sub->runtime, | 323 | ptr = bytes_to_frames(sub->runtime, |
322 | dev->audio_in_buf_pos[index]); | 324 | dev->audio_in_buf_pos[index]); |
323 | 325 | ||
326 | unlock: | ||
324 | spin_unlock(&dev->spinlock); | 327 | spin_unlock(&dev->spinlock); |
325 | return ptr; | 328 | return ptr; |
326 | } | 329 | } |
diff --git a/sound/usb/card.h b/sound/usb/card.h index a39edcc32a93..da5fa1ac4eda 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __USBAUDIO_CARD_H | 1 | #ifndef __USBAUDIO_CARD_H |
2 | #define __USBAUDIO_CARD_H | 2 | #define __USBAUDIO_CARD_H |
3 | 3 | ||
4 | #define MAX_NR_RATES 1024 | ||
4 | #define MAX_PACKS 20 | 5 | #define MAX_PACKS 20 |
5 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ | 6 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ |
6 | #define MAX_URBS 8 | 7 | #define MAX_URBS 8 |
diff --git a/sound/usb/format.c b/sound/usb/format.c index e09aba19375c..ddfef57c4c9f 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -209,8 +209,6 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof | |||
209 | return 0; | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
212 | #define MAX_UAC2_NR_RATES 1024 | ||
213 | |||
214 | /* | 212 | /* |
215 | * Helper function to walk the array of sample rate triplets reported by | 213 | * Helper function to walk the array of sample rate triplets reported by |
216 | * the device. The problem is that we need to parse whole array first to | 214 | * the device. The problem is that we need to parse whole array first to |
@@ -255,7 +253,7 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, | |||
255 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); | 253 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); |
256 | 254 | ||
257 | nr_rates++; | 255 | nr_rates++; |
258 | if (nr_rates >= MAX_UAC2_NR_RATES) { | 256 | if (nr_rates >= MAX_NR_RATES) { |
259 | snd_printk(KERN_ERR "invalid uac2 rates\n"); | 257 | snd_printk(KERN_ERR "invalid uac2 rates\n"); |
260 | break; | 258 | break; |
261 | } | 259 | } |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 8edc5035fc8f..d89ab4c7d44b 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1618,6 +1618,14 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1618 | } | 1618 | } |
1619 | }, | 1619 | }, |
1620 | { | 1620 | { |
1621 | /* Edirol UM-3G */ | ||
1622 | USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108), | ||
1623 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1624 | .ifnum = 0, | ||
1625 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
1626 | } | ||
1627 | }, | ||
1628 | { | ||
1621 | /* Boss JS-8 Jam Station */ | 1629 | /* Boss JS-8 Jam Station */ |
1622 | USB_DEVICE(0x0582, 0x0109), | 1630 | USB_DEVICE(0x0582, 0x0109), |
1623 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1631 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index a3ddac0deffd..27817266867a 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -132,10 +132,14 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
132 | unsigned *rate_table = NULL; | 132 | unsigned *rate_table = NULL; |
133 | 133 | ||
134 | fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL); | 134 | fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL); |
135 | if (! fp) { | 135 | if (!fp) { |
136 | snd_printk(KERN_ERR "cannot memdup\n"); | 136 | snd_printk(KERN_ERR "cannot memdup\n"); |
137 | return -ENOMEM; | 137 | return -ENOMEM; |
138 | } | 138 | } |
139 | if (fp->nr_rates > MAX_NR_RATES) { | ||
140 | kfree(fp); | ||
141 | return -EINVAL; | ||
142 | } | ||
139 | if (fp->nr_rates > 0) { | 143 | if (fp->nr_rates > 0) { |
140 | rate_table = kmemdup(fp->rate_table, | 144 | rate_table = kmemdup(fp->rate_table, |
141 | sizeof(int) * fp->nr_rates, GFP_KERNEL); | 145 | sizeof(int) * fp->nr_rates, GFP_KERNEL); |