diff options
author | Mengdong Lin <mengdong.lin@intel.com> | 2015-04-29 11:43:20 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-04-29 12:27:52 +0200 |
commit | a5e7e07c264bb76d0b7c782766989c491833de05 (patch) | |
tree | 35cd2d573347f42a479f65079d17cb9562fd3f4d /sound | |
parent | ALSA: hda - implement a refcount for i915 power well switch (diff) | |
download | linux-a5e7e07c264bb76d0b7c782766989c491833de05.tar.xz linux-a5e7e07c264bb76d0b7c782766989c491833de05.zip |
ALSA: hda - allow a codec to control the link power
A flag "link_power_control" is added to indicate whether a codec needs to
control the link power. And a new bus ops link_power() is defined for the
codec to request to enable/disable the link power.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/hda/hdac_device.c | 15 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 4 |
2 files changed, 19 insertions, 0 deletions
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index 55c7d086b9dd..cdee7103f649 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -552,6 +552,21 @@ void snd_hdac_power_down_pm(struct hdac_device *codec) EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm); #endif +/* + * Enable/disable the link power for a codec. + */ +int snd_hdac_link_power(struct hdac_device *codec, bool enable) +{ + if (!codec->link_power_control) + return 0; + + if (codec->bus->ops->link_power) + return codec->bus->ops->link_power(codec->bus, enable); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_hdac_link_power); + /* codec vendor labels */ struct hda_vendor_id { unsigned int id; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 2d8883fbde2b..a85242f7f973 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -857,6 +857,7 @@ void snd_hda_codec_register(struct hda_codec *codec) return; if (device_is_registered(hda_codec_dev(codec))) { snd_hda_register_beep_device(codec); + snd_hdac_link_power(&codec->core, true); pm_runtime_enable(hda_codec_dev(codec)); /* it was powered up in snd_hda_codec_new(), now all done */ snd_hda_power_down(codec); @@ -883,6 +884,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device) struct hda_codec *codec = device->device_data; codec->in_freeing = 1; + snd_hdac_link_power(&codec->core, false); snd_hdac_device_unregister(&codec->core); put_device(hda_codec_dev(codec)); return 0; @@ -3102,6 +3104,7 @@ static int hda_codec_runtime_suspend(struct device *dev) if (codec_has_clkstop(codec) && codec_has_epss(codec) && (state & AC_PWRST_CLK_STOP_OK)) snd_hdac_codec_link_down(&codec->core); + snd_hdac_link_power(&codec->core, false); return 0; } @@ -3109,6 +3112,7 @@ static int hda_codec_runtime_resume(struct device *dev) { struct hda_codec *codec = dev_to_hda_codec(dev); + snd_hdac_link_power(&codec->core, true); snd_hdac_codec_link_up(&codec->core); hda_call_codec_resume(codec); pm_runtime_mark_last_busy(dev); |