aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-11-09 08:46:35 -0500
committerTakashi Iwai <tiwai@suse.de>2015-11-20 11:03:33 -0500
commit196543d54574f50e3fd04df4e3048181e006a9da (patch)
tree3da8216a9e030e9b7ae02e54d2f3833a4a19aec3 /sound/pci/hda/patch_sigmatel.c
parentb9c2fa52135d49a931c56ed2bfc17d61f771b412 (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.c45
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
3113static 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
3123static 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
3114static void stac92hd71bxx_fixup_hp(struct hda_codec *codec, 3137static 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))