diff options
author | Kailang Yang <kailang@realtek.com> | 2008-10-15 05:12:35 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-10-15 05:12:35 -0400 |
commit | 7fb0d78fb155845812e98ed10605d8f01963ce05 (patch) | |
tree | 5e7823a08c404395ca81a050ae025b2186179cc7 | |
parent | d21995e3e3acb78e8c48c6631432a3bff191bc46 (diff) |
ALSA: hda - Add auto mic switch in realtek auto-probe mode
Add the automatic mic switch via jack sensing in auto-probe mode
for Realtek codecs.
Signed-off-by: Kailang Yang <kailang@realtek.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 65 |
1 files changed, 50 insertions, 15 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0b6e682c46d0..80c3f6420072 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -822,6 +822,27 @@ static void alc_sku_automute(struct hda_codec *codec) | |||
822 | spec->jack_present ? 0 : PIN_OUT); | 822 | spec->jack_present ? 0 : PIN_OUT); |
823 | } | 823 | } |
824 | 824 | ||
825 | static void alc_mic_automute(struct hda_codec *codec) | ||
826 | { | ||
827 | struct alc_spec *spec = codec->spec; | ||
828 | unsigned int present; | ||
829 | unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; | ||
830 | unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; | ||
831 | unsigned int mix_nid = spec->capsrc_nids[0]; | ||
832 | unsigned int capsrc_idx_mic, capsrc_idx_fmic; | ||
833 | |||
834 | capsrc_idx_mic = mic_nid - 0x18; | ||
835 | capsrc_idx_fmic = fmic_nid - 0x18; | ||
836 | present = snd_hda_codec_read(codec, mic_nid, 0, | ||
837 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
838 | snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
839 | 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80)); | ||
840 | snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
841 | 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0)); | ||
842 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic, | ||
843 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
844 | } | ||
845 | |||
825 | /* unsolicited event for HP jack sensing */ | 846 | /* unsolicited event for HP jack sensing */ |
826 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 847 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) |
827 | { | 848 | { |
@@ -829,10 +850,17 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
829 | res >>= 28; | 850 | res >>= 28; |
830 | else | 851 | else |
831 | res >>= 26; | 852 | res >>= 26; |
832 | if (res != ALC880_HP_EVENT) | 853 | if (res == ALC880_HP_EVENT) |
833 | return; | 854 | alc_sku_automute(codec); |
834 | 855 | ||
856 | if (res == ALC880_MIC_EVENT) | ||
857 | alc_mic_automute(codec); | ||
858 | } | ||
859 | |||
860 | static void alc_inithook(struct hda_codec *codec) | ||
861 | { | ||
835 | alc_sku_automute(codec); | 862 | alc_sku_automute(codec); |
863 | alc_mic_automute(codec); | ||
836 | } | 864 | } |
837 | 865 | ||
838 | /* additional initialization for ALC888 variants */ | 866 | /* additional initialization for ALC888 variants */ |
@@ -1018,10 +1046,17 @@ do_sku: | |||
1018 | else | 1046 | else |
1019 | return; | 1047 | return; |
1020 | } | 1048 | } |
1049 | if (spec->autocfg.hp_pins[0]) | ||
1050 | snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, | ||
1051 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1052 | AC_USRSP_EN | ALC880_HP_EVENT); | ||
1021 | 1053 | ||
1022 | snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, | 1054 | if (spec->autocfg.input_pins[AUTO_PIN_MIC] && |
1023 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1055 | spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) |
1024 | AC_USRSP_EN | ALC880_HP_EVENT); | 1056 | snd_hda_codec_write(codec, |
1057 | spec->autocfg.input_pins[AUTO_PIN_MIC], 0, | ||
1058 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1059 | AC_USRSP_EN | ALC880_MIC_EVENT); | ||
1025 | 1060 | ||
1026 | spec->unsol_event = alc_sku_unsol_event; | 1061 | spec->unsol_event = alc_sku_unsol_event; |
1027 | } | 1062 | } |
@@ -3808,7 +3843,7 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
3808 | alc880_auto_init_extra_out(codec); | 3843 | alc880_auto_init_extra_out(codec); |
3809 | alc880_auto_init_analog_input(codec); | 3844 | alc880_auto_init_analog_input(codec); |
3810 | if (spec->unsol_event) | 3845 | if (spec->unsol_event) |
3811 | alc_sku_automute(codec); | 3846 | alc_inithook(codec); |
3812 | } | 3847 | } |
3813 | 3848 | ||
3814 | /* | 3849 | /* |
@@ -5219,7 +5254,7 @@ static void alc260_auto_init(struct hda_codec *codec) | |||
5219 | alc260_auto_init_multi_out(codec); | 5254 | alc260_auto_init_multi_out(codec); |
5220 | alc260_auto_init_analog_input(codec); | 5255 | alc260_auto_init_analog_input(codec); |
5221 | if (spec->unsol_event) | 5256 | if (spec->unsol_event) |
5222 | alc_sku_automute(codec); | 5257 | alc_inithook(codec); |
5223 | } | 5258 | } |
5224 | 5259 | ||
5225 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5260 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -6629,7 +6664,7 @@ static void alc882_auto_init(struct hda_codec *codec) | |||
6629 | alc882_auto_init_analog_input(codec); | 6664 | alc882_auto_init_analog_input(codec); |
6630 | alc882_auto_init_input_src(codec); | 6665 | alc882_auto_init_input_src(codec); |
6631 | if (spec->unsol_event) | 6666 | if (spec->unsol_event) |
6632 | alc_sku_automute(codec); | 6667 | alc_inithook(codec); |
6633 | } | 6668 | } |
6634 | 6669 | ||
6635 | static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */ | 6670 | static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */ |
@@ -8758,7 +8793,7 @@ static void alc883_auto_init(struct hda_codec *codec) | |||
8758 | alc883_auto_init_analog_input(codec); | 8793 | alc883_auto_init_analog_input(codec); |
8759 | alc883_auto_init_input_src(codec); | 8794 | alc883_auto_init_input_src(codec); |
8760 | if (spec->unsol_event) | 8795 | if (spec->unsol_event) |
8761 | alc_sku_automute(codec); | 8796 | alc_inithook(codec); |
8762 | } | 8797 | } |
8763 | 8798 | ||
8764 | static int patch_alc883(struct hda_codec *codec) | 8799 | static int patch_alc883(struct hda_codec *codec) |
@@ -10285,7 +10320,7 @@ static void alc262_auto_init(struct hda_codec *codec) | |||
10285 | alc262_auto_init_analog_input(codec); | 10320 | alc262_auto_init_analog_input(codec); |
10286 | alc262_auto_init_input_src(codec); | 10321 | alc262_auto_init_input_src(codec); |
10287 | if (spec->unsol_event) | 10322 | if (spec->unsol_event) |
10288 | alc_sku_automute(codec); | 10323 | alc_inithook(codec); |
10289 | } | 10324 | } |
10290 | 10325 | ||
10291 | /* | 10326 | /* |
@@ -11417,7 +11452,7 @@ static void alc268_auto_init(struct hda_codec *codec) | |||
11417 | alc268_auto_init_mono_speaker_out(codec); | 11452 | alc268_auto_init_mono_speaker_out(codec); |
11418 | alc268_auto_init_analog_input(codec); | 11453 | alc268_auto_init_analog_input(codec); |
11419 | if (spec->unsol_event) | 11454 | if (spec->unsol_event) |
11420 | alc_sku_automute(codec); | 11455 | alc_inithook(codec); |
11421 | } | 11456 | } |
11422 | 11457 | ||
11423 | /* | 11458 | /* |
@@ -12200,7 +12235,7 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
12200 | alc269_auto_init_hp_out(codec); | 12235 | alc269_auto_init_hp_out(codec); |
12201 | alc269_auto_init_analog_input(codec); | 12236 | alc269_auto_init_analog_input(codec); |
12202 | if (spec->unsol_event) | 12237 | if (spec->unsol_event) |
12203 | alc_sku_automute(codec); | 12238 | alc_inithook(codec); |
12204 | } | 12239 | } |
12205 | 12240 | ||
12206 | /* | 12241 | /* |
@@ -13281,7 +13316,7 @@ static void alc861_auto_init(struct hda_codec *codec) | |||
13281 | alc861_auto_init_hp_out(codec); | 13316 | alc861_auto_init_hp_out(codec); |
13282 | alc861_auto_init_analog_input(codec); | 13317 | alc861_auto_init_analog_input(codec); |
13283 | if (spec->unsol_event) | 13318 | if (spec->unsol_event) |
13284 | alc_sku_automute(codec); | 13319 | alc_inithook(codec); |
13285 | } | 13320 | } |
13286 | 13321 | ||
13287 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 13322 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -14393,7 +14428,7 @@ static void alc861vd_auto_init(struct hda_codec *codec) | |||
14393 | alc861vd_auto_init_analog_input(codec); | 14428 | alc861vd_auto_init_analog_input(codec); |
14394 | alc861vd_auto_init_input_src(codec); | 14429 | alc861vd_auto_init_input_src(codec); |
14395 | if (spec->unsol_event) | 14430 | if (spec->unsol_event) |
14396 | alc_sku_automute(codec); | 14431 | alc_inithook(codec); |
14397 | } | 14432 | } |
14398 | 14433 | ||
14399 | static int patch_alc861vd(struct hda_codec *codec) | 14434 | static int patch_alc861vd(struct hda_codec *codec) |
@@ -16223,7 +16258,7 @@ static void alc662_auto_init(struct hda_codec *codec) | |||
16223 | alc662_auto_init_analog_input(codec); | 16258 | alc662_auto_init_analog_input(codec); |
16224 | alc662_auto_init_input_src(codec); | 16259 | alc662_auto_init_input_src(codec); |
16225 | if (spec->unsol_event) | 16260 | if (spec->unsol_event) |
16226 | alc_sku_automute(codec); | 16261 | alc_inithook(codec); |
16227 | } | 16262 | } |
16228 | 16263 | ||
16229 | static int patch_alc662(struct hda_codec *codec) | 16264 | static int patch_alc662(struct hda_codec *codec) |