aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-07 04:58:39 -0500
committerTakashi Iwai <tiwai@suse.de>2012-03-07 05:52:50 -0500
commit785f857d1cb0856b612b46a0545b74aa2596e44a (patch)
treedc7d18889a15f5dd835fa466ba95cfd9ce0a3c6c /sound/pci
parent546bb6785265f3413fa76e06b9fdce58ee15ea87 (diff)
ALSA: hda - Set codec to D3 forcibly even if not used
We've seen a problem with a pop-noise at suspend/resume on a HP machine with ALC269, and it turned out to be an issue that the controller going to D3 while the codec is unused. When the device is once suspended and resumed and kept unused, the driver doesn't initialize the codecs. Instead, the codec chips are set up dynamically at the first usage. Now, suppose the device going to suspend again before the codec is set up. The controller is turned off to D3 while the codec chips are untouched. This caused a pop noise because the codec chip might have been turned on implicitly by the hardware. As a workaround, the codec chip needs to be set to D3 when going to suspend no matter whether it was used or not. Also, for making it happening, the controller has to be always set up in the resume path. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c4
-rw-r--r--sound/pci/hda/hda_intel.c14
2 files changed, 5 insertions, 13 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 76bac4fc0472..0527ae1ab96e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -5281,6 +5281,10 @@ int snd_hda_suspend(struct hda_bus *bus)
5281 list_for_each_entry(codec, &bus->codec_list, list) { 5281 list_for_each_entry(codec, &bus->codec_list, list) {
5282 if (hda_codec_is_power_on(codec)) 5282 if (hda_codec_is_power_on(codec))
5283 hda_call_codec_suspend(codec); 5283 hda_call_codec_suspend(codec);
5284 else /* forcibly change the power to D3 even if not used */
5285 hda_set_power_state(codec,
5286 codec->afg ? codec->afg : codec->mfg,
5287 AC_PWRST_D3);
5284 if (codec->patch_ops.post_suspend) 5288 if (codec->patch_ops.post_suspend)
5285 codec->patch_ops.post_suspend(codec); 5289 codec->patch_ops.post_suspend(codec);
5286 } 5290 }
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 6e958bf94191..c19e71a94e1b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2351,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus)
2351 * power management 2351 * power management
2352 */ 2352 */
2353 2353
2354static int snd_hda_codecs_inuse(struct hda_bus *bus)
2355{
2356 struct hda_codec *codec;
2357
2358 list_for_each_entry(codec, &bus->codec_list, list) {
2359 if (snd_hda_codec_needs_resume(codec))
2360 return 1;
2361 }
2362 return 0;
2363}
2364
2365static int azx_suspend(struct pci_dev *pci, pm_message_t state) 2354static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2366{ 2355{
2367 struct snd_card *card = pci_get_drvdata(pci); 2356 struct snd_card *card = pci_get_drvdata(pci);
@@ -2408,8 +2397,7 @@ static int azx_resume(struct pci_dev *pci)
2408 return -EIO; 2397 return -EIO;
2409 azx_init_pci(chip); 2398 azx_init_pci(chip);
2410 2399
2411 if (snd_hda_codecs_inuse(chip->bus)) 2400 azx_init_chip(chip, 1);
2412 azx_init_chip(chip, 1);
2413 2401
2414 snd_hda_resume(chip->bus); 2402 snd_hda_resume(chip->bus);
2415 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2403 snd_power_change_state(card, SNDRV_CTL_POWER_D0);