summaryrefslogtreecommitdiffstats
path: root/sound/hda
diff options
context:
space:
mode:
authorAbhijeet Kumar <abhijeet.kumar@intel.com>2018-01-23 23:00:51 +0530
committerTakashi Iwai <tiwai@suse.de>2018-02-12 13:59:39 +0100
commit09787492537462e3c7b8f67b30ff9704062f97cc (patch)
tree0b728a4c05c493cf70543545383a18060eeb48c8 /sound/hda
parent7928b2cbe55b2a410a0f5c1f154610059c57b1b2 (diff)
downloadlinux-09787492537462e3c7b8f67b30ff9704062f97cc.tar.gz
linux-09787492537462e3c7b8f67b30ff9704062f97cc.tar.bz2
linux-09787492537462e3c7b8f67b30ff9704062f97cc.zip
ALSA: hda: Copying sync power state helper to core
The current sync_power_state is local to hda code, moving it core so that other users apart from hda legacy can use it. The helper function ensures the actual state reaches the target state. Signed-off-by: Abhijeet Kumar <abhijeet.kumar@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/hda')
-rw-r--r--sound/hda/hdac_device.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index 06f845e293cb..7ba100bb1c3f 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -3,6 +3,7 @@
*/
#include <linux/init.h>
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/module.h>
@@ -1064,3 +1065,37 @@ bool snd_hdac_check_power_state(struct hdac_device *hdac,
return (state == target_state);
}
EXPORT_SYMBOL_GPL(snd_hdac_check_power_state);
+/**
+ * snd_hdac_sync_power_state - wait until actual power state matches
+ * with the target state
+ *
+ * @hdac: the HDAC device
+ * @nid: NID to send the command
+ * @target_state: target state to check for
+ *
+ * Return power state or PS_ERROR if codec rejects GET verb.
+ */
+unsigned int snd_hdac_sync_power_state(struct hdac_device *codec,
+ hda_nid_t nid, unsigned int power_state)
+{
+ unsigned long end_time = jiffies + msecs_to_jiffies(500);
+ unsigned int state, actual_state, count;
+
+ for (count = 0; count < 500; count++) {
+ state = snd_hdac_codec_read(codec, nid, 0,
+ AC_VERB_GET_POWER_STATE, 0);
+ if (state & AC_PWRST_ERROR) {
+ msleep(20);
+ break;
+ }
+ actual_state = (state >> 4) & 0x0f;
+ if (actual_state == power_state)
+ break;
+ if (time_after_eq(jiffies, end_time))
+ break;
+ /* wait until the codec reachs to the target state */
+ msleep(1);
+ }
+ return state;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_sync_power_state);