diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-07-07 09:01:13 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-07-07 12:02:43 -0400 |
commit | 21268961d3d1bbdd22a19b68adb80119e8c72dcd (patch) | |
tree | 6041d88f05b73e130b585f74577be813b17d3bb9 /sound/pci/hda/patch_realtek.c | |
parent | a926757f0431042b32ef4188ce8201cbe0fcbb50 (diff) |
ALSA: hda - More flexible dynamic-ADC switching for Realtek codecs
This patch changes the auto-parser and the auto-mic handling codes to
allow more flexible dynamic ADC-switching with Realtek codecs.
In the new code, the following strategy is taken:
- When a cap-src can't handle all input-sources, either skip it, or
switch to the ADC-switching mode. In ADC-switching mode, like the
former dual-ADC mode for ALC275, it changes ADC on the fly according
to the current input source.
- When auto-mic is possible, always assign imux. If the mic pins are
set statically via a quirk, rebuild imux according to the pins.
In the auto-mic mode, the driver always changes the imux (although
the imux isn't exposed as a mixer element).
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 915 |
1 files changed, 429 insertions, 486 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 53188c4cbf75..42026f4978c3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -276,14 +276,6 @@ enum { | |||
276 | ALC_INIT_GPIO3, | 276 | ALC_INIT_GPIO3, |
277 | }; | 277 | }; |
278 | 278 | ||
279 | struct alc_mic_route { | ||
280 | hda_nid_t pin; | ||
281 | unsigned char mux_idx; | ||
282 | unsigned char amix_idx; | ||
283 | }; | ||
284 | |||
285 | #define MUX_IDX_UNDEF ((unsigned char)-1) | ||
286 | |||
287 | struct alc_customize_define { | 279 | struct alc_customize_define { |
288 | unsigned int sku_cfg; | 280 | unsigned int sku_cfg; |
289 | unsigned char port_connectivity; | 281 | unsigned char port_connectivity; |
@@ -351,7 +343,6 @@ struct alc_spec { | |||
351 | hda_nid_t mixer_nid; /* analog-mixer NID */ | 343 | hda_nid_t mixer_nid; /* analog-mixer NID */ |
352 | 344 | ||
353 | /* capture setup for dynamic dual-adc switch */ | 345 | /* capture setup for dynamic dual-adc switch */ |
354 | unsigned int cur_adc_idx; | ||
355 | hda_nid_t cur_adc; | 346 | hda_nid_t cur_adc; |
356 | unsigned int cur_adc_stream_tag; | 347 | unsigned int cur_adc_stream_tag; |
357 | unsigned int cur_adc_format; | 348 | unsigned int cur_adc_format; |
@@ -360,9 +351,9 @@ struct alc_spec { | |||
360 | unsigned int num_mux_defs; | 351 | unsigned int num_mux_defs; |
361 | const struct hda_input_mux *input_mux; | 352 | const struct hda_input_mux *input_mux; |
362 | unsigned int cur_mux[3]; | 353 | unsigned int cur_mux[3]; |
363 | struct alc_mic_route ext_mic; | 354 | hda_nid_t ext_mic_pin; |
364 | struct alc_mic_route dock_mic; | 355 | hda_nid_t dock_mic_pin; |
365 | struct alc_mic_route int_mic; | 356 | hda_nid_t int_mic_pin; |
366 | 357 | ||
367 | /* channel model */ | 358 | /* channel model */ |
368 | const struct hda_channel_mode *channel_mode; | 359 | const struct hda_channel_mode *channel_mode; |
@@ -382,6 +373,9 @@ struct alc_spec { | |||
382 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 373 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
383 | hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; | 374 | hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; |
384 | hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; | 375 | hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; |
376 | hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; | ||
377 | unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; | ||
378 | int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ | ||
385 | 379 | ||
386 | /* hooks */ | 380 | /* hooks */ |
387 | void (*init_hook)(struct hda_codec *codec); | 381 | void (*init_hook)(struct hda_codec *codec); |
@@ -396,6 +390,7 @@ struct alc_spec { | |||
396 | unsigned int line_jack_present:1; | 390 | unsigned int line_jack_present:1; |
397 | unsigned int master_mute:1; | 391 | unsigned int master_mute:1; |
398 | unsigned int auto_mic:1; | 392 | unsigned int auto_mic:1; |
393 | unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */ | ||
399 | unsigned int automute:1; /* HP automute enabled */ | 394 | unsigned int automute:1; /* HP automute enabled */ |
400 | unsigned int detect_line:1; /* Line-out detection enabled */ | 395 | unsigned int detect_line:1; /* Line-out detection enabled */ |
401 | unsigned int automute_lines:1; /* automute line-out as well */ | 396 | unsigned int automute_lines:1; /* automute line-out as well */ |
@@ -403,7 +398,7 @@ struct alc_spec { | |||
403 | 398 | ||
404 | /* other flags */ | 399 | /* other flags */ |
405 | unsigned int no_analog :1; /* digital I/O only */ | 400 | unsigned int no_analog :1; /* digital I/O only */ |
406 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ | 401 | unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ |
407 | unsigned int single_input_src:1; | 402 | unsigned int single_input_src:1; |
408 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ | 403 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ |
409 | 404 | ||
@@ -495,47 +490,81 @@ static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, | |||
495 | return 0; | 490 | return 0; |
496 | } | 491 | } |
497 | 492 | ||
498 | static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, | 493 | static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) |
499 | struct snd_ctl_elem_value *ucontrol) | 494 | { |
495 | struct alc_spec *spec = codec->spec; | ||
496 | hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]]; | ||
497 | |||
498 | if (spec->cur_adc && spec->cur_adc != new_adc) { | ||
499 | /* stream is running, let's swap the current ADC */ | ||
500 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
501 | spec->cur_adc = new_adc; | ||
502 | snd_hda_codec_setup_stream(codec, new_adc, | ||
503 | spec->cur_adc_stream_tag, 0, | ||
504 | spec->cur_adc_format); | ||
505 | return true; | ||
506 | } | ||
507 | return false; | ||
508 | } | ||
509 | |||
510 | /* select the given imux item; either unmute exclusively or select the route */ | ||
511 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | ||
512 | unsigned int idx, bool force) | ||
500 | { | 513 | { |
501 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
502 | struct alc_spec *spec = codec->spec; | 514 | struct alc_spec *spec = codec->spec; |
503 | const struct hda_input_mux *imux; | 515 | const struct hda_input_mux *imux; |
504 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
505 | unsigned int mux_idx; | 516 | unsigned int mux_idx; |
506 | hda_nid_t nid = spec->capsrc_nids ? | 517 | int i, type; |
507 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; | 518 | hda_nid_t nid; |
508 | unsigned int type; | ||
509 | 519 | ||
510 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 520 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
511 | imux = &spec->input_mux[mux_idx]; | 521 | imux = &spec->input_mux[mux_idx]; |
512 | if (!imux->num_items && mux_idx > 0) | 522 | if (!imux->num_items && mux_idx > 0) |
513 | imux = &spec->input_mux[0]; | 523 | imux = &spec->input_mux[0]; |
514 | 524 | ||
525 | if (idx >= imux->num_items) | ||
526 | idx = imux->num_items - 1; | ||
527 | if (spec->cur_mux[adc_idx] == idx && !force) | ||
528 | return 0; | ||
529 | spec->cur_mux[adc_idx] = idx; | ||
530 | |||
531 | if (spec->dyn_adc_switch) { | ||
532 | alc_dyn_adc_pcm_resetup(codec, idx); | ||
533 | adc_idx = spec->dyn_adc_idx[idx]; | ||
534 | } | ||
535 | |||
536 | nid = spec->capsrc_nids ? | ||
537 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; | ||
538 | |||
539 | /* no selection? */ | ||
540 | if (snd_hda_get_conn_list(codec, nid, NULL) <= 1) | ||
541 | return 1; | ||
542 | |||
515 | type = get_wcaps_type(get_wcaps(codec, nid)); | 543 | type = get_wcaps_type(get_wcaps(codec, nid)); |
516 | if (type == AC_WID_AUD_MIX) { | 544 | if (type == AC_WID_AUD_MIX) { |
517 | /* Matrix-mixer style (e.g. ALC882) */ | 545 | /* Matrix-mixer style (e.g. ALC882) */ |
518 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | ||
519 | unsigned int i, idx; | ||
520 | |||
521 | idx = ucontrol->value.enumerated.item[0]; | ||
522 | if (idx >= imux->num_items) | ||
523 | idx = imux->num_items - 1; | ||
524 | if (*cur_val == idx) | ||
525 | return 0; | ||
526 | for (i = 0; i < imux->num_items; i++) { | 546 | for (i = 0; i < imux->num_items; i++) { |
527 | unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; | 547 | unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; |
528 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, | 548 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, |
529 | imux->items[i].index, | 549 | imux->items[i].index, |
530 | HDA_AMP_MUTE, v); | 550 | HDA_AMP_MUTE, v); |
531 | } | 551 | } |
532 | *cur_val = idx; | ||
533 | return 1; | ||
534 | } else { | 552 | } else { |
535 | /* MUX style (e.g. ALC880) */ | 553 | /* MUX style (e.g. ALC880) */ |
536 | return snd_hda_input_mux_put(codec, imux, ucontrol, nid, | 554 | snd_hda_codec_write_cache(codec, nid, 0, |
537 | &spec->cur_mux[adc_idx]); | 555 | AC_VERB_SET_CONNECT_SEL, |
556 | imux->items[idx].index); | ||
538 | } | 557 | } |
558 | return 1; | ||
559 | } | ||
560 | |||
561 | static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
562 | struct snd_ctl_elem_value *ucontrol) | ||
563 | { | ||
564 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
565 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
566 | return alc_mux_select(codec, adc_idx, | ||
567 | ucontrol->value.enumerated.item[0], false); | ||
539 | } | 568 | } |
540 | 569 | ||
541 | /* | 570 | /* |
@@ -1059,8 +1088,8 @@ static int alc_init_jacks(struct hda_codec *codec) | |||
1059 | struct alc_spec *spec = codec->spec; | 1088 | struct alc_spec *spec = codec->spec; |
1060 | int err; | 1089 | int err; |
1061 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; | 1090 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; |
1062 | unsigned int mic_nid = spec->ext_mic.pin; | 1091 | unsigned int mic_nid = spec->ext_mic_pin; |
1063 | unsigned int dock_nid = spec->dock_mic.pin; | 1092 | unsigned int dock_nid = spec->dock_mic_pin; |
1064 | 1093 | ||
1065 | if (hp_nid) { | 1094 | if (hp_nid) { |
1066 | err = snd_hda_input_jack_add(codec, hp_nid, | 1095 | err = snd_hda_input_jack_add(codec, hp_nid, |
@@ -1199,93 +1228,29 @@ static void alc_line_automute(struct hda_codec *codec) | |||
1199 | #define get_connection_index(codec, mux, nid) \ | 1228 | #define get_connection_index(codec, mux, nid) \ |
1200 | snd_hda_get_conn_index(codec, mux, nid, 0) | 1229 | snd_hda_get_conn_index(codec, mux, nid, 0) |
1201 | 1230 | ||
1202 | /* switch the current ADC according to the jack state */ | ||
1203 | static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) | ||
1204 | { | ||
1205 | struct alc_spec *spec = codec->spec; | ||
1206 | unsigned int present; | ||
1207 | hda_nid_t new_adc; | ||
1208 | |||
1209 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); | ||
1210 | if (present) | ||
1211 | spec->cur_adc_idx = 1; | ||
1212 | else | ||
1213 | spec->cur_adc_idx = 0; | ||
1214 | new_adc = spec->adc_nids[spec->cur_adc_idx]; | ||
1215 | if (spec->cur_adc && spec->cur_adc != new_adc) { | ||
1216 | /* stream is running, let's swap the current ADC */ | ||
1217 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
1218 | spec->cur_adc = new_adc; | ||
1219 | snd_hda_codec_setup_stream(codec, new_adc, | ||
1220 | spec->cur_adc_stream_tag, 0, | ||
1221 | spec->cur_adc_format); | ||
1222 | } | ||
1223 | } | ||
1224 | |||
1225 | static void alc_mic_automute(struct hda_codec *codec) | 1231 | static void alc_mic_automute(struct hda_codec *codec) |
1226 | { | 1232 | { |
1227 | struct alc_spec *spec = codec->spec; | 1233 | struct alc_spec *spec = codec->spec; |
1228 | struct alc_mic_route *dead1, *dead2, *alive; | 1234 | hda_nid_t *pins = spec->imux_pins; |
1229 | unsigned int present, type; | ||
1230 | hda_nid_t cap_nid; | ||
1231 | 1235 | ||
1232 | if (!spec->auto_mic) | 1236 | if (!spec->auto_mic || !spec->auto_mic_valid_imux) |
1233 | return; | ||
1234 | if (!spec->int_mic.pin || !spec->ext_mic.pin) | ||
1235 | return; | 1237 | return; |
1236 | if (snd_BUG_ON(!spec->adc_nids)) | 1238 | if (snd_BUG_ON(!spec->adc_nids)) |
1237 | return; | 1239 | return; |
1238 | 1240 | if (snd_BUG_ON(spec->int_mic_idx < 0 || spec->ext_mic_idx < 0)) | |
1239 | if (spec->dual_adc_switch) { | ||
1240 | alc_dual_mic_adc_auto_switch(codec); | ||
1241 | return; | 1241 | return; |
1242 | } | ||
1243 | |||
1244 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; | ||
1245 | |||
1246 | alive = &spec->int_mic; | ||
1247 | dead1 = &spec->ext_mic; | ||
1248 | dead2 = &spec->dock_mic; | ||
1249 | |||
1250 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); | ||
1251 | if (present) { | ||
1252 | alive = &spec->ext_mic; | ||
1253 | dead1 = &spec->int_mic; | ||
1254 | dead2 = &spec->dock_mic; | ||
1255 | } | ||
1256 | if (!present && spec->dock_mic.pin > 0) { | ||
1257 | present = snd_hda_jack_detect(codec, spec->dock_mic.pin); | ||
1258 | if (present) { | ||
1259 | alive = &spec->dock_mic; | ||
1260 | dead1 = &spec->int_mic; | ||
1261 | dead2 = &spec->ext_mic; | ||
1262 | } | ||
1263 | snd_hda_input_jack_report(codec, spec->dock_mic.pin); | ||
1264 | } | ||
1265 | 1242 | ||
1266 | type = get_wcaps_type(get_wcaps(codec, cap_nid)); | 1243 | if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx])) |
1267 | if (type == AC_WID_AUD_MIX) { | 1244 | alc_mux_select(codec, 0, spec->ext_mic_idx, false); |
1268 | /* Matrix-mixer style (e.g. ALC882) */ | 1245 | else if (spec->dock_mic_idx >= 0 && |
1269 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, | 1246 | snd_hda_jack_detect(codec, pins[spec->dock_mic_idx])) |
1270 | alive->mux_idx, | 1247 | alc_mux_select(codec, 0, spec->dock_mic_idx, false); |
1271 | HDA_AMP_MUTE, 0); | 1248 | else |
1272 | if (dead1->pin > 0) | 1249 | alc_mux_select(codec, 0, spec->int_mic_idx, false); |
1273 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, | ||
1274 | dead1->mux_idx, | ||
1275 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
1276 | if (dead2->pin > 0) | ||
1277 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, | ||
1278 | dead2->mux_idx, | ||
1279 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
1280 | } else { | ||
1281 | /* MUX style (e.g. ALC880) */ | ||
1282 | snd_hda_codec_write_cache(codec, cap_nid, 0, | ||
1283 | AC_VERB_SET_CONNECT_SEL, | ||
1284 | alive->mux_idx); | ||
1285 | } | ||
1286 | snd_hda_input_jack_report(codec, spec->ext_mic.pin); | ||
1287 | 1250 | ||
1288 | /* FIXME: analog mixer */ | 1251 | snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]); |
1252 | if (spec->dock_mic_idx >= 0) | ||
1253 | snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]); | ||
1289 | } | 1254 | } |
1290 | 1255 | ||
1291 | /* unsolicited event for HP jack sensing */ | 1256 | /* unsolicited event for HP jack sensing */ |
@@ -1602,6 +1567,87 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
1602 | } | 1567 | } |
1603 | } | 1568 | } |
1604 | 1569 | ||
1570 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
1571 | { | ||
1572 | int i; | ||
1573 | for (i = 0; i < nums; i++) | ||
1574 | if (list[i] == nid) | ||
1575 | return i; | ||
1576 | return -1; | ||
1577 | } | ||
1578 | |||
1579 | static bool alc_check_dyn_adc_switch(struct hda_codec *codec); | ||
1580 | |||
1581 | /* rebuild imux for matching with the given auto-mic pins (if not yet) */ | ||
1582 | static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) | ||
1583 | { | ||
1584 | struct alc_spec *spec = codec->spec; | ||
1585 | struct hda_input_mux *imux; | ||
1586 | static char * const texts[3] = { | ||
1587 | "Mic", "Internal Mic", "Dock Mic" | ||
1588 | }; | ||
1589 | int i; | ||
1590 | |||
1591 | if (!spec->auto_mic) | ||
1592 | return false; | ||
1593 | imux = &spec->private_imux[0]; | ||
1594 | if (spec->input_mux == imux) | ||
1595 | return true; | ||
1596 | spec->imux_pins[0] = spec->ext_mic_pin; | ||
1597 | spec->imux_pins[1] = spec->int_mic_pin; | ||
1598 | spec->imux_pins[2] = spec->dock_mic_pin; | ||
1599 | for (i = 0; i < 3; i++) { | ||
1600 | strcpy(imux->items[i].label, texts[i]); | ||
1601 | if (spec->imux_pins[i]) | ||
1602 | imux->num_items = i + 1; | ||
1603 | } | ||
1604 | spec->num_mux_defs = 1; | ||
1605 | spec->input_mux = imux; | ||
1606 | return true; | ||
1607 | } | ||
1608 | |||
1609 | /* check whether all auto-mic pins are valid; setup indices if OK */ | ||
1610 | static bool alc_auto_mic_check_imux(struct hda_codec *codec) | ||
1611 | { | ||
1612 | struct alc_spec *spec = codec->spec; | ||
1613 | const struct hda_input_mux *imux; | ||
1614 | |||
1615 | if (!spec->auto_mic) | ||
1616 | return false; | ||
1617 | if (spec->auto_mic_valid_imux) | ||
1618 | return true; /* already checked */ | ||
1619 | |||
1620 | /* fill up imux indices */ | ||
1621 | if (!alc_check_dyn_adc_switch(codec)) { | ||
1622 | spec->auto_mic = 0; | ||
1623 | return false; | ||
1624 | } | ||
1625 | |||
1626 | imux = spec->input_mux; | ||
1627 | spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin, | ||
1628 | spec->imux_pins, imux->num_items); | ||
1629 | spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin, | ||
1630 | spec->imux_pins, imux->num_items); | ||
1631 | spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin, | ||
1632 | spec->imux_pins, imux->num_items); | ||
1633 | if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) { | ||
1634 | spec->auto_mic = 0; | ||
1635 | return false; /* no corresponding imux */ | ||
1636 | } | ||
1637 | |||
1638 | snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0, | ||
1639 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1640 | AC_USRSP_EN | ALC880_MIC_EVENT); | ||
1641 | if (spec->dock_mic_pin) | ||
1642 | snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0, | ||
1643 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1644 | AC_USRSP_EN | ALC880_MIC_EVENT); | ||
1645 | |||
1646 | spec->auto_mic_valid_imux = 1; | ||
1647 | spec->auto_mic = 1; | ||
1648 | return true; | ||
1649 | } | ||
1650 | |||
1605 | static void alc_init_auto_mic(struct hda_codec *codec) | 1651 | static void alc_init_auto_mic(struct hda_codec *codec) |
1606 | { | 1652 | { |
1607 | struct alc_spec *spec = codec->spec; | 1653 | struct alc_spec *spec = codec->spec; |
@@ -1609,6 +1655,8 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1609 | hda_nid_t fixed, ext, dock; | 1655 | hda_nid_t fixed, ext, dock; |
1610 | int i; | 1656 | int i; |
1611 | 1657 | ||
1658 | spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1; | ||
1659 | |||
1612 | fixed = ext = dock = 0; | 1660 | fixed = ext = dock = 0; |
1613 | for (i = 0; i < cfg->num_inputs; i++) { | 1661 | for (i = 0; i < cfg->num_inputs; i++) { |
1614 | hda_nid_t nid = cfg->inputs[i].pin; | 1662 | hda_nid_t nid = cfg->inputs[i].pin; |
@@ -1650,18 +1698,18 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1650 | return; /* no unsol support */ | 1698 | return; /* no unsol support */ |
1651 | if (dock && !is_jack_detectable(codec, dock)) | 1699 | if (dock && !is_jack_detectable(codec, dock)) |
1652 | return; /* no unsol support */ | 1700 | return; /* no unsol support */ |
1701 | |||
1702 | /* check imux indices */ | ||
1703 | spec->ext_mic_pin = ext; | ||
1704 | spec->int_mic_pin = fixed; | ||
1705 | spec->dock_mic_pin = dock; | ||
1706 | |||
1707 | spec->auto_mic = 1; | ||
1708 | if (!alc_auto_mic_check_imux(codec)) | ||
1709 | return; | ||
1710 | |||
1653 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", | 1711 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", |
1654 | ext, fixed, dock); | 1712 | ext, fixed, dock); |
1655 | spec->ext_mic.pin = ext; | ||
1656 | spec->dock_mic.pin = dock; | ||
1657 | spec->int_mic.pin = fixed; | ||
1658 | spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ | ||
1659 | spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ | ||
1660 | spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ | ||
1661 | spec->auto_mic = 1; | ||
1662 | snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, | ||
1663 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1664 | AC_USRSP_EN | ALC880_MIC_EVENT); | ||
1665 | spec->unsol_event = alc_sku_unsol_event; | 1713 | spec->unsol_event = alc_sku_unsol_event; |
1666 | } | 1714 | } |
1667 | 1715 | ||
@@ -1737,11 +1785,7 @@ do_sku: | |||
1737 | 1785 | ||
1738 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | 1786 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) |
1739 | { | 1787 | { |
1740 | int i; | 1788 | return find_idx_in_nid_list(nid, list, nums) >= 0; |
1741 | for (i = 0; i < nums; i++) | ||
1742 | if (list[i] == nid) | ||
1743 | return true; | ||
1744 | return false; | ||
1745 | } | 1789 | } |
1746 | 1790 | ||
1747 | /* check subsystem ID and set up device-specific initialization; | 1791 | /* check subsystem ID and set up device-specific initialization; |
@@ -1871,7 +1915,11 @@ static void alc_ssid_check(struct hda_codec *codec, | |||
1871 | "Enable default setup for auto mode as fallback\n"); | 1915 | "Enable default setup for auto mode as fallback\n"); |
1872 | spec->init_amp = ALC_INIT_DEFAULT; | 1916 | spec->init_amp = ALC_INIT_DEFAULT; |
1873 | } | 1917 | } |
1918 | } | ||
1874 | 1919 | ||
1920 | /* check the availabilities of auto-mute and auto-mic switches */ | ||
1921 | static void alc_auto_check_switches(struct hda_codec *codec) | ||
1922 | { | ||
1875 | alc_init_auto_hp(codec); | 1923 | alc_init_auto_hp(codec); |
1876 | alc_init_auto_mic(codec); | 1924 | alc_init_auto_mic(codec); |
1877 | } | 1925 | } |
@@ -2722,10 +2770,10 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | |||
2722 | { | 2770 | { |
2723 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2771 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2724 | struct alc_spec *spec = codec->spec; | 2772 | struct alc_spec *spec = codec->spec; |
2725 | int i, err; | 2773 | int i, err = 0; |
2726 | 2774 | ||
2727 | mutex_lock(&codec->control_mutex); | 2775 | mutex_lock(&codec->control_mutex); |
2728 | if (check_adc_switch && spec->dual_adc_switch) { | 2776 | if (check_adc_switch && spec->dyn_adc_switch) { |
2729 | for (i = 0; i < spec->num_adc_nids; i++) { | 2777 | for (i = 0; i < spec->num_adc_nids; i++) { |
2730 | kcontrol->private_value = | 2778 | kcontrol->private_value = |
2731 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | 2779 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], |
@@ -2742,8 +2790,8 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | |||
2742 | 3, 0, HDA_OUTPUT); | 2790 | 3, 0, HDA_OUTPUT); |
2743 | else | 2791 | else |
2744 | kcontrol->private_value = | 2792 | kcontrol->private_value = |
2745 | val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | 2793 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], |
2746 | 3, 0, HDA_INPUT); | 2794 | 3, 0, HDA_INPUT); |
2747 | err = func(kcontrol, ucontrol); | 2795 | err = func(kcontrol, ucontrol); |
2748 | } | 2796 | } |
2749 | error: | 2797 | error: |
@@ -4299,21 +4347,21 @@ static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
4299 | } | 4347 | } |
4300 | 4348 | ||
4301 | /* analog capture with dynamic dual-adc changes */ | 4349 | /* analog capture with dynamic dual-adc changes */ |
4302 | static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | 4350 | static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo, |
4303 | struct hda_codec *codec, | 4351 | struct hda_codec *codec, |
4304 | unsigned int stream_tag, | 4352 | unsigned int stream_tag, |
4305 | unsigned int format, | 4353 | unsigned int format, |
4306 | struct snd_pcm_substream *substream) | 4354 | struct snd_pcm_substream *substream) |
4307 | { | 4355 | { |
4308 | struct alc_spec *spec = codec->spec; | 4356 | struct alc_spec *spec = codec->spec; |
4309 | spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; | 4357 | spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]]; |
4310 | spec->cur_adc_stream_tag = stream_tag; | 4358 | spec->cur_adc_stream_tag = stream_tag; |
4311 | spec->cur_adc_format = format; | 4359 | spec->cur_adc_format = format; |
4312 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | 4360 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); |
4313 | return 0; | 4361 | return 0; |
4314 | } | 4362 | } |
4315 | 4363 | ||
4316 | static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | 4364 | static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, |
4317 | struct hda_codec *codec, | 4365 | struct hda_codec *codec, |
4318 | struct snd_pcm_substream *substream) | 4366 | struct snd_pcm_substream *substream) |
4319 | { | 4367 | { |
@@ -4323,14 +4371,14 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
4323 | return 0; | 4371 | return 0; |
4324 | } | 4372 | } |
4325 | 4373 | ||
4326 | static const struct hda_pcm_stream dualmic_pcm_analog_capture = { | 4374 | static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = { |
4327 | .substreams = 1, | 4375 | .substreams = 1, |
4328 | .channels_min = 2, | 4376 | .channels_min = 2, |
4329 | .channels_max = 2, | 4377 | .channels_max = 2, |
4330 | .nid = 0, /* fill later */ | 4378 | .nid = 0, /* fill later */ |
4331 | .ops = { | 4379 | .ops = { |
4332 | .prepare = dualmic_capture_pcm_prepare, | 4380 | .prepare = dyn_adc_capture_pcm_prepare, |
4333 | .cleanup = dualmic_capture_pcm_cleanup | 4381 | .cleanup = dyn_adc_capture_pcm_cleanup |
4334 | }, | 4382 | }, |
4335 | }; | 4383 | }; |
4336 | 4384 | ||
@@ -4426,8 +4474,12 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
4426 | } | 4474 | } |
4427 | if (spec->adc_nids) { | 4475 | if (spec->adc_nids) { |
4428 | p = spec->stream_analog_capture; | 4476 | p = spec->stream_analog_capture; |
4429 | if (!p) | 4477 | if (!p) { |
4430 | p = &alc_pcm_analog_capture; | 4478 | if (spec->dyn_adc_switch) |
4479 | p = &dyn_adc_pcm_analog_capture; | ||
4480 | else | ||
4481 | p = &alc_pcm_analog_capture; | ||
4482 | } | ||
4431 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; | 4483 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; |
4432 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | 4484 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; |
4433 | } | 4485 | } |
@@ -5452,8 +5504,7 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) | |||
5452 | break; | 5504 | break; |
5453 | } | 5505 | } |
5454 | spec->adc_nids = spec->private_adc_nids; | 5506 | spec->adc_nids = spec->private_adc_nids; |
5455 | if (indep_capsrc) | 5507 | spec->capsrc_nids = spec->private_capsrc_nids; |
5456 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
5457 | spec->num_adc_nids = nums; | 5508 | spec->num_adc_nids = nums; |
5458 | return nums; | 5509 | return nums; |
5459 | } | 5510 | } |
@@ -5504,11 +5555,16 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) | |||
5504 | spec->capsrc_nids[c] : spec->adc_nids[c]; | 5555 | spec->capsrc_nids[c] : spec->adc_nids[c]; |
5505 | idx = get_connection_index(codec, cap, pin); | 5556 | idx = get_connection_index(codec, cap, pin); |
5506 | if (idx >= 0) { | 5557 | if (idx >= 0) { |
5558 | spec->imux_pins[imux->num_items] = pin; | ||
5507 | snd_hda_add_imux_item(imux, label, idx, NULL); | 5559 | snd_hda_add_imux_item(imux, label, idx, NULL); |
5508 | break; | 5560 | break; |
5509 | } | 5561 | } |
5510 | } | 5562 | } |
5511 | } | 5563 | } |
5564 | |||
5565 | spec->num_mux_defs = 1; | ||
5566 | spec->input_mux = imux; | ||
5567 | |||
5512 | return 0; | 5568 | return 0; |
5513 | } | 5569 | } |
5514 | 5570 | ||
@@ -5613,13 +5669,10 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
5613 | if (spec->kctls.list) | 5669 | if (spec->kctls.list) |
5614 | add_mixer(spec, spec->kctls.list); | 5670 | add_mixer(spec, spec->kctls.list); |
5615 | 5671 | ||
5616 | spec->num_mux_defs = 1; | 5672 | alc_remove_invalid_adc_nids(codec); |
5617 | spec->input_mux = &spec->private_imux[0]; | ||
5618 | |||
5619 | if (!spec->dual_adc_switch) | ||
5620 | alc_remove_invalid_adc_nids(codec); | ||
5621 | 5673 | ||
5622 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | 5674 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
5675 | alc_auto_check_switches(codec); | ||
5623 | 5676 | ||
5624 | return 1; | 5677 | return 1; |
5625 | } | 5678 | } |
@@ -5637,45 +5690,6 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
5637 | alc_inithook(codec); | 5690 | alc_inithook(codec); |
5638 | } | 5691 | } |
5639 | 5692 | ||
5640 | /* check the ADC/MUX contains all input pins; some ADC/MUX contains only | ||
5641 | * one of two digital mic pins, e.g. on ALC272 | ||
5642 | */ | ||
5643 | static void fixup_automic_adc(struct hda_codec *codec) | ||
5644 | { | ||
5645 | struct alc_spec *spec = codec->spec; | ||
5646 | int i; | ||
5647 | |||
5648 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
5649 | hda_nid_t cap = spec->capsrc_nids ? | ||
5650 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
5651 | int iidx, eidx; | ||
5652 | |||
5653 | iidx = get_connection_index(codec, cap, spec->int_mic.pin); | ||
5654 | if (iidx < 0) | ||
5655 | continue; | ||
5656 | eidx = get_connection_index(codec, cap, spec->ext_mic.pin); | ||
5657 | if (eidx < 0) | ||
5658 | continue; | ||
5659 | spec->int_mic.mux_idx = iidx; | ||
5660 | spec->ext_mic.mux_idx = eidx; | ||
5661 | if (spec->capsrc_nids) | ||
5662 | spec->capsrc_nids += i; | ||
5663 | spec->adc_nids += i; | ||
5664 | spec->num_adc_nids = 1; | ||
5665 | /* optional dock-mic */ | ||
5666 | eidx = get_connection_index(codec, cap, spec->dock_mic.pin); | ||
5667 | if (eidx < 0) | ||
5668 | spec->dock_mic.pin = 0; | ||
5669 | else | ||
5670 | spec->dock_mic.mux_idx = eidx; | ||
5671 | return; | ||
5672 | } | ||
5673 | snd_printd(KERN_INFO "hda_codec: %s: " | ||
5674 | "No ADC/MUX containing both 0x%x and 0x%x pins\n", | ||
5675 | codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); | ||
5676 | spec->auto_mic = 0; /* disable auto-mic to be sure */ | ||
5677 | } | ||
5678 | |||
5679 | /* select or unmute the given capsrc route */ | 5693 | /* select or unmute the given capsrc route */ |
5680 | static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, | 5694 | static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, |
5681 | int idx) | 5695 | int idx) |
@@ -5683,7 +5697,7 @@ static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, | |||
5683 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { | 5697 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { |
5684 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, | 5698 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, |
5685 | HDA_AMP_MUTE, 0); | 5699 | HDA_AMP_MUTE, 0); |
5686 | } else { | 5700 | } else if (snd_hda_get_conn_list(codec, cap, NULL) > 1) { |
5687 | snd_hda_codec_write_cache(codec, cap, 0, | 5701 | snd_hda_codec_write_cache(codec, cap, 0, |
5688 | AC_VERB_SET_CONNECT_SEL, idx); | 5702 | AC_VERB_SET_CONNECT_SEL, idx); |
5689 | } | 5703 | } |
@@ -5711,44 +5725,14 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | |||
5711 | return -1; /* not found */ | 5725 | return -1; /* not found */ |
5712 | } | 5726 | } |
5713 | 5727 | ||
5714 | /* choose the ADC/MUX containing the input pin and initialize the setup */ | ||
5715 | static void fixup_single_adc(struct hda_codec *codec) | ||
5716 | { | ||
5717 | struct alc_spec *spec = codec->spec; | ||
5718 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
5719 | int i; | ||
5720 | |||
5721 | /* search for the input pin; there must be only one */ | ||
5722 | if (cfg->num_inputs != 1) | ||
5723 | return; | ||
5724 | i = init_capsrc_for_pin(codec, cfg->inputs[0].pin); | ||
5725 | if (i >= 0) { | ||
5726 | /* use only this ADC */ | ||
5727 | if (spec->capsrc_nids) | ||
5728 | spec->capsrc_nids += i; | ||
5729 | spec->adc_nids += i; | ||
5730 | spec->num_adc_nids = 1; | ||
5731 | spec->single_input_src = 1; | ||
5732 | } | ||
5733 | } | ||
5734 | |||
5735 | /* initialize dual adcs */ | ||
5736 | static void fixup_dual_adc_switch(struct hda_codec *codec) | ||
5737 | { | ||
5738 | struct alc_spec *spec = codec->spec; | ||
5739 | init_capsrc_for_pin(codec, spec->ext_mic.pin); | ||
5740 | init_capsrc_for_pin(codec, spec->dock_mic.pin); | ||
5741 | init_capsrc_for_pin(codec, spec->int_mic.pin); | ||
5742 | } | ||
5743 | |||
5744 | /* initialize some special cases for input sources */ | 5728 | /* initialize some special cases for input sources */ |
5745 | static void alc_init_special_input_src(struct hda_codec *codec) | 5729 | static void alc_init_special_input_src(struct hda_codec *codec) |
5746 | { | 5730 | { |
5747 | struct alc_spec *spec = codec->spec; | 5731 | struct alc_spec *spec = codec->spec; |
5748 | if (spec->dual_adc_switch) | 5732 | int i; |
5749 | fixup_dual_adc_switch(codec); | 5733 | |
5750 | else if (spec->single_input_src) | 5734 | for (i = 0; i < spec->autocfg.num_inputs; i++) |
5751 | init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); | 5735 | init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin); |
5752 | } | 5736 | } |
5753 | 5737 | ||
5754 | static void set_capture_mixer(struct hda_codec *codec) | 5738 | static void set_capture_mixer(struct hda_codec *codec) |
@@ -5777,16 +5761,14 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
5777 | if (spec->num_adc_nids > 0) { | 5761 | if (spec->num_adc_nids > 0) { |
5778 | int mux = 0; | 5762 | int mux = 0; |
5779 | int num_adcs = 0; | 5763 | int num_adcs = 0; |
5780 | if (spec->dual_adc_switch) | 5764 | |
5765 | if (spec->input_mux && spec->input_mux->num_items > 1) | ||
5766 | mux = 1; | ||
5767 | if (spec->auto_mic) { | ||
5768 | num_adcs = 1; | ||
5769 | mux = 0; | ||
5770 | } else if (spec->dyn_adc_switch) | ||
5781 | num_adcs = 1; | 5771 | num_adcs = 1; |
5782 | else if (spec->auto_mic) | ||
5783 | fixup_automic_adc(codec); | ||
5784 | else if (spec->input_mux) { | ||
5785 | if (spec->input_mux->num_items > 1) | ||
5786 | mux = 1; | ||
5787 | else if (spec->input_mux->num_items == 1) | ||
5788 | fixup_single_adc(codec); | ||
5789 | } | ||
5790 | if (!num_adcs) { | 5772 | if (!num_adcs) { |
5791 | if (spec->num_adc_nids > 3) | 5773 | if (spec->num_adc_nids > 3) |
5792 | spec->num_adc_nids = 3; | 5774 | spec->num_adc_nids = 3; |
@@ -5798,35 +5780,92 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
5798 | } | 5780 | } |
5799 | } | 5781 | } |
5800 | 5782 | ||
5783 | /* check whether dynamic ADC-switching is available */ | ||
5784 | static bool alc_check_dyn_adc_switch(struct hda_codec *codec) | ||
5785 | { | ||
5786 | struct alc_spec *spec = codec->spec; | ||
5787 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
5788 | int i, n, idx; | ||
5789 | hda_nid_t cap, pin; | ||
5790 | |||
5791 | if (imux != spec->input_mux) /* no dynamic imux? */ | ||
5792 | return false; | ||
5793 | |||
5794 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
5795 | cap = spec->private_capsrc_nids[n]; | ||
5796 | for (i = 0; i < imux->num_items; i++) { | ||
5797 | pin = spec->imux_pins[i]; | ||
5798 | if (!pin) | ||
5799 | return false; | ||
5800 | if (get_connection_index(codec, cap, pin) < 0) | ||
5801 | break; | ||
5802 | } | ||
5803 | if (i >= imux->num_items) | ||
5804 | return false; /* no ADC-switch is needed */ | ||
5805 | } | ||
5806 | |||
5807 | for (i = 0; i < imux->num_items; i++) { | ||
5808 | pin = spec->imux_pins[i]; | ||
5809 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
5810 | cap = spec->private_capsrc_nids[n]; | ||
5811 | idx = get_connection_index(codec, cap, pin); | ||
5812 | if (idx >= 0) { | ||
5813 | imux->items[i].index = idx; | ||
5814 | spec->dyn_adc_idx[i] = n; | ||
5815 | break; | ||
5816 | } | ||
5817 | } | ||
5818 | } | ||
5819 | |||
5820 | snd_printdd("realtek: enabling ADC switching\n"); | ||
5821 | spec->dyn_adc_switch = 1; | ||
5822 | return true; | ||
5823 | } | ||
5824 | |||
5801 | /* filter out invalid adc_nids (and capsrc_nids) that don't give all | 5825 | /* filter out invalid adc_nids (and capsrc_nids) that don't give all |
5802 | * active input pins | 5826 | * active input pins |
5803 | */ | 5827 | */ |
5804 | static void alc_remove_invalid_adc_nids(struct hda_codec *codec) | 5828 | static void alc_remove_invalid_adc_nids(struct hda_codec *codec) |
5805 | { | 5829 | { |
5806 | struct alc_spec *spec = codec->spec; | 5830 | struct alc_spec *spec = codec->spec; |
5807 | struct auto_pin_cfg *cfg = &spec->autocfg; | 5831 | const struct hda_input_mux *imux; |
5808 | hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)]; | 5832 | hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)]; |
5809 | hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)]; | 5833 | hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)]; |
5810 | int i, n, nums; | 5834 | int i, n, nums; |
5811 | 5835 | ||
5836 | imux = spec->input_mux; | ||
5837 | if (!imux) | ||
5838 | return; | ||
5839 | if (spec->dyn_adc_switch) | ||
5840 | return; | ||
5841 | |||
5812 | nums = 0; | 5842 | nums = 0; |
5813 | for (n = 0; n < spec->num_adc_nids; n++) { | 5843 | for (n = 0; n < spec->num_adc_nids; n++) { |
5814 | hda_nid_t cap = spec->private_capsrc_nids[n]; | 5844 | hda_nid_t cap = spec->private_capsrc_nids[n]; |
5815 | for (i = 0; i < cfg->num_inputs; i++) { | 5845 | int num_conns = snd_hda_get_conn_list(codec, cap, NULL); |
5816 | hda_nid_t pin = cfg->inputs[i].pin; | 5846 | for (i = 0; i < imux->num_items; i++) { |
5817 | if (get_connection_index(codec, cap, pin) < 0) | 5847 | hda_nid_t pin = spec->imux_pins[i]; |
5848 | if (pin) { | ||
5849 | if (get_connection_index(codec, cap, pin) < 0) | ||
5850 | break; | ||
5851 | } else if (num_conns <= imux->items[i].index) | ||
5818 | break; | 5852 | break; |
5819 | } | 5853 | } |
5820 | if (i >= cfg->num_inputs) { | 5854 | if (i >= imux->num_items) { |
5821 | adc_nids[nums] = spec->private_adc_nids[n]; | 5855 | adc_nids[nums] = spec->private_adc_nids[n]; |
5822 | capsrc_nids[nums++] = cap; | 5856 | capsrc_nids[nums++] = cap; |
5823 | } | 5857 | } |
5824 | } | 5858 | } |
5825 | if (!nums) { | 5859 | if (!nums) { |
5826 | printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" | 5860 | /* check whether ADC-switch is possible */ |
5827 | " using fallback 0x%x\n", | 5861 | if (!alc_check_dyn_adc_switch(codec)) { |
5828 | codec->chip_name, spec->private_adc_nids[0]); | 5862 | printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" |
5829 | spec->num_adc_nids = 1; | 5863 | " using fallback 0x%x\n", |
5864 | codec->chip_name, spec->private_adc_nids[0]); | ||
5865 | spec->num_adc_nids = 1; | ||
5866 | spec->auto_mic = 0; | ||
5867 | return; | ||
5868 | } | ||
5830 | } else if (nums != spec->num_adc_nids) { | 5869 | } else if (nums != spec->num_adc_nids) { |
5831 | memcpy(spec->private_adc_nids, adc_nids, | 5870 | memcpy(spec->private_adc_nids, adc_nids, |
5832 | nums * sizeof(hda_nid_t)); | 5871 | nums * sizeof(hda_nid_t)); |
@@ -5834,6 +5873,11 @@ static void alc_remove_invalid_adc_nids(struct hda_codec *codec) | |||
5834 | nums * sizeof(hda_nid_t)); | 5873 | nums * sizeof(hda_nid_t)); |
5835 | spec->num_adc_nids = nums; | 5874 | spec->num_adc_nids = nums; |
5836 | } | 5875 | } |
5876 | |||
5877 | if (spec->auto_mic) | ||
5878 | alc_auto_mic_check_imux(codec); /* check auto-mic setups */ | ||
5879 | else if (spec->input_mux->num_items == 1) | ||
5880 | spec->num_adc_nids = 1; /* reduce to a single ADC */ | ||
5837 | } | 5881 | } |
5838 | 5882 | ||
5839 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 5883 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
@@ -5915,6 +5959,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
5915 | 5959 | ||
5916 | if (!spec->adc_nids && spec->input_mux) { | 5960 | if (!spec->adc_nids && spec->input_mux) { |
5917 | alc_auto_fill_adc_caps(codec); | 5961 | alc_auto_fill_adc_caps(codec); |
5962 | alc_rebuild_imux_for_auto_mic(codec); | ||
5918 | alc_remove_invalid_adc_nids(codec); | 5963 | alc_remove_invalid_adc_nids(codec); |
5919 | } | 5964 | } |
5920 | set_capture_mixer(codec); | 5965 | set_capture_mixer(codec); |
@@ -7160,13 +7205,10 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
7160 | if (spec->kctls.list) | 7205 | if (spec->kctls.list) |
7161 | add_mixer(spec, spec->kctls.list); | 7206 | add_mixer(spec, spec->kctls.list); |
7162 | 7207 | ||
7163 | spec->num_mux_defs = 1; | 7208 | alc_remove_invalid_adc_nids(codec); |
7164 | spec->input_mux = &spec->private_imux[0]; | ||
7165 | |||
7166 | if (!spec->dual_adc_switch) | ||
7167 | alc_remove_invalid_adc_nids(codec); | ||
7168 | 7209 | ||
7169 | alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); | 7210 | alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); |
7211 | alc_auto_check_switches(codec); | ||
7170 | 7212 | ||
7171 | return 1; | 7213 | return 1; |
7172 | } | 7214 | } |
@@ -7450,6 +7492,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
7450 | 7492 | ||
7451 | if (!spec->adc_nids && spec->input_mux) { | 7493 | if (!spec->adc_nids && spec->input_mux) { |
7452 | alc_auto_fill_adc_caps(codec); | 7494 | alc_auto_fill_adc_caps(codec); |
7495 | alc_rebuild_imux_for_auto_mic(codec); | ||
7453 | alc_remove_invalid_adc_nids(codec); | 7496 | alc_remove_invalid_adc_nids(codec); |
7454 | } | 7497 | } |
7455 | set_capture_mixer(codec); | 7498 | set_capture_mixer(codec); |
@@ -9704,10 +9747,8 @@ static void alc883_mode2_setup(struct hda_codec *codec) | |||
9704 | spec->autocfg.speaker_pins[0] = 0x14; | 9747 | spec->autocfg.speaker_pins[0] = 0x14; |
9705 | spec->autocfg.speaker_pins[1] = 0x15; | 9748 | spec->autocfg.speaker_pins[1] = 0x15; |
9706 | spec->autocfg.speaker_pins[2] = 0x16; | 9749 | spec->autocfg.speaker_pins[2] = 0x16; |
9707 | spec->ext_mic.pin = 0x18; | 9750 | spec->ext_mic_pin = 0x18; |
9708 | spec->int_mic.pin = 0x19; | 9751 | spec->int_mic_pin = 0x19; |
9709 | spec->ext_mic.mux_idx = 0; | ||
9710 | spec->int_mic.mux_idx = 1; | ||
9711 | spec->auto_mic = 1; | 9752 | spec->auto_mic = 1; |
9712 | spec->automute = 1; | 9753 | spec->automute = 1; |
9713 | spec->automute_mode = ALC_AUTOMUTE_AMP; | 9754 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
@@ -10780,67 +10821,41 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
10780 | /* | 10821 | /* |
10781 | * BIOS auto configuration | 10822 | * BIOS auto configuration |
10782 | */ | 10823 | */ |
10783 | static void alc_auto_init_input_src(struct hda_codec *codec) | 10824 | static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx) |
10784 | { | 10825 | { |
10785 | struct alc_spec *spec = codec->spec; | 10826 | struct alc_spec *spec = codec->spec; |
10786 | int c; | 10827 | hda_nid_t nid; |
10787 | |||
10788 | if (spec->dual_adc_switch) | ||
10789 | return; | ||
10790 | 10828 | ||
10791 | for (c = 0; c < spec->num_adc_nids; c++) { | 10829 | nid = spec->adc_nids[adc_idx]; |
10792 | hda_nid_t nid; | 10830 | /* mute ADC */ |
10793 | unsigned int mux_idx; | 10831 | if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) { |
10794 | const struct hda_input_mux *imux; | 10832 | snd_hda_codec_write(codec, nid, 0, |
10795 | int conns, mute, idx, item; | ||
10796 | unsigned int wid_type; | ||
10797 | |||
10798 | nid = spec->capsrc_nids ? | ||
10799 | spec->capsrc_nids[c] : spec->adc_nids[c]; | ||
10800 | /* mute ADC */ | ||
10801 | if (query_amp_caps(codec, spec->adc_nids[c], HDA_INPUT) & | ||
10802 | AC_AMPCAP_MUTE) | ||
10803 | snd_hda_codec_write(codec, spec->adc_nids[c], 0, | ||
10804 | AC_VERB_SET_AMP_GAIN_MUTE, | 10833 | AC_VERB_SET_AMP_GAIN_MUTE, |
10805 | AMP_IN_MUTE(0)); | 10834 | AMP_IN_MUTE(0)); |
10806 | else if (query_amp_caps(codec, nid, HDA_OUTPUT) & | 10835 | return; |
10807 | AC_AMPCAP_MUTE) | 10836 | } |
10808 | snd_hda_codec_write(codec, nid, 0, | 10837 | if (!spec->capsrc_nids) |
10838 | return; | ||
10839 | nid = spec->capsrc_nids[adc_idx]; | ||
10840 | if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE) | ||
10841 | snd_hda_codec_write(codec, nid, 0, | ||
10809 | AC_VERB_SET_AMP_GAIN_MUTE, | 10842 | AC_VERB_SET_AMP_GAIN_MUTE, |
10810 | AMP_OUT_MUTE); | 10843 | AMP_OUT_MUTE); |
10844 | } | ||
10811 | 10845 | ||
10812 | conns = snd_hda_get_conn_list(codec, nid, NULL); | 10846 | static void alc_auto_init_input_src(struct hda_codec *codec) |
10813 | if (conns <= 0) | 10847 | { |
10814 | continue; | 10848 | struct alc_spec *spec = codec->spec; |
10815 | mux_idx = c >= spec->num_mux_defs ? 0 : c; | 10849 | int c, nums; |
10816 | imux = &spec->input_mux[mux_idx]; | 10850 | |
10817 | if (!imux->num_items && mux_idx > 0) | 10851 | for (c = 0; c < spec->num_adc_nids; c++) |
10818 | imux = &spec->input_mux[0]; | 10852 | alc_auto_init_adc(codec, c); |
10819 | wid_type = get_wcaps_type(get_wcaps(codec, nid)); | 10853 | if (spec->dyn_adc_switch) |
10820 | for (idx = 0; idx < conns; idx++) { | 10854 | nums = 1; |
10821 | /* if the current connection is the selected one, | 10855 | else |
10822 | * unmute it as default - otherwise mute it | 10856 | nums = spec->num_adc_nids; |
10823 | */ | 10857 | for (c = 0; c < nums; c++) |
10824 | mute = AMP_IN_MUTE(idx); | 10858 | alc_mux_select(codec, 0, spec->cur_mux[c], true); |
10825 | for (item = 0; item < imux->num_items; item++) { | ||
10826 | if (imux->items[item].index == idx) { | ||
10827 | if (spec->cur_mux[c] == item) | ||
10828 | mute = AMP_IN_UNMUTE(idx); | ||
10829 | break; | ||
10830 | } | ||
10831 | } | ||
10832 | /* initialize the mute status if mute-amp is present */ | ||
10833 | if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) | ||
10834 | snd_hda_codec_write(codec, nid, 0, | ||
10835 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
10836 | mute); | ||
10837 | if (wid_type == AC_WID_AUD_SEL && | ||
10838 | mute != AMP_IN_MUTE(idx)) | ||
10839 | snd_hda_codec_write(codec, nid, 0, | ||
10840 | AC_VERB_SET_CONNECT_SEL, | ||
10841 | idx); | ||
10842 | } | ||
10843 | } | ||
10844 | } | 10859 | } |
10845 | 10860 | ||
10846 | /* add mic boosts if needed */ | 10861 | /* add mic boosts if needed */ |
@@ -10920,18 +10935,15 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
10920 | if (spec->kctls.list) | 10935 | if (spec->kctls.list) |
10921 | add_mixer(spec, spec->kctls.list); | 10936 | add_mixer(spec, spec->kctls.list); |
10922 | 10937 | ||
10923 | spec->num_mux_defs = 1; | ||
10924 | spec->input_mux = &spec->private_imux[0]; | ||
10925 | |||
10926 | if (!spec->dual_adc_switch) | ||
10927 | alc_remove_invalid_adc_nids(codec); | ||
10928 | |||
10929 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | ||
10930 | |||
10931 | err = alc_auto_add_mic_boost(codec); | 10938 | err = alc_auto_add_mic_boost(codec); |
10932 | if (err < 0) | 10939 | if (err < 0) |
10933 | return err; | 10940 | return err; |
10934 | 10941 | ||
10942 | alc_remove_invalid_adc_nids(codec); | ||
10943 | |||
10944 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | ||
10945 | alc_auto_check_switches(codec); | ||
10946 | |||
10935 | return 1; /* config found */ | 10947 | return 1; /* config found */ |
10936 | } | 10948 | } |
10937 | 10949 | ||
@@ -11019,6 +11031,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
11019 | 11031 | ||
11020 | if (!spec->adc_nids && spec->input_mux) { | 11032 | if (!spec->adc_nids && spec->input_mux) { |
11021 | alc_auto_fill_adc_caps(codec); | 11033 | alc_auto_fill_adc_caps(codec); |
11034 | alc_rebuild_imux_for_auto_mic(codec); | ||
11022 | alc_remove_invalid_adc_nids(codec); | 11035 | alc_remove_invalid_adc_nids(codec); |
11023 | } | 11036 | } |
11024 | 11037 | ||
@@ -11515,10 +11528,8 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec) | |||
11515 | 11528 | ||
11516 | spec->autocfg.hp_pins[0] = 0x15; | 11529 | spec->autocfg.hp_pins[0] = 0x15; |
11517 | spec->autocfg.speaker_pins[0] = 0x14; | 11530 | spec->autocfg.speaker_pins[0] = 0x14; |
11518 | spec->ext_mic.pin = 0x18; | 11531 | spec->ext_mic_pin = 0x18; |
11519 | spec->ext_mic.mux_idx = 0; | 11532 | spec->int_mic_pin = 0x12; |
11520 | spec->int_mic.pin = 0x12; | ||
11521 | spec->int_mic.mux_idx = 9; | ||
11522 | spec->auto_mic = 1; | 11533 | spec->auto_mic = 1; |
11523 | spec->automute = 1; | 11534 | spec->automute = 1; |
11524 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 11535 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
@@ -12243,17 +12254,14 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
12243 | if (spec->kctls.list) | 12254 | if (spec->kctls.list) |
12244 | add_mixer(spec, spec->kctls.list); | 12255 | add_mixer(spec, spec->kctls.list); |
12245 | 12256 | ||
12246 | spec->num_mux_defs = 1; | ||
12247 | spec->input_mux = &spec->private_imux[0]; | ||
12248 | |||
12249 | if (!spec->dual_adc_switch) | ||
12250 | alc_remove_invalid_adc_nids(codec); | ||
12251 | |||
12252 | err = alc_auto_add_mic_boost(codec); | 12257 | err = alc_auto_add_mic_boost(codec); |
12253 | if (err < 0) | 12258 | if (err < 0) |
12254 | return err; | 12259 | return err; |
12255 | 12260 | ||
12261 | alc_remove_invalid_adc_nids(codec); | ||
12262 | |||
12256 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | 12263 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
12264 | alc_auto_check_switches(codec); | ||
12257 | 12265 | ||
12258 | return 1; | 12266 | return 1; |
12259 | } | 12267 | } |
@@ -12661,6 +12669,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
12661 | 12669 | ||
12662 | if (!spec->adc_nids && spec->input_mux) { | 12670 | if (!spec->adc_nids && spec->input_mux) { |
12663 | alc_auto_fill_adc_caps(codec); | 12671 | alc_auto_fill_adc_caps(codec); |
12672 | alc_rebuild_imux_for_auto_mic(codec); | ||
12664 | alc_remove_invalid_adc_nids(codec); | 12673 | alc_remove_invalid_adc_nids(codec); |
12665 | } | 12674 | } |
12666 | if (!spec->cap_mixer && !spec->no_analog) | 12675 | if (!spec->cap_mixer && !spec->no_analog) |
@@ -12863,10 +12872,8 @@ static void alc268_acer_lc_setup(struct hda_codec *codec) | |||
12863 | spec->autocfg.speaker_pins[0] = 0x14; | 12872 | spec->autocfg.speaker_pins[0] = 0x14; |
12864 | spec->automute = 1; | 12873 | spec->automute = 1; |
12865 | spec->automute_mode = ALC_AUTOMUTE_AMP; | 12874 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
12866 | spec->ext_mic.pin = 0x18; | 12875 | spec->ext_mic_pin = 0x18; |
12867 | spec->ext_mic.mux_idx = 0; | 12876 | spec->int_mic_pin = 0x12; |
12868 | spec->int_mic.pin = 0x12; | ||
12869 | spec->int_mic.mux_idx = 6; | ||
12870 | spec->auto_mic = 1; | 12877 | spec->auto_mic = 1; |
12871 | } | 12878 | } |
12872 | 12879 | ||
@@ -12896,10 +12903,8 @@ static void alc268_dell_setup(struct hda_codec *codec) | |||
12896 | 12903 | ||
12897 | spec->autocfg.hp_pins[0] = 0x15; | 12904 | spec->autocfg.hp_pins[0] = 0x15; |
12898 | spec->autocfg.speaker_pins[0] = 0x14; | 12905 | spec->autocfg.speaker_pins[0] = 0x14; |
12899 | spec->ext_mic.pin = 0x18; | 12906 | spec->ext_mic_pin = 0x18; |
12900 | spec->ext_mic.mux_idx = 0; | 12907 | spec->int_mic_pin = 0x19; |
12901 | spec->int_mic.pin = 0x19; | ||
12902 | spec->int_mic.mux_idx = 1; | ||
12903 | spec->auto_mic = 1; | 12908 | spec->auto_mic = 1; |
12904 | spec->automute = 1; | 12909 | spec->automute = 1; |
12905 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 12910 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
@@ -12928,10 +12933,8 @@ static void alc267_quanta_il1_setup(struct hda_codec *codec) | |||
12928 | struct alc_spec *spec = codec->spec; | 12933 | struct alc_spec *spec = codec->spec; |
12929 | spec->autocfg.hp_pins[0] = 0x15; | 12934 | spec->autocfg.hp_pins[0] = 0x15; |
12930 | spec->autocfg.speaker_pins[0] = 0x14; | 12935 | spec->autocfg.speaker_pins[0] = 0x14; |
12931 | spec->ext_mic.pin = 0x18; | 12936 | spec->ext_mic_pin = 0x18; |
12932 | spec->ext_mic.mux_idx = 0; | 12937 | spec->int_mic_pin = 0x19; |
12933 | spec->int_mic.pin = 0x19; | ||
12934 | spec->int_mic.mux_idx = 1; | ||
12935 | spec->auto_mic = 1; | 12938 | spec->auto_mic = 1; |
12936 | spec->automute = 1; | 12939 | spec->automute = 1; |
12937 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 12940 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
@@ -13358,17 +13361,14 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
13358 | add_verb(spec, alc268_beep_init_verbs); | 13361 | add_verb(spec, alc268_beep_init_verbs); |
13359 | } | 13362 | } |
13360 | 13363 | ||
13361 | spec->num_mux_defs = 1; | ||
13362 | spec->input_mux = &spec->private_imux[0]; | ||
13363 | |||
13364 | if (!spec->dual_adc_switch) | ||
13365 | alc_remove_invalid_adc_nids(codec); | ||
13366 | |||
13367 | err = alc_auto_add_mic_boost(codec); | 13364 | err = alc_auto_add_mic_boost(codec); |
13368 | if (err < 0) | 13365 | if (err < 0) |
13369 | return err; | 13366 | return err; |
13370 | 13367 | ||
13368 | alc_remove_invalid_adc_nids(codec); | ||
13369 | |||
13371 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | 13370 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
13371 | alc_auto_check_switches(codec); | ||
13372 | 13372 | ||
13373 | return 1; | 13373 | return 1; |
13374 | } | 13374 | } |
@@ -13668,6 +13668,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
13668 | 13668 | ||
13669 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 13669 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { |
13670 | alc_auto_fill_adc_caps(codec); | 13670 | alc_auto_fill_adc_caps(codec); |
13671 | alc_rebuild_imux_for_auto_mic(codec); | ||
13671 | alc_remove_invalid_adc_nids(codec); | 13672 | alc_remove_invalid_adc_nids(codec); |
13672 | } | 13673 | } |
13673 | 13674 | ||
@@ -13924,10 +13925,8 @@ static void alc269_quanta_fl1_setup(struct hda_codec *codec) | |||
13924 | spec->automute_mixer_nid[0] = 0x0c; | 13925 | spec->automute_mixer_nid[0] = 0x0c; |
13925 | spec->automute = 1; | 13926 | spec->automute = 1; |
13926 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 13927 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
13927 | spec->ext_mic.pin = 0x18; | 13928 | spec->ext_mic_pin = 0x18; |
13928 | spec->ext_mic.mux_idx = 0; | 13929 | spec->int_mic_pin = 0x19; |
13929 | spec->int_mic.pin = 0x19; | ||
13930 | spec->int_mic.mux_idx = 1; | ||
13931 | spec->auto_mic = 1; | 13930 | spec->auto_mic = 1; |
13932 | } | 13931 | } |
13933 | 13932 | ||
@@ -14019,10 +14018,8 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec) | |||
14019 | spec->automute_mixer_nid[0] = 0x0c; | 14018 | spec->automute_mixer_nid[0] = 0x0c; |
14020 | spec->automute = 1; | 14019 | spec->automute = 1; |
14021 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 14020 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
14022 | spec->ext_mic.pin = 0x18; | 14021 | spec->ext_mic_pin = 0x18; |
14023 | spec->ext_mic.mux_idx = 0; | 14022 | spec->int_mic_pin = 0x19; |
14024 | spec->int_mic.pin = 0x19; | ||
14025 | spec->int_mic.mux_idx = 1; | ||
14026 | spec->auto_mic = 1; | 14023 | spec->auto_mic = 1; |
14027 | } | 14024 | } |
14028 | 14025 | ||
@@ -14034,10 +14031,8 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec) | |||
14034 | spec->automute_mixer_nid[0] = 0x0c; | 14031 | spec->automute_mixer_nid[0] = 0x0c; |
14035 | spec->automute = 1; | 14032 | spec->automute = 1; |
14036 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 14033 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
14037 | spec->ext_mic.pin = 0x18; | 14034 | spec->ext_mic_pin = 0x18; |
14038 | spec->ext_mic.mux_idx = 0; | 14035 | spec->int_mic_pin = 0x12; |
14039 | spec->int_mic.pin = 0x12; | ||
14040 | spec->int_mic.mux_idx = 5; | ||
14041 | spec->auto_mic = 1; | 14036 | spec->auto_mic = 1; |
14042 | } | 14037 | } |
14043 | 14038 | ||
@@ -14049,10 +14044,8 @@ static void alc269vb_laptop_amic_setup(struct hda_codec *codec) | |||
14049 | spec->automute_mixer_nid[0] = 0x0c; | 14044 | spec->automute_mixer_nid[0] = 0x0c; |
14050 | spec->automute = 1; | 14045 | spec->automute = 1; |
14051 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 14046 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
14052 | spec->ext_mic.pin = 0x18; | 14047 | spec->ext_mic_pin = 0x18; |
14053 | spec->ext_mic.mux_idx = 0; | 14048 | spec->int_mic_pin = 0x19; |
14054 | spec->int_mic.pin = 0x19; | ||
14055 | spec->int_mic.mux_idx = 1; | ||
14056 | spec->auto_mic = 1; | 14049 | spec->auto_mic = 1; |
14057 | } | 14050 | } |
14058 | 14051 | ||
@@ -14064,10 +14057,8 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | |||
14064 | spec->automute_mixer_nid[0] = 0x0c; | 14057 | spec->automute_mixer_nid[0] = 0x0c; |
14065 | spec->automute = 1; | 14058 | spec->automute = 1; |
14066 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 14059 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
14067 | spec->ext_mic.pin = 0x18; | 14060 | spec->ext_mic_pin = 0x18; |
14068 | spec->ext_mic.mux_idx = 0; | 14061 | spec->int_mic_pin = 0x12; |
14069 | spec->int_mic.pin = 0x12; | ||
14070 | spec->int_mic.mux_idx = 6; | ||
14071 | spec->auto_mic = 1; | 14062 | spec->auto_mic = 1; |
14072 | } | 14063 | } |
14073 | 14064 | ||
@@ -14217,36 +14208,6 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) | |||
14217 | } | 14208 | } |
14218 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | 14209 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ |
14219 | 14210 | ||
14220 | static int alc275_setup_dual_adc(struct hda_codec *codec) | ||
14221 | { | ||
14222 | struct alc_spec *spec = codec->spec; | ||
14223 | |||
14224 | if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) | ||
14225 | return 0; | ||
14226 | if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || | ||
14227 | (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { | ||
14228 | if (spec->ext_mic.pin <= 0x12) { | ||
14229 | spec->private_adc_nids[0] = 0x08; | ||
14230 | spec->private_adc_nids[1] = 0x11; | ||
14231 | spec->private_capsrc_nids[0] = 0x23; | ||
14232 | spec->private_capsrc_nids[1] = 0x22; | ||
14233 | } else { | ||
14234 | spec->private_adc_nids[0] = 0x11; | ||
14235 | spec->private_adc_nids[1] = 0x08; | ||
14236 | spec->private_capsrc_nids[0] = 0x22; | ||
14237 | spec->private_capsrc_nids[1] = 0x23; | ||
14238 | } | ||
14239 | spec->adc_nids = spec->private_adc_nids; | ||
14240 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
14241 | spec->num_adc_nids = 2; | ||
14242 | spec->dual_adc_switch = 1; | ||
14243 | snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", | ||
14244 | spec->adc_nids[0], spec->adc_nids[1]); | ||
14245 | return 1; | ||
14246 | } | ||
14247 | return 0; | ||
14248 | } | ||
14249 | |||
14250 | /* different alc269-variants */ | 14211 | /* different alc269-variants */ |
14251 | enum { | 14212 | enum { |
14252 | ALC269_TYPE_ALC269VA, | 14213 | ALC269_TYPE_ALC269VA, |
@@ -14282,17 +14243,13 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14282 | if (spec->kctls.list) | 14243 | if (spec->kctls.list) |
14283 | add_mixer(spec, spec->kctls.list); | 14244 | add_mixer(spec, spec->kctls.list); |
14284 | 14245 | ||
14246 | alc_remove_invalid_adc_nids(codec); | ||
14247 | |||
14285 | if (spec->codec_variant != ALC269_TYPE_ALC269VA) | 14248 | if (spec->codec_variant != ALC269_TYPE_ALC269VA) |
14286 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); | 14249 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); |
14287 | else | 14250 | else |
14288 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | 14251 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
14289 | 14252 | alc_auto_check_switches(codec); | |
14290 | spec->num_mux_defs = 1; | ||
14291 | spec->input_mux = &spec->private_imux[0]; | ||
14292 | |||
14293 | alc275_setup_dual_adc(codec); | ||
14294 | if (!spec->dual_adc_switch) | ||
14295 | alc_remove_invalid_adc_nids(codec); | ||
14296 | 14253 | ||
14297 | err = alc_auto_add_mic_boost(codec); | 14254 | err = alc_auto_add_mic_boost(codec); |
14298 | if (err < 0) | 14255 | if (err < 0) |
@@ -14819,6 +14776,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
14819 | 14776 | ||
14820 | if (!spec->adc_nids) { /* wasn't filled automatically? use default */ | 14777 | if (!spec->adc_nids) { /* wasn't filled automatically? use default */ |
14821 | alc_auto_fill_adc_caps(codec); | 14778 | alc_auto_fill_adc_caps(codec); |
14779 | alc_rebuild_imux_for_auto_mic(codec); | ||
14822 | alc_remove_invalid_adc_nids(codec); | 14780 | alc_remove_invalid_adc_nids(codec); |
14823 | } | 14781 | } |
14824 | 14782 | ||
@@ -15616,13 +15574,10 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
15616 | if (spec->kctls.list) | 15574 | if (spec->kctls.list) |
15617 | add_mixer(spec, spec->kctls.list); | 15575 | add_mixer(spec, spec->kctls.list); |
15618 | 15576 | ||
15619 | spec->num_mux_defs = 1; | 15577 | alc_remove_invalid_adc_nids(codec); |
15620 | spec->input_mux = &spec->private_imux[0]; | ||
15621 | |||
15622 | if (!spec->dual_adc_switch) | ||
15623 | alc_remove_invalid_adc_nids(codec); | ||
15624 | 15578 | ||
15625 | alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); | 15579 | alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); |
15580 | alc_auto_check_switches(codec); | ||
15626 | 15581 | ||
15627 | set_capture_mixer(codec); | 15582 | set_capture_mixer(codec); |
15628 | 15583 | ||
@@ -15871,6 +15826,12 @@ static int patch_alc861(struct hda_codec *codec) | |||
15871 | if (board_config != ALC861_AUTO) | 15826 | if (board_config != ALC861_AUTO) |
15872 | setup_preset(codec, &alc861_presets[board_config]); | 15827 | setup_preset(codec, &alc861_presets[board_config]); |
15873 | 15828 | ||
15829 | if (!spec->adc_nids) { | ||
15830 | alc_auto_fill_adc_caps(codec); | ||
15831 | alc_rebuild_imux_for_auto_mic(codec); | ||
15832 | alc_remove_invalid_adc_nids(codec); | ||
15833 | } | ||
15834 | |||
15874 | if (!spec->cap_mixer) | 15835 | if (!spec->cap_mixer) |
15875 | set_capture_mixer(codec); | 15836 | set_capture_mixer(codec); |
15876 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 15837 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
@@ -16664,18 +16625,15 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
16664 | if (spec->kctls.list) | 16625 | if (spec->kctls.list) |
16665 | add_mixer(spec, spec->kctls.list); | 16626 | add_mixer(spec, spec->kctls.list); |
16666 | 16627 | ||
16667 | spec->num_mux_defs = 1; | 16628 | alc_remove_invalid_adc_nids(codec); |
16668 | spec->input_mux = &spec->private_imux[0]; | ||
16669 | 16629 | ||
16670 | if (!spec->dual_adc_switch) | 16630 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
16671 | alc_remove_invalid_adc_nids(codec); | 16631 | alc_auto_check_switches(codec); |
16672 | 16632 | ||
16673 | err = alc_auto_add_mic_boost(codec); | 16633 | err = alc_auto_add_mic_boost(codec); |
16674 | if (err < 0) | 16634 | if (err < 0) |
16675 | return err; | 16635 | return err; |
16676 | 16636 | ||
16677 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | ||
16678 | |||
16679 | return 1; | 16637 | return 1; |
16680 | } | 16638 | } |
16681 | 16639 | ||
@@ -16772,6 +16730,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
16772 | 16730 | ||
16773 | if (!spec->adc_nids) { | 16731 | if (!spec->adc_nids) { |
16774 | alc_auto_fill_adc_caps(codec); | 16732 | alc_auto_fill_adc_caps(codec); |
16733 | alc_rebuild_imux_for_auto_mic(codec); | ||
16775 | alc_remove_invalid_adc_nids(codec); | 16734 | alc_remove_invalid_adc_nids(codec); |
16776 | } | 16735 | } |
16777 | 16736 | ||
@@ -17539,10 +17498,8 @@ static void alc662_eeepc_setup(struct hda_codec *codec) | |||
17539 | struct alc_spec *spec = codec->spec; | 17498 | struct alc_spec *spec = codec->spec; |
17540 | 17499 | ||
17541 | alc262_hippo1_setup(codec); | 17500 | alc262_hippo1_setup(codec); |
17542 | spec->ext_mic.pin = 0x18; | 17501 | spec->ext_mic_pin = 0x18; |
17543 | spec->ext_mic.mux_idx = 0; | 17502 | spec->int_mic_pin = 0x19; |
17544 | spec->int_mic.pin = 0x19; | ||
17545 | spec->int_mic.mux_idx = 1; | ||
17546 | spec->auto_mic = 1; | 17503 | spec->auto_mic = 1; |
17547 | } | 17504 | } |
17548 | 17505 | ||
@@ -17564,10 +17521,8 @@ static void alc663_m51va_setup(struct hda_codec *codec) | |||
17564 | spec->automute_mixer_nid[0] = 0x0c; | 17521 | spec->automute_mixer_nid[0] = 0x0c; |
17565 | spec->automute = 1; | 17522 | spec->automute = 1; |
17566 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 17523 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
17567 | spec->ext_mic.pin = 0x18; | 17524 | spec->ext_mic_pin = 0x18; |
17568 | spec->ext_mic.mux_idx = 0; | 17525 | spec->int_mic_pin = 0x12; |
17569 | spec->int_mic.pin = 0x12; | ||
17570 | spec->int_mic.mux_idx = 9; | ||
17571 | spec->auto_mic = 1; | 17526 | spec->auto_mic = 1; |
17572 | } | 17527 | } |
17573 | 17528 | ||
@@ -17580,10 +17535,8 @@ static void alc663_mode1_setup(struct hda_codec *codec) | |||
17580 | spec->automute_mixer_nid[0] = 0x0c; | 17535 | spec->automute_mixer_nid[0] = 0x0c; |
17581 | spec->automute = 1; | 17536 | spec->automute = 1; |
17582 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 17537 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
17583 | spec->ext_mic.pin = 0x18; | 17538 | spec->ext_mic_pin = 0x18; |
17584 | spec->ext_mic.mux_idx = 0; | 17539 | spec->int_mic_pin = 0x19; |
17585 | spec->int_mic.pin = 0x19; | ||
17586 | spec->int_mic.mux_idx = 1; | ||
17587 | spec->auto_mic = 1; | 17540 | spec->auto_mic = 1; |
17588 | } | 17541 | } |
17589 | 17542 | ||
@@ -17595,10 +17548,8 @@ static void alc662_mode2_setup(struct hda_codec *codec) | |||
17595 | spec->autocfg.speaker_pins[0] = 0x14; | 17548 | spec->autocfg.speaker_pins[0] = 0x14; |
17596 | spec->automute = 1; | 17549 | spec->automute = 1; |
17597 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 17550 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
17598 | spec->ext_mic.pin = 0x18; | 17551 | spec->ext_mic_pin = 0x18; |
17599 | spec->ext_mic.mux_idx = 0; | 17552 | spec->int_mic_pin = 0x19; |
17600 | spec->int_mic.pin = 0x19; | ||
17601 | spec->int_mic.mux_idx = 1; | ||
17602 | spec->auto_mic = 1; | 17553 | spec->auto_mic = 1; |
17603 | } | 17554 | } |
17604 | 17555 | ||
@@ -17611,10 +17562,8 @@ static void alc663_mode3_setup(struct hda_codec *codec) | |||
17611 | spec->autocfg.speaker_pins[0] = 0x14; | 17562 | spec->autocfg.speaker_pins[0] = 0x14; |
17612 | spec->automute = 1; | 17563 | spec->automute = 1; |
17613 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 17564 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
17614 | spec->ext_mic.pin = 0x18; | 17565 | spec->ext_mic_pin = 0x18; |
17615 | spec->ext_mic.mux_idx = 0; | 17566 | spec->int_mic_pin = 0x19; |
17616 | spec->int_mic.pin = 0x19; | ||
17617 | spec->int_mic.mux_idx = 1; | ||
17618 | spec->auto_mic = 1; | 17567 | spec->auto_mic = 1; |
17619 | } | 17568 | } |
17620 | 17569 | ||
@@ -17629,10 +17578,8 @@ static void alc663_mode4_setup(struct hda_codec *codec) | |||
17629 | spec->automute_mixer_nid[1] = 0x0e; | 17578 | spec->automute_mixer_nid[1] = 0x0e; |
17630 | spec->automute = 1; | 17579 | spec->automute = 1; |
17631 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 17580 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
17632 | spec->ext_mic.pin = 0x18; | 17581 | spec->ext_mic_pin = 0x18; |
17633 | spec->ext_mic.mux_idx = 0; | 17582 | spec->int_mic_pin = 0x19; |
17634 | spec->int_mic.pin = 0x19; | ||
17635 | spec->int_mic.mux_idx = 1; | ||
17636 | spec->auto_mic = 1; | 17583 | spec->auto_mic = 1; |
17637 | } | 17584 | } |
17638 | 17585 | ||
@@ -17647,10 +17594,8 @@ static void alc663_mode5_setup(struct hda_codec *codec) | |||
17647 | spec->automute_mixer_nid[1] = 0x0e; | 17594 | spec->automute_mixer_nid[1] = 0x0e; |
17648 | spec->automute = 1; | 17595 | spec->automute = 1; |
17649 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 17596 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
17650 | spec->ext_mic.pin = 0x18; | 17597 | spec->ext_mic_pin = 0x18; |
17651 | spec->ext_mic.mux_idx = 0; | 17598 | spec->int_mic_pin = 0x19; |
17652 | spec->int_mic.pin = 0x19; | ||
17653 | spec->int_mic.mux_idx = 1; | ||
17654 | spec->auto_mic = 1; | 17599 | spec->auto_mic = 1; |
17655 | } | 17600 | } |
17656 | 17601 | ||
@@ -17664,10 +17609,8 @@ static void alc663_mode6_setup(struct hda_codec *codec) | |||
17664 | spec->automute_mixer_nid[0] = 0x0c; | 17609 | spec->automute_mixer_nid[0] = 0x0c; |
17665 | spec->automute = 1; | 17610 | spec->automute = 1; |
17666 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | 17611 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
17667 | spec->ext_mic.pin = 0x18; | 17612 | spec->ext_mic_pin = 0x18; |
17668 | spec->ext_mic.mux_idx = 0; | 17613 | spec->int_mic_pin = 0x19; |
17669 | spec->int_mic.pin = 0x19; | ||
17670 | spec->int_mic.mux_idx = 1; | ||
17671 | spec->auto_mic = 1; | 17614 | spec->auto_mic = 1; |
17672 | } | 17615 | } |
17673 | 17616 | ||
@@ -17681,10 +17624,8 @@ static void alc663_mode7_setup(struct hda_codec *codec) | |||
17681 | spec->autocfg.speaker_pins[0] = 0x17; | 17624 | spec->autocfg.speaker_pins[0] = 0x17; |
17682 | spec->automute = 1; | 17625 | spec->automute = 1; |
17683 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 17626 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
17684 | spec->ext_mic.pin = 0x18; | 17627 | spec->ext_mic_pin = 0x18; |
17685 | spec->ext_mic.mux_idx = 0; | 17628 | spec->int_mic_pin = 0x19; |
17686 | spec->int_mic.pin = 0x19; | ||
17687 | spec->int_mic.mux_idx = 1; | ||
17688 | spec->auto_mic = 1; | 17629 | spec->auto_mic = 1; |
17689 | } | 17630 | } |
17690 | 17631 | ||
@@ -17698,10 +17639,8 @@ static void alc663_mode8_setup(struct hda_codec *codec) | |||
17698 | spec->autocfg.speaker_pins[0] = 0x17; | 17639 | spec->autocfg.speaker_pins[0] = 0x17; |
17699 | spec->automute = 1; | 17640 | spec->automute = 1; |
17700 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 17641 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
17701 | spec->ext_mic.pin = 0x18; | 17642 | spec->ext_mic_pin = 0x18; |
17702 | spec->ext_mic.mux_idx = 0; | 17643 | spec->int_mic_pin = 0x12; |
17703 | spec->int_mic.pin = 0x12; | ||
17704 | spec->int_mic.mux_idx = 9; | ||
17705 | spec->auto_mic = 1; | 17644 | spec->auto_mic = 1; |
17706 | } | 17645 | } |
17707 | 17646 | ||
@@ -17715,10 +17654,8 @@ static void alc663_g71v_setup(struct hda_codec *codec) | |||
17715 | spec->automute_mode = ALC_AUTOMUTE_AMP; | 17654 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
17716 | spec->detect_line = 1; | 17655 | spec->detect_line = 1; |
17717 | spec->automute_lines = 1; | 17656 | spec->automute_lines = 1; |
17718 | spec->ext_mic.pin = 0x18; | 17657 | spec->ext_mic_pin = 0x18; |
17719 | spec->ext_mic.mux_idx = 0; | 17658 | spec->int_mic_pin = 0x12; |
17720 | spec->int_mic.pin = 0x12; | ||
17721 | spec->int_mic.mux_idx = 9; | ||
17722 | spec->auto_mic = 1; | 17659 | spec->auto_mic = 1; |
17723 | } | 17660 | } |
17724 | 17661 | ||
@@ -18779,21 +18716,18 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
18779 | if (spec->kctls.list) | 18716 | if (spec->kctls.list) |
18780 | add_mixer(spec, spec->kctls.list); | 18717 | add_mixer(spec, spec->kctls.list); |
18781 | 18718 | ||
18782 | spec->num_mux_defs = 1; | 18719 | alc_remove_invalid_adc_nids(codec); |
18783 | spec->input_mux = &spec->private_imux[0]; | ||
18784 | |||
18785 | if (!spec->dual_adc_switch) | ||
18786 | alc_remove_invalid_adc_nids(codec); | ||
18787 | |||
18788 | err = alc_auto_add_mic_boost(codec); | ||
18789 | if (err < 0) | ||
18790 | return err; | ||
18791 | 18720 | ||
18792 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || | 18721 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || |
18793 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) | 18722 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) |
18794 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); | 18723 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); |
18795 | else | 18724 | else |
18796 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | 18725 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
18726 | alc_auto_check_switches(codec); | ||
18727 | |||
18728 | err = alc_auto_add_mic_boost(codec); | ||
18729 | if (err < 0) | ||
18730 | return err; | ||
18797 | 18731 | ||
18798 | return 1; | 18732 | return 1; |
18799 | } | 18733 | } |
@@ -18949,6 +18883,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
18949 | 18883 | ||
18950 | if (!spec->adc_nids) { | 18884 | if (!spec->adc_nids) { |
18951 | alc_auto_fill_adc_caps(codec); | 18885 | alc_auto_fill_adc_caps(codec); |
18886 | alc_rebuild_imux_for_auto_mic(codec); | ||
18952 | alc_remove_invalid_adc_nids(codec); | 18887 | alc_remove_invalid_adc_nids(codec); |
18953 | } | 18888 | } |
18954 | 18889 | ||
@@ -19036,36 +18971,32 @@ static const hda_nid_t alc680_adc_nids[3] = { | |||
19036 | /* | 18971 | /* |
19037 | * Analog capture ADC cgange | 18972 | * Analog capture ADC cgange |
19038 | */ | 18973 | */ |
19039 | static void alc680_rec_autoswitch(struct hda_codec *codec) | 18974 | static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec) |
19040 | { | 18975 | { |
19041 | struct alc_spec *spec = codec->spec; | 18976 | static hda_nid_t pins[] = {0x18, 0x19}; |
19042 | struct auto_pin_cfg *cfg = &spec->autocfg; | 18977 | static hda_nid_t adcs[] = {0x08, 0x09}; |
19043 | int pin_found = 0; | ||
19044 | int type_found = AUTO_PIN_LAST; | ||
19045 | hda_nid_t nid; | ||
19046 | int i; | 18978 | int i; |
19047 | 18979 | ||
19048 | for (i = 0; i < cfg->num_inputs; i++) { | 18980 | for (i = 0; i < ARRAY_SIZE(pins); i++) { |
19049 | nid = cfg->inputs[i].pin; | 18981 | if (!is_jack_detectable(codec, pins[i])) |
19050 | if (!is_jack_detectable(codec, nid)) | ||
19051 | continue; | 18982 | continue; |
19052 | if (snd_hda_jack_detect(codec, nid)) { | 18983 | if (snd_hda_jack_detect(codec, pins[i])) |
19053 | if (cfg->inputs[i].type < type_found) { | 18984 | return adcs[i]; |
19054 | type_found = cfg->inputs[i].type; | ||
19055 | pin_found = nid; | ||
19056 | } | ||
19057 | } | ||
19058 | } | 18985 | } |
18986 | return 0x07; | ||
18987 | } | ||
19059 | 18988 | ||
19060 | nid = 0x07; | 18989 | static void alc680_rec_autoswitch(struct hda_codec *codec) |
19061 | if (pin_found) | 18990 | { |
19062 | snd_hda_get_connections(codec, pin_found, &nid, 1); | 18991 | struct alc_spec *spec = codec->spec; |
19063 | 18992 | hda_nid_t nid = alc680_get_cur_adc(codec); | |
19064 | if (nid != spec->cur_adc) | 18993 | if (spec->cur_adc && nid != spec->cur_adc) { |
19065 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | 18994 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); |
19066 | spec->cur_adc = nid; | 18995 | spec->cur_adc = nid; |
19067 | snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0, | 18996 | snd_hda_codec_setup_stream(codec, nid, |
19068 | spec->cur_adc_format); | 18997 | spec->cur_adc_stream_tag, 0, |
18998 | spec->cur_adc_format); | ||
18999 | } | ||
19069 | } | 19000 | } |
19070 | 19001 | ||
19071 | static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | 19002 | static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, |
@@ -19075,12 +19006,12 @@ static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
19075 | struct snd_pcm_substream *substream) | 19006 | struct snd_pcm_substream *substream) |
19076 | { | 19007 | { |
19077 | struct alc_spec *spec = codec->spec; | 19008 | struct alc_spec *spec = codec->spec; |
19009 | hda_nid_t nid = alc680_get_cur_adc(codec); | ||
19078 | 19010 | ||
19079 | spec->cur_adc = 0x07; | 19011 | spec->cur_adc = nid; |
19080 | spec->cur_adc_stream_tag = stream_tag; | 19012 | spec->cur_adc_stream_tag = stream_tag; |
19081 | spec->cur_adc_format = format; | 19013 | spec->cur_adc_format = format; |
19082 | 19014 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | |
19083 | alc680_rec_autoswitch(codec); | ||
19084 | return 0; | 19015 | return 0; |
19085 | } | 19016 | } |
19086 | 19017 | ||
@@ -19088,9 +19019,9 @@ static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
19088 | struct hda_codec *codec, | 19019 | struct hda_codec *codec, |
19089 | struct snd_pcm_substream *substream) | 19020 | struct snd_pcm_substream *substream) |
19090 | { | 19021 | { |
19091 | snd_hda_codec_cleanup_stream(codec, 0x07); | 19022 | struct alc_spec *spec = codec->spec; |
19092 | snd_hda_codec_cleanup_stream(codec, 0x08); | 19023 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); |
19093 | snd_hda_codec_cleanup_stream(codec, 0x09); | 19024 | spec->cur_adc = 0; |
19094 | return 0; | 19025 | return 0; |
19095 | } | 19026 | } |
19096 | 19027 | ||
@@ -19332,6 +19263,10 @@ static int alc680_parse_auto_config(struct hda_codec *codec) | |||
19332 | if (err < 0) | 19263 | if (err < 0) |
19333 | return err; | 19264 | return err; |
19334 | 19265 | ||
19266 | err = alc_auto_create_input_ctls(codec); | ||
19267 | if (err < 0) | ||
19268 | return err; | ||
19269 | |||
19335 | spec->multiout.max_channels = 2; | 19270 | spec->multiout.max_channels = 2; |
19336 | 19271 | ||
19337 | dig_only: | 19272 | dig_only: |
@@ -19340,6 +19275,10 @@ static int alc680_parse_auto_config(struct hda_codec *codec) | |||
19340 | if (spec->kctls.list) | 19275 | if (spec->kctls.list) |
19341 | add_mixer(spec, spec->kctls.list); | 19276 | add_mixer(spec, spec->kctls.list); |
19342 | 19277 | ||
19278 | alc_remove_invalid_adc_nids(codec); | ||
19279 | |||
19280 | alc_auto_check_switches(codec); | ||
19281 | |||
19343 | err = alc_auto_add_mic_boost(codec); | 19282 | err = alc_auto_add_mic_boost(codec); |
19344 | if (err < 0) | 19283 | if (err < 0) |
19345 | return err; | 19284 | return err; |
@@ -19354,6 +19293,7 @@ static void alc680_auto_init(struct hda_codec *codec) | |||
19354 | alc680_auto_init_multi_out(codec); | 19293 | alc680_auto_init_multi_out(codec); |
19355 | alc680_auto_init_hp_out(codec); | 19294 | alc680_auto_init_hp_out(codec); |
19356 | alc_auto_init_analog_input(codec); | 19295 | alc_auto_init_analog_input(codec); |
19296 | alc_auto_init_input_src(codec); | ||
19357 | alc_auto_init_digital(codec); | 19297 | alc_auto_init_digital(codec); |
19358 | if (spec->unsol_event) | 19298 | if (spec->unsol_event) |
19359 | alc_inithook(codec); | 19299 | alc_inithook(codec); |
@@ -19427,11 +19367,14 @@ static int patch_alc680(struct hda_codec *codec) | |||
19427 | } | 19367 | } |
19428 | } | 19368 | } |
19429 | 19369 | ||
19430 | if (board_config != ALC680_AUTO) | 19370 | if (board_config != ALC680_AUTO) { |
19431 | setup_preset(codec, &alc680_presets[board_config]); | 19371 | setup_preset(codec, &alc680_presets[board_config]); |
19372 | spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; | ||
19373 | } | ||
19432 | 19374 | ||
19433 | if (!spec->adc_nids) { | 19375 | if (!spec->adc_nids) { |
19434 | alc_auto_fill_adc_caps(codec); | 19376 | alc_auto_fill_adc_caps(codec); |
19377 | alc_rebuild_imux_for_auto_mic(codec); | ||
19435 | alc_remove_invalid_adc_nids(codec); | 19378 | alc_remove_invalid_adc_nids(codec); |
19436 | } | 19379 | } |
19437 | 19380 | ||