diff options
author | David Henningsson <david.henningsson@canonical.com> | 2013-04-15 06:50:02 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-04-15 10:03:53 -0400 |
commit | d240d1dcd5b42df4680e65f637e71bbc954e4d74 (patch) | |
tree | 2bc270a74008b124cf42ed5e4e5ff78c8778cd79 /sound/pci | |
parent | 73bdd597823e2231dc882577dbbaf8df92fe1775 (diff) |
ALSA: hda - Fix headset mic support for Asus X101CH
With this patch, a TRRS headset mic cannot be successfully detected
on the Asus X101CH, and we can also distinguish between headphone
and headset automatically.
Buglink: https://bugs.launchpad.net/bugs/1169138
Co-authored-by: Kailang <kailang@realtek.com>
Tested-by: Luis Henriques <luis.henriques@canonical.com>
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cd5f9e9f8838..cba9dc6dc38b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -2699,6 +2699,34 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec, | |||
2699 | spec->gen.automute_hook = alc269_quanta_automute; | 2699 | spec->gen.automute_hook = alc269_quanta_automute; |
2700 | } | 2700 | } |
2701 | 2701 | ||
2702 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, | ||
2703 | struct hda_jack_tbl *jack) | ||
2704 | { | ||
2705 | struct alc_spec *spec = codec->spec; | ||
2706 | int vref; | ||
2707 | msleep(200); | ||
2708 | snd_hda_gen_hp_automute(codec, jack); | ||
2709 | |||
2710 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; | ||
2711 | msleep(100); | ||
2712 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2713 | vref); | ||
2714 | msleep(500); | ||
2715 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2716 | vref); | ||
2717 | } | ||
2718 | |||
2719 | static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, | ||
2720 | const struct hda_fixup *fix, int action) | ||
2721 | { | ||
2722 | struct alc_spec *spec = codec->spec; | ||
2723 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2724 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | ||
2725 | spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; | ||
2726 | } | ||
2727 | } | ||
2728 | |||
2729 | |||
2702 | /* update mute-LED according to the speaker mute state via mic VREF pin */ | 2730 | /* update mute-LED according to the speaker mute state via mic VREF pin */ |
2703 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) | 2731 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) |
2704 | { | 2732 | { |
@@ -3156,6 +3184,9 @@ enum { | |||
3156 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, | 3184 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, |
3157 | ALC269_FIXUP_HEADSET_MODE, | 3185 | ALC269_FIXUP_HEADSET_MODE, |
3158 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, | 3186 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, |
3187 | ALC269_FIXUP_ASUS_X101_FUNC, | ||
3188 | ALC269_FIXUP_ASUS_X101_VERB, | ||
3189 | ALC269_FIXUP_ASUS_X101, | ||
3159 | ALC271_FIXUP_AMIC_MIC2, | 3190 | ALC271_FIXUP_AMIC_MIC2, |
3160 | ALC271_FIXUP_HP_GATE_MIC_JACK, | 3191 | ALC271_FIXUP_HP_GATE_MIC_JACK, |
3161 | ALC269_FIXUP_ACER_AC700, | 3192 | ALC269_FIXUP_ACER_AC700, |
@@ -3344,6 +3375,30 @@ static const struct hda_fixup alc269_fixups[] = { | |||
3344 | .type = HDA_FIXUP_FUNC, | 3375 | .type = HDA_FIXUP_FUNC, |
3345 | .v.func = alc_fixup_headset_mode_no_hp_mic, | 3376 | .v.func = alc_fixup_headset_mode_no_hp_mic, |
3346 | }, | 3377 | }, |
3378 | [ALC269_FIXUP_ASUS_X101_FUNC] = { | ||
3379 | .type = HDA_FIXUP_FUNC, | ||
3380 | .v.func = alc269_fixup_x101_headset_mic, | ||
3381 | }, | ||
3382 | [ALC269_FIXUP_ASUS_X101_VERB] = { | ||
3383 | .type = HDA_FIXUP_VERBS, | ||
3384 | .v.verbs = (const struct hda_verb[]) { | ||
3385 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
3386 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, | ||
3387 | {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, | ||
3388 | { } | ||
3389 | }, | ||
3390 | .chained = true, | ||
3391 | .chain_id = ALC269_FIXUP_ASUS_X101_FUNC | ||
3392 | }, | ||
3393 | [ALC269_FIXUP_ASUS_X101] = { | ||
3394 | .type = HDA_FIXUP_PINS, | ||
3395 | .v.pins = (const struct hda_pintbl[]) { | ||
3396 | { 0x18, 0x04a1182c }, /* Headset mic */ | ||
3397 | { } | ||
3398 | }, | ||
3399 | .chained = true, | ||
3400 | .chain_id = ALC269_FIXUP_ASUS_X101_VERB | ||
3401 | }, | ||
3347 | [ALC271_FIXUP_AMIC_MIC2] = { | 3402 | [ALC271_FIXUP_AMIC_MIC2] = { |
3348 | .type = HDA_FIXUP_PINS, | 3403 | .type = HDA_FIXUP_PINS, |
3349 | .v.pins = (const struct hda_pintbl[]) { | 3404 | .v.pins = (const struct hda_pintbl[]) { |
@@ -3412,6 +3467,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
3412 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), | 3467 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), |
3413 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 3468 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
3414 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 3469 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
3470 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), | ||
3415 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), | 3471 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), |
3416 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 3472 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
3417 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 3473 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |