aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c178
1 files changed, 154 insertions, 24 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a7592f5e97d..ca1a87a4812 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -333,6 +333,12 @@ struct alc_spec {
333 hda_nid_t *capsrc_nids; 333 hda_nid_t *capsrc_nids;
334 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 334 hda_nid_t dig_in_nid; /* digital-in NID; optional */
335 335
336 /* capture setup for dynamic dual-adc switch */
337 unsigned int cur_adc_idx;
338 hda_nid_t cur_adc;
339 unsigned int cur_adc_stream_tag;
340 unsigned int cur_adc_format;
341
336 /* capture source */ 342 /* capture source */
337 unsigned int num_mux_defs; 343 unsigned int num_mux_defs;
338 const struct hda_input_mux *input_mux; 344 const struct hda_input_mux *input_mux;
@@ -374,6 +380,7 @@ struct alc_spec {
374 380
375 /* other flags */ 381 /* other flags */
376 unsigned int no_analog :1; /* digital I/O only */ 382 unsigned int no_analog :1; /* digital I/O only */
383 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
377 int init_amp; 384 int init_amp;
378 385
379 /* for virtual master */ 386 /* for virtual master */
@@ -1010,6 +1017,29 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1010 return -1; 1017 return -1;
1011} 1018}
1012 1019
1020/* switch the current ADC according to the jack state */
1021static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1022{
1023 struct alc_spec *spec = codec->spec;
1024 unsigned int present;
1025 hda_nid_t new_adc;
1026
1027 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1028 if (present)
1029 spec->cur_adc_idx = 1;
1030 else
1031 spec->cur_adc_idx = 0;
1032 new_adc = spec->adc_nids[spec->cur_adc_idx];
1033 if (spec->cur_adc && spec->cur_adc != new_adc) {
1034 /* stream is running, let's swap the current ADC */
1035 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1036 spec->cur_adc = new_adc;
1037 snd_hda_codec_setup_stream(codec, new_adc,
1038 spec->cur_adc_stream_tag, 0,
1039 spec->cur_adc_format);
1040 }
1041}
1042
1013static void alc_mic_automute(struct hda_codec *codec) 1043static void alc_mic_automute(struct hda_codec *codec)
1014{ 1044{
1015 struct alc_spec *spec = codec->spec; 1045 struct alc_spec *spec = codec->spec;
@@ -1024,6 +1054,11 @@ static void alc_mic_automute(struct hda_codec *codec)
1024 if (snd_BUG_ON(!spec->adc_nids)) 1054 if (snd_BUG_ON(!spec->adc_nids))
1025 return; 1055 return;
1026 1056
1057 if (spec->dual_adc_switch) {
1058 alc_dual_mic_adc_auto_switch(codec);
1059 return;
1060 }
1061
1027 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1062 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1028 1063
1029 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1064 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
@@ -3614,6 +3649,41 @@ static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3614 return 0; 3649 return 0;
3615} 3650}
3616 3651
3652/* analog capture with dynamic dual-adc changes */
3653static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3654 struct hda_codec *codec,
3655 unsigned int stream_tag,
3656 unsigned int format,
3657 struct snd_pcm_substream *substream)
3658{
3659 struct alc_spec *spec = codec->spec;
3660 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3661 spec->cur_adc_stream_tag = stream_tag;
3662 spec->cur_adc_format = format;
3663 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3664 return 0;
3665}
3666
3667static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3668 struct hda_codec *codec,
3669 struct snd_pcm_substream *substream)
3670{
3671 struct alc_spec *spec = codec->spec;
3672 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3673 spec->cur_adc = 0;
3674 return 0;
3675}
3676
3677static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3678 .substreams = 1,
3679 .channels_min = 2,
3680 .channels_max = 2,
3681 .nid = 0, /* fill later */
3682 .ops = {
3683 .prepare = dualmic_capture_pcm_prepare,
3684 .cleanup = dualmic_capture_pcm_cleanup
3685 },
3686};
3617 3687
3618/* 3688/*
3619 */ 3689 */
@@ -5052,24 +5122,12 @@ static void fixup_automic_adc(struct hda_codec *codec)
5052 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5122 spec->auto_mic = 0; /* disable auto-mic to be sure */
5053} 5123}
5054 5124
5055/* choose the ADC/MUX containing the input pin and initialize the setup */ 5125/* set the default connection to that pin */
5056static void fixup_single_adc(struct hda_codec *codec) 5126static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5057{ 5127{
5058 struct alc_spec *spec = codec->spec; 5128 struct alc_spec *spec = codec->spec;
5059 hda_nid_t pin = 0;
5060 int i; 5129 int i;
5061 5130
5062 /* search for the input pin; there must be only one */
5063 for (i = 0; i < AUTO_PIN_LAST; i++) {
5064 if (spec->autocfg.input_pins[i]) {
5065 pin = spec->autocfg.input_pins[i];
5066 break;
5067 }
5068 }
5069 if (!pin)
5070 return;
5071
5072 /* set the default connection to that pin */
5073 for (i = 0; i < spec->num_adc_nids; i++) { 5131 for (i = 0; i < spec->num_adc_nids; i++) {
5074 hda_nid_t cap = spec->capsrc_nids ? 5132 hda_nid_t cap = spec->capsrc_nids ?
5075 spec->capsrc_nids[i] : spec->adc_nids[i]; 5133 spec->capsrc_nids[i] : spec->adc_nids[i];
@@ -5078,11 +5136,6 @@ static void fixup_single_adc(struct hda_codec *codec)
5078 idx = get_connection_index(codec, cap, pin); 5136 idx = get_connection_index(codec, cap, pin);
5079 if (idx < 0) 5137 if (idx < 0)
5080 continue; 5138 continue;
5081 /* use only this ADC */
5082 if (spec->capsrc_nids)
5083 spec->capsrc_nids += i;
5084 spec->adc_nids += i;
5085 spec->num_adc_nids = 1;
5086 /* select or unmute this route */ 5139 /* select or unmute this route */
5087 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 5140 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5088 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 5141 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
@@ -5091,10 +5144,45 @@ static void fixup_single_adc(struct hda_codec *codec)
5091 snd_hda_codec_write_cache(codec, cap, 0, 5144 snd_hda_codec_write_cache(codec, cap, 0,
5092 AC_VERB_SET_CONNECT_SEL, idx); 5145 AC_VERB_SET_CONNECT_SEL, idx);
5093 } 5146 }
5147 return i; /* return the found index */
5148 }
5149 return -1; /* not found */
5150}
5151
5152/* choose the ADC/MUX containing the input pin and initialize the setup */
5153static void fixup_single_adc(struct hda_codec *codec)
5154{
5155 struct alc_spec *spec = codec->spec;
5156 hda_nid_t pin = 0;
5157 int i;
5158
5159 /* search for the input pin; there must be only one */
5160 for (i = 0; i < AUTO_PIN_LAST; i++) {
5161 if (spec->autocfg.input_pins[i]) {
5162 pin = spec->autocfg.input_pins[i];
5163 break;
5164 }
5165 }
5166 if (!pin)
5094 return; 5167 return;
5168 i = init_capsrc_for_pin(codec, pin);
5169 if (i >= 0) {
5170 /* use only this ADC */
5171 if (spec->capsrc_nids)
5172 spec->capsrc_nids += i;
5173 spec->adc_nids += i;
5174 spec->num_adc_nids = 1;
5095 } 5175 }
5096} 5176}
5097 5177
5178/* initialize dual adcs */
5179static void fixup_dual_adc_switch(struct hda_codec *codec)
5180{
5181 struct alc_spec *spec = codec->spec;
5182 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5183 init_capsrc_for_pin(codec, spec->int_mic.pin);
5184}
5185
5098static void set_capture_mixer(struct hda_codec *codec) 5186static void set_capture_mixer(struct hda_codec *codec)
5099{ 5187{
5100 struct alc_spec *spec = codec->spec; 5188 struct alc_spec *spec = codec->spec;
@@ -5108,7 +5196,10 @@ static void set_capture_mixer(struct hda_codec *codec)
5108 }; 5196 };
5109 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5197 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5110 int mux = 0; 5198 int mux = 0;
5111 if (spec->auto_mic) 5199 int num_adcs = spec->num_adc_nids;
5200 if (spec->dual_adc_switch)
5201 fixup_dual_adc_switch(codec);
5202 else if (spec->auto_mic)
5112 fixup_automic_adc(codec); 5203 fixup_automic_adc(codec);
5113 else if (spec->input_mux) { 5204 else if (spec->input_mux) {
5114 if (spec->input_mux->num_items > 1) 5205 if (spec->input_mux->num_items > 1)
@@ -5116,7 +5207,9 @@ static void set_capture_mixer(struct hda_codec *codec)
5116 else if (spec->input_mux->num_items == 1) 5207 else if (spec->input_mux->num_items == 1)
5117 fixup_single_adc(codec); 5208 fixup_single_adc(codec);
5118 } 5209 }
5119 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; 5210 if (spec->dual_adc_switch)
5211 num_adcs = 1;
5212 spec->cap_mixer = caps[mux][num_adcs - 1];
5120 } 5213 }
5121} 5214}
5122 5215
@@ -14141,6 +14234,36 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14141} 14234}
14142#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14235#endif /* CONFIG_SND_HDA_POWER_SAVE */
14143 14236
14237static int alc275_setup_dual_adc(struct hda_codec *codec)
14238{
14239 struct alc_spec *spec = codec->spec;
14240
14241 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14242 return 0;
14243 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14244 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14245 if (spec->ext_mic.pin <= 0x12) {
14246 spec->private_adc_nids[0] = 0x08;
14247 spec->private_adc_nids[1] = 0x11;
14248 spec->private_capsrc_nids[0] = 0x23;
14249 spec->private_capsrc_nids[1] = 0x22;
14250 } else {
14251 spec->private_adc_nids[0] = 0x11;
14252 spec->private_adc_nids[1] = 0x08;
14253 spec->private_capsrc_nids[0] = 0x22;
14254 spec->private_capsrc_nids[1] = 0x23;
14255 }
14256 spec->adc_nids = spec->private_adc_nids;
14257 spec->capsrc_nids = spec->private_capsrc_nids;
14258 spec->num_adc_nids = 2;
14259 spec->dual_adc_switch = 1;
14260 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14261 spec->adc_nids[0], spec->adc_nids[1]);
14262 return 1;
14263 }
14264 return 0;
14265}
14266
14144/* 14267/*
14145 * BIOS auto configuration 14268 * BIOS auto configuration
14146 */ 14269 */
@@ -14180,11 +14303,14 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14180 14303
14181 spec->num_mux_defs = 1; 14304 spec->num_mux_defs = 1;
14182 spec->input_mux = &spec->private_imux[0]; 14305 spec->input_mux = &spec->private_imux[0];
14183 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14306
14184 sizeof(alc269_adc_candidates)); 14307 if (!alc275_setup_dual_adc(codec))
14308 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14309 sizeof(alc269_adc_candidates));
14185 14310
14186 /* set default input source */ 14311 /* set default input source */
14187 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], 14312 if (!spec->dual_adc_switch)
14313 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
14188 0, AC_VERB_SET_CONNECT_SEL, 14314 0, AC_VERB_SET_CONNECT_SEL,
14189 spec->input_mux->items[0].index); 14315 spec->input_mux->items[0].index);
14190 14316
@@ -14480,6 +14606,10 @@ static int patch_alc269(struct hda_codec *codec)
14480 */ 14606 */
14481 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 14607 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14482 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 14608 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14609 } else if (spec->dual_adc_switch) {
14610 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14611 /* switch ADC dynamically */
14612 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
14483 } else { 14613 } else {
14484 spec->stream_analog_playback = &alc269_pcm_analog_playback; 14614 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14485 spec->stream_analog_capture = &alc269_pcm_analog_capture; 14615 spec->stream_analog_capture = &alc269_pcm_analog_capture;