ALSA: hda: Copying sync power state helper to core
authorAbhijeet Kumar <abhijeet.kumar@intel.com>
Tue, 23 Jan 2018 17:30:51 +0000 (23:00 +0530)
committerTakashi Iwai <tiwai@suse.de>
Mon, 12 Feb 2018 12:59:39 +0000 (13:59 +0100)
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>
include/sound/hdaudio.h
sound/hda/hdac_device.c

index 68169e3749de164c140902413dc517e18c006c53..4c93ff5301bd21528ad194df0388553c86a9e634 100644 (file)
@@ -146,6 +146,8 @@ int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
                        int flags, unsigned int verb, unsigned int parm);
 bool snd_hdac_check_power_state(struct hdac_device *hdac,
                hda_nid_t nid, unsigned int target_state);
+unsigned int snd_hdac_sync_power_state(struct hdac_device *hdac,
+                     hda_nid_t nid, unsigned int target_state);
 /**
  * snd_hdac_read_parm - read a codec parameter
  * @codec: the codec object
index 06f845e293cb2dfcdaba0208aea03c69d3ad0ddc..7ba100bb1c3fcb22e0a958e7763a7ee683c45d2d 100644 (file)
@@ -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);