Commit 7eba5c9d authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela

[ALSA] hda-codec - Check PINCAP only for PIN widgets

The recent addition of checking PINCAP for EAPD seems to break some
systems due to unexpected response from the codec chip.  We shouldn't
issue GET_PINCAP verb to non-PIN widgets.  Now checks the widget type
before checking EAPD bit.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 60fac85f
......@@ -1625,19 +1625,26 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) {
if (get_wcaps(codec, nid) & AC_WCAP_POWER) {
unsigned int pincap;
/*
* don't power down the widget if it controls eapd
* and EAPD_BTLENABLE is set.
*/
pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
if (pincap & AC_PINCAP_EAPD) {
int eapd = snd_hda_codec_read(codec, nid,
0, AC_VERB_GET_EAPD_BTLENABLE, 0);
eapd &= 0x02;
if (power_state == AC_PWRST_D3 && eapd)
continue;
unsigned int wcaps = get_wcaps(codec, nid);
if (wcaps & AC_WCAP_POWER) {
unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >>
AC_WCAP_TYPE_SHIFT;
if (wid_type == AC_WID_PIN) {
unsigned int pincap;
/*
* don't power down the widget if it controls
* eapd and EAPD_BTLENABLE is set.
*/
pincap = snd_hda_param_read(codec, nid,
AC_PAR_PIN_CAP);
if (pincap & AC_PINCAP_EAPD) {
int eapd = snd_hda_codec_read(codec,
nid, 0,
AC_VERB_GET_EAPD_BTLENABLE, 0);
eapd &= 0x02;
if (power_state == AC_PWRST_D3 && eapd)
continue;
}
}
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_POWER_STATE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment