aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-09-06 09:45:38 -0400
committerTakashi Iwai <tiwai@suse.de>2013-09-06 09:54:42 -0400
commit7bba2157c5d3ee7f076adfdfa96eec274801da8f (patch)
tree34b7814425046fdbe77e4175243933226deb6c19 /sound
parentb054087dbacee30a9dddaef2c9a96312146be04e (diff)
ALSA: hda - Add dock speaker support for ASUS TX300
ASUS TX300 has a built-in speaker in the tablet part and in the dock part, and the tablet speaker is supposed to be unused while the machine is docked. The current HD-audio driver, however, doesn't support the dock speaker, partly because BIOS doesn't set up the pin for the corresponding output. But, not only the missing pin config, also the missing unsol event handling is another issue. Otherwise the automatic switching via dock/undock won't work. Through debugging sessions, we found out that the dock speaker pin is NID 0x1b, and it generates an unsol event at docking/undocking, the docking state can be inquired via the normal pin detection verb. Also, it's turned out that GPIO 2 is needed as an amp. So, all materials are ready to cook. This patch provides the basic dock speaker support with TX300: - The dock speaker is turned on/off via "Dock Speaker" mixer mute. - The dock speaker is automatically muted when docked. This is independently from the mixer mute switch, just like the headphone auto-mute function. The implementation is a bit tricky. Since we want to handle it as a secondary speaker, we set it up a pin as a speaker with a jack detection. Then, the fixup function registers the own unsol callback for this pin because the standard automute can't handle the thing like a "speaker jack". In the own automute hook, we apply the mute of the tablet speaker in addition by checking the dock state. Also, the speaker control names are slightly shuffled because the generic parser doesn't give good names but blindly assumes a bass speaker as a secondary speaker. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=59791 Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_realtek.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4a909170b59e..d38d6a04eb67 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -3443,6 +3443,56 @@ static void alc283_fixup_chromebook(struct hda_codec *codec,
3443 } 3443 }
3444} 3444}
3445 3445
3446/* mute tablet speaker pin (0x14) via dock plugging in addition */
3447static void asus_tx300_automute(struct hda_codec *codec)
3448{
3449 struct alc_spec *spec = codec->spec;
3450 snd_hda_gen_update_outputs(codec);
3451 if (snd_hda_jack_detect(codec, 0x1b))
3452 spec->gen.mute_bits |= (1ULL << 0x14);
3453}
3454
3455static void alc282_fixup_asus_tx300(struct hda_codec *codec,
3456 const struct hda_fixup *fix, int action)
3457{
3458 struct alc_spec *spec = codec->spec;
3459 /* TX300 needs to set up GPIO2 for the speaker amp */
3460 static const struct hda_verb gpio2_verbs[] = {
3461 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3462 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3463 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
3464 {}
3465 };
3466 static const struct hda_pintbl dock_pins[] = {
3467 { 0x1b, 0x21114000 }, /* dock speaker pin */
3468 {}
3469 };
3470 struct snd_kcontrol *kctl;
3471
3472 switch (action) {
3473 case HDA_FIXUP_ACT_PRE_PROBE:
3474 snd_hda_add_verbs(codec, gpio2_verbs);
3475 snd_hda_apply_pincfgs(codec, dock_pins);
3476 spec->gen.auto_mute_via_amp = 1;
3477 spec->gen.automute_hook = asus_tx300_automute;
3478 snd_hda_jack_detect_enable_callback(codec, 0x1b,
3479 HDA_GEN_HP_EVENT,
3480 snd_hda_gen_hp_automute);
3481 break;
3482 case HDA_FIXUP_ACT_BUILD:
3483 /* this is a bit tricky; give more sane names for the main
3484 * (tablet) speaker and the dock speaker, respectively
3485 */
3486 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
3487 if (kctl)
3488 strcpy(kctl->id.name, "Dock Speaker Playback Switch");
3489 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
3490 if (kctl)
3491 strcpy(kctl->id.name, "Speaker Playback Switch");
3492 break;
3493 }
3494}
3495
3446enum { 3496enum {
3447 ALC269_FIXUP_SONY_VAIO, 3497 ALC269_FIXUP_SONY_VAIO,
3448 ALC275_FIXUP_SONY_VAIO_GPIO2, 3498 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -3480,6 +3530,7 @@ enum {
3480 ALC269_FIXUP_LIMIT_INT_MIC_BOOST, 3530 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
3481 ALC269VB_FIXUP_ORDISSIMO_EVE2, 3531 ALC269VB_FIXUP_ORDISSIMO_EVE2,
3482 ALC283_FIXUP_CHROME_BOOK, 3532 ALC283_FIXUP_CHROME_BOOK,
3533 ALC282_FIXUP_ASUS_TX300,
3483}; 3534};
3484 3535
3485static const struct hda_fixup alc269_fixups[] = { 3536static const struct hda_fixup alc269_fixups[] = {
@@ -3735,6 +3786,10 @@ static const struct hda_fixup alc269_fixups[] = {
3735 .type = HDA_FIXUP_FUNC, 3786 .type = HDA_FIXUP_FUNC,
3736 .v.func = alc283_fixup_chromebook, 3787 .v.func = alc283_fixup_chromebook,
3737 }, 3788 },
3789 [ALC282_FIXUP_ASUS_TX300] = {
3790 .type = HDA_FIXUP_FUNC,
3791 .v.func = alc282_fixup_asus_tx300,
3792 },
3738}; 3793};
3739 3794
3740static const struct snd_pci_quirk alc269_fixup_tbl[] = { 3795static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -3784,6 +3839,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3784 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3839 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
3785 SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK), 3840 SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK),
3786 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), 3841 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
3842 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
3787 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3843 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3788 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3844 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3789 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), 3845 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),