diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-11-06 09:47:50 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-11-06 09:47:50 -0500 |
commit | 167eae5a17b3cd44a324dbb972c338e489413f54 (patch) | |
tree | 15019380cbb9b82daca5716a251a41722c9770d0 /sound | |
parent | 9ad6a46b6497ae64e7fec307deb0de88e6a8ca06 (diff) |
ALSA: hda - Reset pins of IDT/STAC codecs at free
Some laptops cause annoying clicks or noises at shutdown/reboot since
the speaker pin is set still high. Apply the same procedure used for
the suspend to avoid such clicks/noises for freeing the codec, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 8eb6508cd991..3087705a8e51 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -4327,6 +4327,28 @@ static void stac92xx_free_kctls(struct hda_codec *codec) | |||
4327 | snd_array_free(&spec->kctls); | 4327 | snd_array_free(&spec->kctls); |
4328 | } | 4328 | } |
4329 | 4329 | ||
4330 | static void stac92xx_shutup(struct hda_codec *codec) | ||
4331 | { | ||
4332 | struct sigmatel_spec *spec = codec->spec; | ||
4333 | int i; | ||
4334 | hda_nid_t nid; | ||
4335 | |||
4336 | /* reset each pin before powering down DAC/ADC to avoid click noise */ | ||
4337 | nid = codec->start_nid; | ||
4338 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
4339 | unsigned int wcaps = get_wcaps(codec, nid); | ||
4340 | unsigned int wid_type = get_wcaps_type(wcaps); | ||
4341 | if (wid_type == AC_WID_PIN) | ||
4342 | snd_hda_codec_read(codec, nid, 0, | ||
4343 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
4344 | } | ||
4345 | |||
4346 | if (spec->eapd_mask) | ||
4347 | stac_gpio_set(codec, spec->gpio_mask, | ||
4348 | spec->gpio_dir, spec->gpio_data & | ||
4349 | ~spec->eapd_mask); | ||
4350 | } | ||
4351 | |||
4330 | static void stac92xx_free(struct hda_codec *codec) | 4352 | static void stac92xx_free(struct hda_codec *codec) |
4331 | { | 4353 | { |
4332 | struct sigmatel_spec *spec = codec->spec; | 4354 | struct sigmatel_spec *spec = codec->spec; |
@@ -4334,6 +4356,7 @@ static void stac92xx_free(struct hda_codec *codec) | |||
4334 | if (! spec) | 4356 | if (! spec) |
4335 | return; | 4357 | return; |
4336 | 4358 | ||
4359 | stac92xx_shutup(codec); | ||
4337 | stac92xx_free_jacks(codec); | 4360 | stac92xx_free_jacks(codec); |
4338 | snd_array_free(&spec->events); | 4361 | snd_array_free(&spec->events); |
4339 | 4362 | ||
@@ -4793,24 +4816,7 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, | |||
4793 | 4816 | ||
4794 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | 4817 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) |
4795 | { | 4818 | { |
4796 | struct sigmatel_spec *spec = codec->spec; | 4819 | stac92xx_shutup(codec); |
4797 | int i; | ||
4798 | hda_nid_t nid; | ||
4799 | |||
4800 | /* reset each pin before powering down DAC/ADC to avoid click noise */ | ||
4801 | nid = codec->start_nid; | ||
4802 | for (i = 0; i < codec->num_nodes; i++, nid++) { | ||
4803 | unsigned int wcaps = get_wcaps(codec, nid); | ||
4804 | unsigned int wid_type = get_wcaps_type(wcaps); | ||
4805 | if (wid_type == AC_WID_PIN) | ||
4806 | snd_hda_codec_read(codec, nid, 0, | ||
4807 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
4808 | } | ||
4809 | |||
4810 | if (spec->eapd_mask) | ||
4811 | stac_gpio_set(codec, spec->gpio_mask, | ||
4812 | spec->gpio_dir, spec->gpio_data & | ||
4813 | ~spec->eapd_mask); | ||
4814 | return 0; | 4820 | return 0; |
4815 | } | 4821 | } |
4816 | #endif | 4822 | #endif |