aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-05-08 10:52:23 -0400
committerTakashi Iwai <tiwai@suse.de>2012-05-08 12:00:47 -0400
commit7f30830b7b82e5225c38a48b387e44f3defe40e2 (patch)
tree18eed775bdfb03289a993de5f2859e0a8683eb74 /sound/pci
parentc382a9f009d7332e16919154e01f5554eeb095ed (diff)
ALSA: hda - Always resume the codec immediately
This is a fix for the problem in commit 785f857d1c, the pop noise issue on some machines with ALC269. The problem was the uninitialized state after the resume due to the delayed resume of the codec chips. In that commit, we tried to fix by forcibly putting the codec to D3 at suspend. But, this still also leaves the uninitialized state after resume, and it _might_ be still problematic with some BIOS. Since the commit turned out to regress another issues, we reverted it in the end. Now, in this fix, try to fix by turning on the codec immediately at the resume path. We need to take care of the power-saving in this case. When the device is woken up at the power-saved state, it should go power-saving again after the resume. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c9
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_intel.c14
3 files changed, 8 insertions, 17 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 98976c8ed107..e134e7212cd9 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -3500,6 +3500,10 @@ static void hda_call_codec_suspend(struct hda_codec *codec)
3500 */ 3500 */
3501static void hda_call_codec_resume(struct hda_codec *codec) 3501static void hda_call_codec_resume(struct hda_codec *codec)
3502{ 3502{
3503 /* set as if powered on for avoiding re-entering the resume
3504 * in the resume / power-save sequence
3505 */
3506 hda_keep_power_on(codec);
3503 hda_set_power_state(codec, 3507 hda_set_power_state(codec,
3504 codec->afg ? codec->afg : codec->mfg, 3508 codec->afg ? codec->afg : codec->mfg,
3505 AC_PWRST_D0); 3509 AC_PWRST_D0);
@@ -3515,6 +3519,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
3515 snd_hda_codec_resume_amp(codec); 3519 snd_hda_codec_resume_amp(codec);
3516 snd_hda_codec_resume_cache(codec); 3520 snd_hda_codec_resume_cache(codec);
3517 } 3521 }
3522 snd_hda_power_down(codec); /* flag down before returning */
3518} 3523}
3519#endif /* CONFIG_PM */ 3524#endif /* CONFIG_PM */
3520 3525
@@ -4332,6 +4337,7 @@ void snd_hda_power_up(struct hda_codec *codec)
4332 snd_hda_update_power_acct(codec); 4337 snd_hda_update_power_acct(codec);
4333 codec->power_on = 1; 4338 codec->power_on = 1;
4334 codec->power_jiffies = jiffies; 4339 codec->power_jiffies = jiffies;
4340 codec->power_transition = 1; /* avoid reentrance */
4335 if (bus->ops.pm_notify) 4341 if (bus->ops.pm_notify)
4336 bus->ops.pm_notify(bus); 4342 bus->ops.pm_notify(bus);
4337 hda_call_codec_resume(codec); 4343 hda_call_codec_resume(codec);
@@ -5521,8 +5527,7 @@ int snd_hda_resume(struct hda_bus *bus)
5521 list_for_each_entry(codec, &bus->codec_list, list) { 5527 list_for_each_entry(codec, &bus->codec_list, list) {
5522 if (codec->patch_ops.pre_resume) 5528 if (codec->patch_ops.pre_resume)
5523 codec->patch_ops.pre_resume(codec); 5529 codec->patch_ops.pre_resume(codec);
5524 if (snd_hda_codec_needs_resume(codec)) 5530 hda_call_codec_resume(codec);
5525 hda_call_codec_resume(codec);
5526 } 5531 }
5527 return 0; 5532 return 0;
5528} 5533}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 56b4f74c0b13..0fe64912cefc 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -1051,12 +1051,10 @@ const char *snd_hda_get_jack_location(u32 cfg);
1051#ifdef CONFIG_SND_HDA_POWER_SAVE 1051#ifdef CONFIG_SND_HDA_POWER_SAVE
1052void snd_hda_power_up(struct hda_codec *codec); 1052void snd_hda_power_up(struct hda_codec *codec);
1053void snd_hda_power_down(struct hda_codec *codec); 1053void snd_hda_power_down(struct hda_codec *codec);
1054#define snd_hda_codec_needs_resume(codec) codec->power_count
1055void snd_hda_update_power_acct(struct hda_codec *codec); 1054void snd_hda_update_power_acct(struct hda_codec *codec);
1056#else 1055#else
1057static inline void snd_hda_power_up(struct hda_codec *codec) {} 1056static inline void snd_hda_power_up(struct hda_codec *codec) {}
1058static inline void snd_hda_power_down(struct hda_codec *codec) {} 1057static inline void snd_hda_power_down(struct hda_codec *codec) {}
1059#define snd_hda_codec_needs_resume(codec) 1
1060#endif 1058#endif
1061 1059
1062#ifdef CONFIG_SND_HDA_PATCH_LOADER 1060#ifdef CONFIG_SND_HDA_PATCH_LOADER
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);