diff options
author | Wang Xingchao <xingchao.wang@linux.intel.com> | 2013-07-25 23:34:46 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-07-29 08:33:20 -0400 |
commit | 7d4f606c50ffaaa3ac60b7faf770dc6e84af3207 (patch) | |
tree | b833c9ec23b4496a61e96d7887469c3bf47722af /sound/pci/hda/hda_intel.c | |
parent | 18e606275691726cce06ad803072ac54315740f7 (diff) |
ALSA: hda - WAKEEN feature enabling for runtime pm
With runtime power save feature enabled, Headphone hotplug
event will not be detected while controller/codec in D3. HDA has
feature WAKEEN to let codec wake up system if controller is in D3 or
system in S3.(HDA Spec 4.5.9.2/3). Codec can send out INT or wake up
controller depending on whether CIE or GIE enabled.(Figure 4, Interupt
structure).
The controller must be in RESET mode after enter runtime-suspend, otherwise
it will not be waken up even if codec send out wake-up event. And STATESTS
will be cleared after controller brought out of RESET mode.
This patch only enable WAKEEN for runtime-suspend(Controller D3) mode,
not for system S3 mode. with tool "evtest", Headphone hotplug events
could be cought and reported successfully.
[fixed an unused variable warning by tiwai]
Signed-off-by: Wang Xingchao <xingchao.wang@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3f16c4bafc1a..7f9e4062a8d7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2971,6 +2971,10 @@ static int azx_runtime_suspend(struct device *dev) | |||
2971 | struct snd_card *card = dev_get_drvdata(dev); | 2971 | struct snd_card *card = dev_get_drvdata(dev); |
2972 | struct azx *chip = card->private_data; | 2972 | struct azx *chip = card->private_data; |
2973 | 2973 | ||
2974 | /* enable controller wake up event */ | ||
2975 | azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) | | ||
2976 | STATESTS_INT_MASK); | ||
2977 | |||
2974 | azx_stop_chip(chip); | 2978 | azx_stop_chip(chip); |
2975 | azx_enter_link_reset(chip); | 2979 | azx_enter_link_reset(chip); |
2976 | azx_clear_irq_pending(chip); | 2980 | azx_clear_irq_pending(chip); |
@@ -2983,11 +2987,31 @@ static int azx_runtime_resume(struct device *dev) | |||
2983 | { | 2987 | { |
2984 | struct snd_card *card = dev_get_drvdata(dev); | 2988 | struct snd_card *card = dev_get_drvdata(dev); |
2985 | struct azx *chip = card->private_data; | 2989 | struct azx *chip = card->private_data; |
2990 | struct hda_bus *bus; | ||
2991 | struct hda_codec *codec; | ||
2992 | int status; | ||
2986 | 2993 | ||
2987 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | 2994 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) |
2988 | hda_display_power(true); | 2995 | hda_display_power(true); |
2996 | |||
2997 | /* Read STATESTS before controller reset */ | ||
2998 | status = azx_readw(chip, STATESTS); | ||
2999 | |||
2989 | azx_init_pci(chip); | 3000 | azx_init_pci(chip); |
2990 | azx_init_chip(chip, 1); | 3001 | azx_init_chip(chip, 1); |
3002 | |||
3003 | bus = chip->bus; | ||
3004 | if (status && bus) { | ||
3005 | list_for_each_entry(codec, &bus->codec_list, list) | ||
3006 | if (status & (1 << codec->addr)) | ||
3007 | queue_delayed_work(codec->bus->workq, | ||
3008 | &codec->jackpoll_work, codec->jackpoll_interval); | ||
3009 | } | ||
3010 | |||
3011 | /* disable controller Wake Up event*/ | ||
3012 | azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & | ||
3013 | ~STATESTS_INT_MASK); | ||
3014 | |||
2991 | return 0; | 3015 | return 0; |
2992 | } | 3016 | } |
2993 | 3017 | ||