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 | ||