]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From 05ff7e11b78f18ff6819d2c260b7bcc7da0c8f46 Mon Sep 17 00:00:00 2001 |
2 | From: Takashi Iwai <tiwai@suse.de> | |
3 | Subject: [PATCH] ALSA: hda - Reduce click noise at power-saving | |
4 | Patch-mainline: | |
5 | References: bnc#521190 | |
6 | ||
7 | Add some tricks to reduce the click noise at powering down to D3 | |
8 | in the power saving mode on STAC/IDT codecs. | |
9 | The key seems to be to reset PINs before the power-down, and some | |
10 | delay before entering D3. The needed delay is significantly long, | |
11 | but I don't know why. | |
12 | ||
13 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
14 | ||
15 | --- | |
16 | sound/pci/hda/hda_codec.c | 9 +++++++-- | |
17 | sound/pci/hda/patch_sigmatel.c | 14 ++++++++++++++ | |
18 | 2 files changed, 21 insertions(+), 2 deletions(-) | |
19 | ||
20 | --- a/sound/pci/hda/hda_codec.c | |
21 | +++ b/sound/pci/hda/hda_codec.c | |
22 | @@ -1979,9 +1979,14 @@ static void hda_set_power_state(struct h | |
23 | hda_nid_t nid; | |
24 | int i; | |
25 | ||
26 | - snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, | |
27 | + /* this delay seems necessary to avoid click noise at power-down */ | |
28 | + if (power_state == AC_PWRST_D3) | |
29 | + msleep(100); | |
30 | + snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | |
31 | power_state); | |
32 | - msleep(10); /* partial workaround for "azx_get_response timeout" */ | |
33 | + /* partial workaround for "azx_get_response timeout" */ | |
34 | + if (power_state == AC_PWRST_D0) | |
35 | + msleep(10); | |
36 | ||
37 | nid = codec->start_nid; | |
38 | for (i = 0; i < codec->num_nodes; i++, nid++) { | |
39 | --- a/sound/pci/hda/patch_sigmatel.c | |
40 | +++ b/sound/pci/hda/patch_sigmatel.c | |
41 | @@ -4268,6 +4268,20 @@ static int stac92xx_resume(struct hda_co | |
42 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | |
43 | { | |
44 | struct sigmatel_spec *spec = codec->spec; | |
45 | + int i; | |
46 | + hda_nid_t nid; | |
47 | + | |
48 | + /* reset each pin before powering down DAC/ADC to avoid click noise */ | |
49 | + nid = codec->start_nid; | |
50 | + for (i = 0; i < codec->num_nodes; i++, nid++) { | |
51 | + unsigned int wcaps = get_wcaps(codec, nid); | |
52 | + unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> | |
53 | + AC_WCAP_TYPE_SHIFT; | |
54 | + if (wid_type == AC_WID_PIN) | |
55 | + snd_hda_codec_read(codec, nid, 0, | |
56 | + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | |
57 | + } | |
58 | + | |
59 | if (spec->eapd_mask) | |
60 | stac_gpio_set(codec, spec->gpio_mask, | |
61 | spec->gpio_dir, spec->gpio_data & |