diff options
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
| -rw-r--r-- | sound/pci/hda/patch_analog.c | 61 |
1 files changed, 28 insertions, 33 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2d603f6aba63..455a0494f907 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
| @@ -156,15 +156,19 @@ static const char *ad_slave_sws[] = { | |||
| 156 | 156 | ||
| 157 | static void ad198x_free_kctls(struct hda_codec *codec); | 157 | static void ad198x_free_kctls(struct hda_codec *codec); |
| 158 | 158 | ||
| 159 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
| 159 | /* additional beep mixers; the actual parameters are overwritten at build */ | 160 | /* additional beep mixers; the actual parameters are overwritten at build */ |
| 160 | static struct snd_kcontrol_new ad_beep_mixer[] = { | 161 | static struct snd_kcontrol_new ad_beep_mixer[] = { |
| 161 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), | 162 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), |
| 162 | HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_OUTPUT), | 163 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), |
| 163 | { } /* end */ | 164 | { } /* end */ |
| 164 | }; | 165 | }; |
| 165 | 166 | ||
| 166 | #define set_beep_amp(spec, nid, idx, dir) \ | 167 | #define set_beep_amp(spec, nid, idx, dir) \ |
| 167 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ | 168 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ |
| 169 | #else | ||
| 170 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | ||
| 171 | #endif | ||
| 168 | 172 | ||
| 169 | static int ad198x_build_controls(struct hda_codec *codec) | 173 | static int ad198x_build_controls(struct hda_codec *codec) |
| 170 | { | 174 | { |
| @@ -194,6 +198,7 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
| 194 | } | 198 | } |
| 195 | 199 | ||
| 196 | /* create beep controls if needed */ | 200 | /* create beep controls if needed */ |
| 201 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
| 197 | if (spec->beep_amp) { | 202 | if (spec->beep_amp) { |
| 198 | struct snd_kcontrol_new *knew; | 203 | struct snd_kcontrol_new *knew; |
| 199 | for (knew = ad_beep_mixer; knew->name; knew++) { | 204 | for (knew = ad_beep_mixer; knew->name; knew++) { |
| @@ -202,11 +207,14 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
| 202 | if (!kctl) | 207 | if (!kctl) |
| 203 | return -ENOMEM; | 208 | return -ENOMEM; |
| 204 | kctl->private_value = spec->beep_amp; | 209 | kctl->private_value = spec->beep_amp; |
| 205 | err = snd_hda_ctl_add(codec, kctl); | 210 | err = snd_hda_ctl_add(codec, |
| 211 | get_amp_nid_(spec->beep_amp), | ||
| 212 | kctl); | ||
| 206 | if (err < 0) | 213 | if (err < 0) |
| 207 | return err; | 214 | return err; |
| 208 | } | 215 | } |
| 209 | } | 216 | } |
| 217 | #endif | ||
| 210 | 218 | ||
| 211 | /* if we have no master control, let's create it */ | 219 | /* if we have no master control, let's create it */ |
| 212 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | 220 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { |
| @@ -712,10 +720,10 @@ static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { | |||
| 712 | static void ad1986a_automic(struct hda_codec *codec) | 720 | static void ad1986a_automic(struct hda_codec *codec) |
| 713 | { | 721 | { |
| 714 | unsigned int present; | 722 | unsigned int present; |
| 715 | present = snd_hda_codec_read(codec, 0x1f, 0, AC_VERB_GET_PIN_SENSE, 0); | 723 | present = snd_hda_jack_detect(codec, 0x1f); |
| 716 | /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */ | 724 | /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */ |
| 717 | snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL, | 725 | snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL, |
| 718 | (present & AC_PINSENSE_PRESENCE) ? 0 : 2); | 726 | present ? 0 : 2); |
| 719 | } | 727 | } |
| 720 | 728 | ||
| 721 | #define AD1986A_MIC_EVENT 0x36 | 729 | #define AD1986A_MIC_EVENT 0x36 |
| @@ -754,10 +762,8 @@ static void ad1986a_update_hp(struct hda_codec *codec) | |||
| 754 | static void ad1986a_hp_automute(struct hda_codec *codec) | 762 | static void ad1986a_hp_automute(struct hda_codec *codec) |
| 755 | { | 763 | { |
| 756 | struct ad198x_spec *spec = codec->spec; | 764 | struct ad198x_spec *spec = codec->spec; |
| 757 | unsigned int present; | ||
| 758 | 765 | ||
| 759 | present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); | 766 | spec->jack_present = snd_hda_jack_detect(codec, 0x1a); |
| 760 | spec->jack_present = !!(present & 0x80000000); | ||
| 761 | if (spec->inv_jack_detect) | 767 | if (spec->inv_jack_detect) |
| 762 | spec->jack_present = !spec->jack_present; | 768 | spec->jack_present = !spec->jack_present; |
| 763 | ad1986a_update_hp(codec); | 769 | ad1986a_update_hp(codec); |
| @@ -1547,8 +1553,7 @@ static void ad1981_hp_automute(struct hda_codec *codec) | |||
| 1547 | { | 1553 | { |
| 1548 | unsigned int present; | 1554 | unsigned int present; |
| 1549 | 1555 | ||
| 1550 | present = snd_hda_codec_read(codec, 0x06, 0, | 1556 | present = snd_hda_jack_detect(codec, 0x06); |
| 1551 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
| 1552 | snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0, | 1557 | snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0, |
| 1553 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 1558 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
| 1554 | } | 1559 | } |
| @@ -1568,8 +1573,7 @@ static void ad1981_hp_automic(struct hda_codec *codec) | |||
| 1568 | }; | 1573 | }; |
| 1569 | unsigned int present; | 1574 | unsigned int present; |
| 1570 | 1575 | ||
| 1571 | present = snd_hda_codec_read(codec, 0x08, 0, | 1576 | present = snd_hda_jack_detect(codec, 0x08); |
| 1572 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
| 1573 | if (present) | 1577 | if (present) |
| 1574 | snd_hda_sequence_write(codec, mic_jack_on); | 1578 | snd_hda_sequence_write(codec, mic_jack_on); |
| 1575 | else | 1579 | else |
| @@ -2524,7 +2528,7 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res) | |||
| 2524 | { | 2528 | { |
| 2525 | if ((res >> 26) != AD1988_HP_EVENT) | 2529 | if ((res >> 26) != AD1988_HP_EVENT) |
| 2526 | return; | 2530 | return; |
| 2527 | if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31)) | 2531 | if (snd_hda_jack_detect(codec, 0x11)) |
| 2528 | snd_hda_sequence_write(codec, ad1988_laptop_hp_on); | 2532 | snd_hda_sequence_write(codec, ad1988_laptop_hp_on); |
| 2529 | else | 2533 | else |
| 2530 | snd_hda_sequence_write(codec, ad1988_laptop_hp_off); | 2534 | snd_hda_sequence_write(codec, ad1988_laptop_hp_off); |
| @@ -2569,6 +2573,8 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name, | |||
| 2569 | knew->name = kstrdup(name, GFP_KERNEL); | 2573 | knew->name = kstrdup(name, GFP_KERNEL); |
| 2570 | if (! knew->name) | 2574 | if (! knew->name) |
| 2571 | return -ENOMEM; | 2575 | return -ENOMEM; |
| 2576 | if (get_amp_nid_(val)) | ||
| 2577 | knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); | ||
| 2572 | knew->private_value = val; | 2578 | knew->private_value = val; |
| 2573 | return 0; | 2579 | return 0; |
| 2574 | } | 2580 | } |
| @@ -3768,8 +3774,7 @@ static void ad1884a_hp_automute(struct hda_codec *codec) | |||
| 3768 | { | 3774 | { |
| 3769 | unsigned int present; | 3775 | unsigned int present; |
| 3770 | 3776 | ||
| 3771 | present = snd_hda_codec_read(codec, 0x11, 0, | 3777 | present = snd_hda_jack_detect(codec, 0x11); |
| 3772 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
| 3773 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | 3778 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, |
| 3774 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 3779 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
| 3775 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, | 3780 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, |
| @@ -3781,8 +3786,7 @@ static void ad1884a_hp_automic(struct hda_codec *codec) | |||
| 3781 | { | 3786 | { |
| 3782 | unsigned int present; | 3787 | unsigned int present; |
| 3783 | 3788 | ||
| 3784 | present = snd_hda_codec_read(codec, 0x14, 0, | 3789 | present = snd_hda_jack_detect(codec, 0x14); |
| 3785 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
| 3786 | snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, | 3790 | snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, |
| 3787 | present ? 0 : 1); | 3791 | present ? 0 : 1); |
| 3788 | } | 3792 | } |
| @@ -3817,13 +3821,9 @@ static void ad1884a_laptop_automute(struct hda_codec *codec) | |||
| 3817 | { | 3821 | { |
| 3818 | unsigned int present; | 3822 | unsigned int present; |
| 3819 | 3823 | ||
| 3820 | present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0); | 3824 | present = snd_hda_jack_detect(codec, 0x11); |
| 3821 | present &= AC_PINSENSE_PRESENCE; | 3825 | if (!present) |
| 3822 | if (!present) { | 3826 | present = snd_hda_jack_detect(codec, 0x12); |
| 3823 | present = snd_hda_codec_read(codec, 0x12, 0, | ||
| 3824 | AC_VERB_GET_PIN_SENSE, 0); | ||
| 3825 | present &= AC_PINSENSE_PRESENCE; | ||
| 3826 | } | ||
| 3827 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | 3827 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, |
| 3828 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 3828 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
| 3829 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, | 3829 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, |
| @@ -3835,11 +3835,9 @@ static void ad1884a_laptop_automic(struct hda_codec *codec) | |||
| 3835 | { | 3835 | { |
| 3836 | unsigned int idx; | 3836 | unsigned int idx; |
| 3837 | 3837 | ||
| 3838 | if (snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & | 3838 | if (snd_hda_jack_detect(codec, 0x14)) |
| 3839 | AC_PINSENSE_PRESENCE) | ||
| 3840 | idx = 0; | 3839 | idx = 0; |
| 3841 | else if (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0) & | 3840 | else if (snd_hda_jack_detect(codec, 0x1c)) |
| 3842 | AC_PINSENSE_PRESENCE) | ||
| 3843 | idx = 4; | 3841 | idx = 4; |
| 3844 | else | 3842 | else |
| 3845 | idx = 1; | 3843 | idx = 1; |
| @@ -4008,8 +4006,7 @@ static void ad1984a_thinkpad_automute(struct hda_codec *codec) | |||
| 4008 | { | 4006 | { |
| 4009 | unsigned int present; | 4007 | unsigned int present; |
| 4010 | 4008 | ||
| 4011 | present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) | 4009 | present = snd_hda_jack_detect(codec, 0x11); |
| 4012 | & AC_PINSENSE_PRESENCE; | ||
| 4013 | snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0, | 4010 | snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0, |
| 4014 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | 4011 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); |
| 4015 | } | 4012 | } |
| @@ -4117,14 +4114,12 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { | |||
| 4117 | /* switch to external mic if plugged */ | 4114 | /* switch to external mic if plugged */ |
| 4118 | static void ad1984a_touchsmart_automic(struct hda_codec *codec) | 4115 | static void ad1984a_touchsmart_automic(struct hda_codec *codec) |
| 4119 | { | 4116 | { |
| 4120 | if (snd_hda_codec_read(codec, 0x1c, 0, | 4117 | if (snd_hda_jack_detect(codec, 0x1c)) |
| 4121 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000) { | ||
| 4122 | snd_hda_codec_write(codec, 0x0c, 0, | 4118 | snd_hda_codec_write(codec, 0x0c, 0, |
| 4123 | AC_VERB_SET_CONNECT_SEL, 0x4); | 4119 | AC_VERB_SET_CONNECT_SEL, 0x4); |
| 4124 | } else { | 4120 | else |
| 4125 | snd_hda_codec_write(codec, 0x0c, 0, | 4121 | snd_hda_codec_write(codec, 0x0c, 0, |
| 4126 | AC_VERB_SET_CONNECT_SEL, 0x5); | 4122 | AC_VERB_SET_CONNECT_SEL, 0x5); |
| 4127 | } | ||
| 4128 | } | 4123 | } |
| 4129 | 4124 | ||
| 4130 | 4125 | ||
