Commit 785f857d authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 546bb678
...@@ -5281,6 +5281,10 @@ int snd_hda_suspend(struct hda_bus *bus) ...@@ -5281,6 +5281,10 @@ int snd_hda_suspend(struct hda_bus *bus)
list_for_each_entry(codec, &bus->codec_list, list) { list_for_each_entry(codec, &bus->codec_list, list) {
if (hda_codec_is_power_on(codec)) if (hda_codec_is_power_on(codec))
hda_call_codec_suspend(codec); hda_call_codec_suspend(codec);
else /* forcibly change the power to D3 even if not used */
hda_set_power_state(codec,
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D3);
if (codec->patch_ops.post_suspend) if (codec->patch_ops.post_suspend)
codec->patch_ops.post_suspend(codec); codec->patch_ops.post_suspend(codec);
} }
......
...@@ -2351,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus) ...@@ -2351,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus)
* power management * power management
*/ */
static int snd_hda_codecs_inuse(struct hda_bus *bus)
{
struct hda_codec *codec;
list_for_each_entry(codec, &bus->codec_list, list) {
if (snd_hda_codec_needs_resume(codec))
return 1;
}
return 0;
}
static int azx_suspend(struct pci_dev *pci, pm_message_t state) static int azx_suspend(struct pci_dev *pci, pm_message_t state)
{ {
struct snd_card *card = pci_get_drvdata(pci); struct snd_card *card = pci_get_drvdata(pci);
...@@ -2408,7 +2397,6 @@ static int azx_resume(struct pci_dev *pci) ...@@ -2408,7 +2397,6 @@ static int azx_resume(struct pci_dev *pci)
return -EIO; return -EIO;
azx_init_pci(chip); azx_init_pci(chip);
if (snd_hda_codecs_inuse(chip->bus))
azx_init_chip(chip, 1); azx_init_chip(chip, 1);
snd_hda_resume(chip->bus); snd_hda_resume(chip->bus);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment