diff options
| -rw-r--r-- | sound/pci/hda/patch_analog.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index ff1b922c610b..a99e86d74278 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
| @@ -3644,33 +3644,17 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { | |||
| 3644 | { } /* end */ | 3644 | { } /* end */ |
| 3645 | }; | 3645 | }; |
| 3646 | 3646 | ||
| 3647 | static struct hda_input_mux ad1884a_mobile_capture_source = { | ||
| 3648 | .num_items = 2, | ||
| 3649 | .items = { | ||
| 3650 | { "Mic", 0x1 }, /* port-C */ | ||
| 3651 | { "Mix", 0x3 }, | ||
| 3652 | }, | ||
| 3653 | }; | ||
| 3654 | |||
| 3655 | static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { | 3647 | static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { |
| 3656 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 3648 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
| 3657 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), | 3649 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), |
| 3658 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), | 3650 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), |
| 3659 | HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), | 3651 | HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), |
| 3660 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | ||
| 3661 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | ||
| 3662 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), | 3652 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), |
| 3663 | HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), | 3653 | HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), |
| 3664 | HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), | 3654 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), |
| 3655 | HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT), | ||
| 3665 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | 3656 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), |
| 3666 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | 3657 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), |
| 3667 | { | ||
| 3668 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 3669 | .name = "Capture Source", | ||
| 3670 | .info = ad198x_mux_enum_info, | ||
| 3671 | .get = ad198x_mux_enum_get, | ||
| 3672 | .put = ad198x_mux_enum_put, | ||
| 3673 | }, | ||
| 3674 | { } /* end */ | 3658 | { } /* end */ |
| 3675 | }; | 3659 | }; |
| 3676 | 3660 | ||
| @@ -3687,14 +3671,31 @@ static void ad1884a_hp_automute(struct hda_codec *codec) | |||
| 3687 | present ? 0x00 : 0x02); | 3671 | present ? 0x00 : 0x02); |
| 3688 | } | 3672 | } |
| 3689 | 3673 | ||
| 3674 | /* switch to external mic if plugged */ | ||
| 3675 | static void ad1884a_hp_automic(struct hda_codec *codec) | ||
| 3676 | { | ||
| 3677 | unsigned int present; | ||
| 3678 | |||
| 3679 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
| 3680 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
| 3681 | snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, | ||
| 3682 | present ? 0 : 1); | ||
| 3683 | } | ||
| 3684 | |||
| 3690 | #define AD1884A_HP_EVENT 0x37 | 3685 | #define AD1884A_HP_EVENT 0x37 |
| 3686 | #define AD1884A_MIC_EVENT 0x36 | ||
| 3691 | 3687 | ||
| 3692 | /* unsolicited event for HP jack sensing */ | 3688 | /* unsolicited event for HP jack sensing */ |
| 3693 | static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res) | 3689 | static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res) |
| 3694 | { | 3690 | { |
| 3695 | if ((res >> 26) != AD1884A_HP_EVENT) | 3691 | switch (res >> 26) { |
| 3696 | return; | 3692 | case AD1884A_HP_EVENT: |
| 3697 | ad1884a_hp_automute(codec); | 3693 | ad1884a_hp_automute(codec); |
| 3694 | break; | ||
| 3695 | case AD1884A_MIC_EVENT: | ||
| 3696 | ad1884a_hp_automic(codec); | ||
| 3697 | break; | ||
| 3698 | } | ||
| 3698 | } | 3699 | } |
| 3699 | 3700 | ||
| 3700 | /* initialize jack-sensing, too */ | 3701 | /* initialize jack-sensing, too */ |
| @@ -3702,6 +3703,7 @@ static int ad1884a_hp_init(struct hda_codec *codec) | |||
| 3702 | { | 3703 | { |
| 3703 | ad198x_init(codec); | 3704 | ad198x_init(codec); |
| 3704 | ad1884a_hp_automute(codec); | 3705 | ad1884a_hp_automute(codec); |
| 3706 | ad1884a_hp_automic(codec); | ||
| 3705 | return 0; | 3707 | return 0; |
| 3706 | } | 3708 | } |
| 3707 | 3709 | ||
| @@ -3715,10 +3717,15 @@ static struct hda_verb ad1884a_laptop_verbs[] = { | |||
| 3715 | /* Port-F pin */ | 3717 | /* Port-F pin */ |
| 3716 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 3718 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
| 3717 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 3719 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
| 3720 | /* Port-C pin - internal mic-in */ | ||
| 3721 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 3722 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ | ||
| 3723 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ | ||
| 3718 | /* analog mix */ | 3724 | /* analog mix */ |
| 3719 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 3725 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, |
| 3720 | /* unsolicited event for pin-sense */ | 3726 | /* unsolicited event for pin-sense */ |
| 3721 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, | 3727 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, |
| 3728 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, | ||
| 3722 | { } /* end */ | 3729 | { } /* end */ |
| 3723 | }; | 3730 | }; |
| 3724 | 3731 | ||
| @@ -3878,7 +3885,6 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
| 3878 | spec->mixers[0] = ad1884a_mobile_mixers; | 3885 | spec->mixers[0] = ad1884a_mobile_mixers; |
| 3879 | spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; | 3886 | spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; |
| 3880 | spec->multiout.dig_out_nid = 0; | 3887 | spec->multiout.dig_out_nid = 0; |
| 3881 | spec->input_mux = &ad1884a_mobile_capture_source; | ||
| 3882 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; | 3888 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; |
| 3883 | codec->patch_ops.init = ad1884a_hp_init; | 3889 | codec->patch_ops.init = ad1884a_hp_init; |
| 3884 | break; | 3890 | break; |
