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