Loading include/sound/hdaudio.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading sound/hda/hdac_device.c +35 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ */ #include <linux/init.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/slab.h> #include <linux/module.h> Loading Loading @@ -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); sound/pci/hda/hda_codec.c +1 −27 Original line number Diff line number Diff line Loading @@ -2702,32 +2702,6 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, } EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all); /* * wait until the state is reached, returns the current state */ static unsigned int hda_sync_power_state(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state) { unsigned long end_time = jiffies + msecs_to_jiffies(500); unsigned int state, actual_state; for (;;) { state = snd_hda_codec_read(codec, fg, 0, AC_VERB_GET_POWER_STATE, 0); if (state & AC_PWRST_ERROR) 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; } /** * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD * @codec: the HDA codec Loading Loading @@ -2790,7 +2764,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, state); snd_hda_codec_set_power_to_all(codec, fg, power_state); } state = hda_sync_power_state(codec, fg, power_state); state = snd_hda_sync_power_state(codec, fg, power_state); if (!(state & AC_PWRST_ERROR)) break; } Loading sound/pci/hda/hda_local.h +5 −1 Original line number Diff line number Diff line Loading @@ -622,7 +622,11 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid, { return snd_hdac_check_power_state(&codec->core, nid, target_state); } static inline bool snd_hda_sync_power_state(struct hda_codec *codec, hda_nid_t nid, unsigned int target_state) { return snd_hdac_sync_power_state(&codec->core, nid, target_state); } unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, hda_nid_t nid, unsigned int power_state); Loading Loading
include/sound/hdaudio.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
sound/hda/hdac_device.c +35 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ */ #include <linux/init.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/slab.h> #include <linux/module.h> Loading Loading @@ -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);
sound/pci/hda/hda_codec.c +1 −27 Original line number Diff line number Diff line Loading @@ -2702,32 +2702,6 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, } EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all); /* * wait until the state is reached, returns the current state */ static unsigned int hda_sync_power_state(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state) { unsigned long end_time = jiffies + msecs_to_jiffies(500); unsigned int state, actual_state; for (;;) { state = snd_hda_codec_read(codec, fg, 0, AC_VERB_GET_POWER_STATE, 0); if (state & AC_PWRST_ERROR) 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; } /** * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD * @codec: the HDA codec Loading Loading @@ -2790,7 +2764,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, state); snd_hda_codec_set_power_to_all(codec, fg, power_state); } state = hda_sync_power_state(codec, fg, power_state); state = snd_hda_sync_power_state(codec, fg, power_state); if (!(state & AC_PWRST_ERROR)) break; } Loading
sound/pci/hda/hda_local.h +5 −1 Original line number Diff line number Diff line Loading @@ -622,7 +622,11 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid, { return snd_hdac_check_power_state(&codec->core, nid, target_state); } static inline bool snd_hda_sync_power_state(struct hda_codec *codec, hda_nid_t nid, unsigned int target_state) { return snd_hdac_sync_power_state(&codec->core, nid, target_state); } unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, hda_nid_t nid, unsigned int power_state); Loading