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

Commit 196543d5 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Apply HP headphone fixups more generically

It turned out that many HP laptops suffer from the same problem as
fixed in commit [c932b98c: ALSA: hda - Apply pin fixup for HP
ProBook 6550b].  But, it's tiresome to list up all such PCI SSIDs, as
there are really lots of HP machines.

Instead, we do a bit more clever, try to check the supposedly dock and
built-in headphone pins, and apply the fixup when both seem valid.
This rule can be applied generically to all models using the same
quirk, so we'll fix all in a shot.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=107491


Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b9c2fa52
Loading
Loading
Loading
Loading
+29 −16
Original line number Original line Diff line number Diff line
@@ -3110,6 +3110,29 @@ static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec,
	spec->gpio_led = 0x08;
	spec->gpio_led = 0x08;
}
}


static bool is_hp_output(struct hda_codec *codec, hda_nid_t pin)
{
	unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);

	/* count line-out, too, as BIOS sets often so */
	return get_defcfg_connect(pin_cfg) != AC_JACK_PORT_NONE &&
		(get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
		 get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT);
}

static void fixup_hp_headphone(struct hda_codec *codec, hda_nid_t pin)
{
	unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin);

	/* It was changed in the BIOS to just satisfy MS DTM.
	 * Lets turn it back into slaved HP
	 */
	pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) |
		(AC_JACK_HP_OUT << AC_DEFCFG_DEVICE_SHIFT);
	pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | AC_DEFCFG_SEQUENCE))) |
		0x1f;
	snd_hda_codec_set_pincfg(codec, pin, pin_cfg);
}


static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
				   const struct hda_fixup *fix, int action)
				   const struct hda_fixup *fix, int action)
@@ -3119,22 +3142,12 @@ static void stac92hd71bxx_fixup_hp(struct hda_codec *codec,
	if (action != HDA_FIXUP_ACT_PRE_PROBE)
	if (action != HDA_FIXUP_ACT_PRE_PROBE)
		return;
		return;


	if (hp_blike_system(codec->core.subsystem_id)) {
	/* when both output A and F are assigned, these are supposedly
		unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
	 * dock and built-in headphones; fix both pin configs
		if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
			get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER  ||
			get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) {
			/* It was changed in the BIOS to just satisfy MS DTM.
			 * Lets turn it back into slaved HP
	 */
	 */
			pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE))
	if (is_hp_output(codec, 0x0a) && is_hp_output(codec, 0x0f)) {
					| (AC_JACK_HP_OUT <<
		fixup_hp_headphone(codec, 0x0a);
						AC_DEFCFG_DEVICE_SHIFT);
		fixup_hp_headphone(codec, 0x0f);
			pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC
							| AC_DEFCFG_SEQUENCE)))
								| 0x1f;
			snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg);
		}
	}
	}


	if (find_mute_led_cfg(codec, 1))
	if (find_mute_led_cfg(codec, 1))