aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt1
-rw-r--r--sound/pci/hda/patch_analog.c94
2 files changed, 95 insertions, 0 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index b02404395e52..42dd8f5855da 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -923,6 +923,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
923 desktop 3-stack desktop (default) 923 desktop 3-stack desktop (default)
924 laptop laptop with HP jack sensing 924 laptop laptop with HP jack sensing
925 mobile mobile devices with HP jack sensing 925 mobile mobile devices with HP jack sensing
926 thinkpad Lenovo Thinkpad X300
926 927
927 AD1884 928 AD1884
928 N/A 929 N/A
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 220784bb76a7..2befeebd909e 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3702,12 +3702,95 @@ static struct hda_verb ad1884a_laptop_verbs[] = {
3702}; 3702};
3703 3703
3704/* 3704/*
3705 * Thinkpad X300
3706 * 0x11 - HP
3707 * 0x12 - speaker
3708 * 0x14 - mic-in
3709 * 0x17 - built-in mic
3710 */
3711
3712static struct hda_verb ad1984a_thinkpad_verbs[] = {
3713 /* HP unmute */
3714 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3715 /* analog mix */
3716 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3717 /* turn on EAPD */
3718 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3719 /* unsolicited event for pin-sense */
3720 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
3721 /* internal mic - dmic */
3722 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3723 { } /* end */
3724};
3725
3726static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
3727 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3728 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3729 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3730 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3731 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3732 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3733 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3734 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3735 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
3736 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
3737 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3738 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3739 {
3740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3741 .name = "Capture Source",
3742 .info = ad198x_mux_enum_info,
3743 .get = ad198x_mux_enum_get,
3744 .put = ad198x_mux_enum_put,
3745 },
3746 { } /* end */
3747};
3748
3749static struct hda_input_mux ad1984a_thinkpad_capture_source = {
3750 .num_items = 3,
3751 .items = {
3752 { "Mic", 0x0 },
3753 { "Internal Mic", 0x5 },
3754 { "Mix", 0x3 },
3755 },
3756};
3757
3758/* mute internal speaker if HP is plugged */
3759static void ad1984a_thinkpad_automute(struct hda_codec *codec)
3760{
3761 unsigned int present;
3762
3763 present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0)
3764 & AC_PINSENSE_PRESENCE;
3765 snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
3766 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3767}
3768
3769/* unsolicited event for HP jack sensing */
3770static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
3771 unsigned int res)
3772{
3773 if ((res >> 26) != AD1884A_HP_EVENT)
3774 return;
3775 ad1984a_thinkpad_automute(codec);
3776}
3777
3778/* initialize jack-sensing, too */
3779static int ad1984a_thinkpad_init(struct hda_codec *codec)
3780{
3781 ad198x_init(codec);
3782 ad1984a_thinkpad_automute(codec);
3783 return 0;
3784}
3785
3786/*
3705 */ 3787 */
3706 3788
3707enum { 3789enum {
3708 AD1884A_DESKTOP, 3790 AD1884A_DESKTOP,
3709 AD1884A_LAPTOP, 3791 AD1884A_LAPTOP,
3710 AD1884A_MOBILE, 3792 AD1884A_MOBILE,
3793 AD1884A_THINKPAD,
3711 AD1884A_MODELS 3794 AD1884A_MODELS
3712}; 3795};
3713 3796
@@ -3715,10 +3798,12 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
3715 [AD1884A_DESKTOP] = "desktop", 3798 [AD1884A_DESKTOP] = "desktop",
3716 [AD1884A_LAPTOP] = "laptop", 3799 [AD1884A_LAPTOP] = "laptop",
3717 [AD1884A_MOBILE] = "mobile", 3800 [AD1884A_MOBILE] = "mobile",
3801 [AD1884A_THINKPAD] = "thinkpad",
3718}; 3802};
3719 3803
3720static struct snd_pci_quirk ad1884a_cfg_tbl[] = { 3804static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
3721 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), 3805 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
3806 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
3722 {} 3807 {}
3723}; 3808};
3724 3809
@@ -3773,6 +3858,15 @@ static int patch_ad1884a(struct hda_codec *codec)
3773 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; 3858 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
3774 codec->patch_ops.init = ad1884a_hp_init; 3859 codec->patch_ops.init = ad1884a_hp_init;
3775 break; 3860 break;
3861 case AD1884A_THINKPAD:
3862 spec->mixers[0] = ad1984a_thinkpad_mixers;
3863 spec->init_verbs[spec->num_init_verbs++] =
3864 ad1984a_thinkpad_verbs;
3865 spec->multiout.dig_out_nid = 0;
3866 spec->input_mux = &ad1984a_thinkpad_capture_source;
3867 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
3868 codec->patch_ops.init = ad1984a_thinkpad_init;
3869 break;
3776 } 3870 }
3777 3871
3778 return 0; 3872 return 0;