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); |
