Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+20 −13
Original line number Diff line number Diff line
@@ -1625,20 +1625,27 @@ 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 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.
				 * 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);
				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);
					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,
					    power_state);