diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-11-09 08:46:35 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-11-20 11:03:33 -0500 |
commit | 196543d54574f50e3fd04df4e3048181e006a9da (patch) | |
tree | 3da8216a9e030e9b7ae02e54d2f3833a4a19aec3 /sound/pci/hda/patch_sigmatel.c | |
parent | b9c2fa52135d49a931c56ed2bfc17d61f771b412 (diff) |
ALSA: hda - Apply HP headphone fixups more generically
It turned out that many HP laptops suffer from the same problem as
fixed in commit [c932b98c1e47: 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: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 826122d8acee..2c7c5eb8b1e9 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -3110,6 +3110,29 @@ static void stac92hd71bxx_fixup_hp_hdx(struct hda_codec *codec, | |||
3110 | spec->gpio_led = 0x08; | 3110 | spec->gpio_led = 0x08; |
3111 | } | 3111 | } |
3112 | 3112 | ||
3113 | static bool is_hp_output(struct hda_codec *codec, hda_nid_t pin) | ||
3114 | { | ||
3115 | unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin); | ||
3116 | |||
3117 | /* count line-out, too, as BIOS sets often so */ | ||
3118 | return get_defcfg_connect(pin_cfg) != AC_JACK_PORT_NONE && | ||
3119 | (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || | ||
3120 | get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT); | ||
3121 | } | ||
3122 | |||
3123 | static void fixup_hp_headphone(struct hda_codec *codec, hda_nid_t pin) | ||
3124 | { | ||
3125 | unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, pin); | ||
3126 | |||
3127 | /* It was changed in the BIOS to just satisfy MS DTM. | ||
3128 | * Lets turn it back into slaved HP | ||
3129 | */ | ||
3130 | pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) | | ||
3131 | (AC_JACK_HP_OUT << AC_DEFCFG_DEVICE_SHIFT); | ||
3132 | pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | AC_DEFCFG_SEQUENCE))) | | ||
3133 | 0x1f; | ||
3134 | snd_hda_codec_set_pincfg(codec, pin, pin_cfg); | ||
3135 | } | ||
3113 | 3136 | ||
3114 | static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, | 3137 | static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, |
3115 | const struct hda_fixup *fix, int action) | 3138 | const struct hda_fixup *fix, int action) |
@@ -3119,22 +3142,12 @@ static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, | |||
3119 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | 3142 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
3120 | return; | 3143 | return; |
3121 | 3144 | ||
3122 | if (hp_blike_system(codec->core.subsystem_id)) { | 3145 | /* when both output A and F are assigned, these are supposedly |
3123 | unsigned int pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); | 3146 | * dock and built-in headphones; fix both pin configs |
3124 | if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || | 3147 | */ |
3125 | get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || | 3148 | if (is_hp_output(codec, 0x0a) && is_hp_output(codec, 0x0f)) { |
3126 | get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) { | 3149 | fixup_hp_headphone(codec, 0x0a); |
3127 | /* It was changed in the BIOS to just satisfy MS DTM. | 3150 | fixup_hp_headphone(codec, 0x0f); |
3128 | * Lets turn it back into slaved HP | ||
3129 | */ | ||
3130 | pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) | ||
3131 | | (AC_JACK_HP_OUT << | ||
3132 | AC_DEFCFG_DEVICE_SHIFT); | ||
3133 | pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC | ||
3134 | | AC_DEFCFG_SEQUENCE))) | ||
3135 | | 0x1f; | ||
3136 | snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg); | ||
3137 | } | ||
3138 | } | 3151 | } |
3139 | 3152 | ||
3140 | if (find_mute_led_cfg(codec, 1)) | 3153 | if (find_mute_led_cfg(codec, 1)) |