diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 997 |
1 files changed, 374 insertions, 623 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1ec14ac24232..3ee2be544f4d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -278,6 +278,11 @@ static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, | |||
278 | #define nid_has_volume(codec, nid, dir) \ | 278 | #define nid_has_volume(codec, nid, dir) \ |
279 | check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) | 279 | check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS) |
280 | 280 | ||
281 | static struct nid_path * | ||
282 | get_nid_path(struct hda_codec *codec, hda_nid_t from_nid, hda_nid_t to_nid); | ||
283 | static void activate_path(struct hda_codec *codec, struct nid_path *path, | ||
284 | bool enable, bool add_aamix); | ||
285 | |||
281 | /* | 286 | /* |
282 | * input MUX handling | 287 | * input MUX handling |
283 | */ | 288 | */ |
@@ -286,12 +291,7 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, | |||
286 | { | 291 | { |
287 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 292 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
288 | struct alc_spec *spec = codec->spec; | 293 | struct alc_spec *spec = codec->spec; |
289 | unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); | 294 | return snd_hda_input_mux_info(&spec->input_mux[0], uinfo); |
290 | if (mux_idx >= spec->num_mux_defs) | ||
291 | mux_idx = 0; | ||
292 | if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) | ||
293 | mux_idx = 0; | ||
294 | return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); | ||
295 | } | 295 | } |
296 | 296 | ||
297 | static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, | 297 | static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, |
@@ -305,6 +305,14 @@ static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, | |||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
308 | static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx) | ||
309 | { | ||
310 | struct alc_spec *spec = codec->spec; | ||
311 | if (spec->dyn_adc_switch) | ||
312 | adc_idx = spec->dyn_adc_idx[imux_idx]; | ||
313 | return spec->adc_nids[adc_idx]; | ||
314 | } | ||
315 | |||
308 | static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) | 316 | static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) |
309 | { | 317 | { |
310 | struct alc_spec *spec = codec->spec; | 318 | struct alc_spec *spec = codec->spec; |
@@ -322,14 +330,9 @@ static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) | |||
322 | return false; | 330 | return false; |
323 | } | 331 | } |
324 | 332 | ||
325 | static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) | ||
326 | { | ||
327 | return spec->capsrc_nids ? | ||
328 | spec->capsrc_nids[idx] : spec->adc_nids[idx]; | ||
329 | } | ||
330 | |||
331 | static void call_update_outputs(struct hda_codec *codec); | 333 | static void call_update_outputs(struct hda_codec *codec); |
332 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); | 334 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); |
335 | static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx); | ||
333 | 336 | ||
334 | /* for shared I/O, change the pin-control accordingly */ | 337 | /* for shared I/O, change the pin-control accordingly */ |
335 | static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) | 338 | static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) |
@@ -369,56 +372,39 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
369 | { | 372 | { |
370 | struct alc_spec *spec = codec->spec; | 373 | struct alc_spec *spec = codec->spec; |
371 | const struct hda_input_mux *imux; | 374 | const struct hda_input_mux *imux; |
372 | unsigned int mux_idx; | 375 | struct nid_path *path; |
373 | int i, type, num_conns; | ||
374 | hda_nid_t nid; | ||
375 | |||
376 | if (!spec->input_mux) | ||
377 | return 0; | ||
378 | 376 | ||
379 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 377 | imux = spec->input_mux; |
380 | imux = &spec->input_mux[mux_idx]; | 378 | if (!imux || !imux->num_items) |
381 | if (!imux->num_items && mux_idx > 0) | ||
382 | imux = &spec->input_mux[0]; | ||
383 | if (!imux->num_items) | ||
384 | return 0; | 379 | return 0; |
385 | 380 | ||
386 | if (idx >= imux->num_items) | 381 | if (idx >= imux->num_items) |
387 | idx = imux->num_items - 1; | 382 | idx = imux->num_items - 1; |
388 | if (spec->cur_mux[adc_idx] == idx && !force) | 383 | if (spec->cur_mux[adc_idx] == idx && !force) |
389 | return 0; | 384 | return 0; |
385 | |||
386 | path = get_nid_path(codec, spec->imux_pins[spec->cur_mux[adc_idx]], | ||
387 | spec->adc_nids[adc_idx]); | ||
388 | if (!path) | ||
389 | return 0; | ||
390 | if (path->active) | ||
391 | activate_path(codec, path, false, false); | ||
392 | |||
390 | spec->cur_mux[adc_idx] = idx; | 393 | spec->cur_mux[adc_idx] = idx; |
391 | 394 | ||
392 | if (spec->shared_mic_hp) | 395 | if (spec->shared_mic_hp) |
393 | update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); | 396 | update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); |
394 | 397 | ||
395 | if (spec->dyn_adc_switch) { | 398 | if (spec->dyn_adc_switch) |
396 | alc_dyn_adc_pcm_resetup(codec, idx); | 399 | alc_dyn_adc_pcm_resetup(codec, idx); |
397 | adc_idx = spec->dyn_adc_idx[idx]; | ||
398 | } | ||
399 | |||
400 | nid = get_capsrc(spec, adc_idx); | ||
401 | 400 | ||
402 | /* no selection? */ | 401 | path = get_nid_path(codec, spec->imux_pins[idx], |
403 | num_conns = snd_hda_get_num_conns(codec, nid); | 402 | get_adc_nid(codec, adc_idx, idx)); |
404 | if (num_conns <= 1) | 403 | if (!path) |
405 | return 1; | 404 | return 0; |
406 | 405 | if (path->active) | |
407 | type = get_wcaps_type(get_wcaps(codec, nid)); | 406 | return 0; |
408 | if (type == AC_WID_AUD_MIX) { | 407 | activate_path(codec, path, true, false); |
409 | /* Matrix-mixer style (e.g. ALC882) */ | ||
410 | int active = imux->items[idx].index; | ||
411 | for (i = 0; i < num_conns; i++) { | ||
412 | unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; | ||
413 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, | ||
414 | HDA_AMP_MUTE, v); | ||
415 | } | ||
416 | } else { | ||
417 | /* MUX style (e.g. ALC880) */ | ||
418 | snd_hda_codec_write_cache(codec, nid, 0, | ||
419 | AC_VERB_SET_CONNECT_SEL, | ||
420 | imux->items[idx].index); | ||
421 | } | ||
422 | alc_inv_dmic_sync(codec, true); | 408 | alc_inv_dmic_sync(codec, true); |
423 | return 1; | 409 | return 1; |
424 | } | 410 | } |
@@ -1006,65 +992,12 @@ static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | |||
1006 | return -1; | 992 | return -1; |
1007 | } | 993 | } |
1008 | 994 | ||
1009 | /* check whether dynamic ADC-switching is available */ | ||
1010 | static bool alc_check_dyn_adc_switch(struct hda_codec *codec) | ||
1011 | { | ||
1012 | struct alc_spec *spec = codec->spec; | ||
1013 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
1014 | int i, n, idx; | ||
1015 | hda_nid_t cap, pin; | ||
1016 | |||
1017 | if (imux != spec->input_mux) /* no dynamic imux? */ | ||
1018 | return false; | ||
1019 | |||
1020 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
1021 | cap = spec->private_capsrc_nids[n]; | ||
1022 | for (i = 0; i < imux->num_items; i++) { | ||
1023 | pin = spec->imux_pins[i]; | ||
1024 | if (!pin) | ||
1025 | return false; | ||
1026 | if (get_connection_index(codec, cap, pin) < 0) | ||
1027 | break; | ||
1028 | } | ||
1029 | if (i >= imux->num_items) | ||
1030 | return true; /* no ADC-switch is needed */ | ||
1031 | } | ||
1032 | |||
1033 | for (i = 0; i < imux->num_items; i++) { | ||
1034 | pin = spec->imux_pins[i]; | ||
1035 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
1036 | cap = spec->private_capsrc_nids[n]; | ||
1037 | idx = get_connection_index(codec, cap, pin); | ||
1038 | if (idx >= 0) { | ||
1039 | imux->items[i].index = idx; | ||
1040 | spec->dyn_adc_idx[i] = n; | ||
1041 | break; | ||
1042 | } | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1046 | snd_printdd("realtek: enabling ADC switching\n"); | ||
1047 | spec->dyn_adc_switch = 1; | ||
1048 | return true; | ||
1049 | } | ||
1050 | |||
1051 | /* check whether all auto-mic pins are valid; setup indices if OK */ | 995 | /* check whether all auto-mic pins are valid; setup indices if OK */ |
1052 | static bool alc_auto_mic_check_imux(struct hda_codec *codec) | 996 | static bool alc_auto_mic_check_imux(struct hda_codec *codec) |
1053 | { | 997 | { |
1054 | struct alc_spec *spec = codec->spec; | 998 | struct alc_spec *spec = codec->spec; |
1055 | const struct hda_input_mux *imux; | 999 | const struct hda_input_mux *imux; |
1056 | 1000 | ||
1057 | if (!spec->auto_mic) | ||
1058 | return false; | ||
1059 | if (spec->auto_mic_valid_imux) | ||
1060 | return true; /* already checked */ | ||
1061 | |||
1062 | /* fill up imux indices */ | ||
1063 | if (!alc_check_dyn_adc_switch(codec)) { | ||
1064 | spec->auto_mic = 0; | ||
1065 | return false; | ||
1066 | } | ||
1067 | |||
1068 | imux = spec->input_mux; | 1001 | imux = spec->input_mux; |
1069 | spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin, | 1002 | spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin, |
1070 | spec->imux_pins, imux->num_items); | 1003 | spec->imux_pins, imux->num_items); |
@@ -1072,10 +1005,8 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec) | |||
1072 | spec->imux_pins, imux->num_items); | 1005 | spec->imux_pins, imux->num_items); |
1073 | spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin, | 1006 | spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin, |
1074 | spec->imux_pins, imux->num_items); | 1007 | spec->imux_pins, imux->num_items); |
1075 | if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) { | 1008 | if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) |
1076 | spec->auto_mic = 0; | ||
1077 | return false; /* no corresponding imux */ | 1009 | return false; /* no corresponding imux */ |
1078 | } | ||
1079 | 1010 | ||
1080 | snd_hda_jack_detect_enable_callback(codec, spec->ext_mic_pin, | 1011 | snd_hda_jack_detect_enable_callback(codec, spec->ext_mic_pin, |
1081 | ALC_MIC_EVENT, alc_mic_automute); | 1012 | ALC_MIC_EVENT, alc_mic_automute); |
@@ -1085,7 +1016,6 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec) | |||
1085 | alc_mic_automute); | 1016 | alc_mic_automute); |
1086 | 1017 | ||
1087 | spec->auto_mic_valid_imux = 1; | 1018 | spec->auto_mic_valid_imux = 1; |
1088 | spec->auto_mic = 1; | ||
1089 | return true; | 1019 | return true; |
1090 | } | 1020 | } |
1091 | 1021 | ||
@@ -1100,9 +1030,6 @@ static int alc_init_auto_mic(struct hda_codec *codec) | |||
1100 | hda_nid_t fixed, ext, dock; | 1030 | hda_nid_t fixed, ext, dock; |
1101 | int i; | 1031 | int i; |
1102 | 1032 | ||
1103 | if (spec->shared_mic_hp) | ||
1104 | return 0; /* no auto-mic for the shared I/O */ | ||
1105 | |||
1106 | spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1; | 1033 | spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1; |
1107 | 1034 | ||
1108 | fixed = ext = dock = 0; | 1035 | fixed = ext = dock = 0; |
@@ -1152,30 +1079,18 @@ static int alc_init_auto_mic(struct hda_codec *codec) | |||
1152 | spec->int_mic_pin = fixed; | 1079 | spec->int_mic_pin = fixed; |
1153 | spec->dock_mic_pin = dock; | 1080 | spec->dock_mic_pin = dock; |
1154 | 1081 | ||
1155 | spec->auto_mic = 1; | ||
1156 | if (!alc_auto_mic_check_imux(codec)) | 1082 | if (!alc_auto_mic_check_imux(codec)) |
1157 | return 0; | 1083 | return 0; |
1158 | 1084 | ||
1085 | spec->auto_mic = 1; | ||
1086 | spec->num_adc_nids = 1; | ||
1087 | spec->cur_mux[0] = spec->int_mic_idx; | ||
1159 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", | 1088 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", |
1160 | ext, fixed, dock); | 1089 | ext, fixed, dock); |
1161 | 1090 | ||
1162 | return 0; | 1091 | return 0; |
1163 | } | 1092 | } |
1164 | 1093 | ||
1165 | /* check the availabilities of auto-mute and auto-mic switches */ | ||
1166 | static int alc_auto_check_switches(struct hda_codec *codec) | ||
1167 | { | ||
1168 | int err; | ||
1169 | |||
1170 | err = alc_init_automute(codec); | ||
1171 | if (err < 0) | ||
1172 | return err; | ||
1173 | err = alc_init_auto_mic(codec); | ||
1174 | if (err < 0) | ||
1175 | return err; | ||
1176 | return 0; | ||
1177 | } | ||
1178 | |||
1179 | /* | 1094 | /* |
1180 | * Realtek SSID verification | 1095 | * Realtek SSID verification |
1181 | */ | 1096 | */ |
@@ -1509,169 +1424,101 @@ static void alc_auto_parse_digital(struct hda_codec *codec) | |||
1509 | /* | 1424 | /* |
1510 | * capture mixer elements | 1425 | * capture mixer elements |
1511 | */ | 1426 | */ |
1512 | static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, | 1427 | #define alc_cap_vol_info snd_hda_mixer_amp_volume_info |
1513 | struct snd_ctl_elem_info *uinfo) | 1428 | #define alc_cap_vol_get snd_hda_mixer_amp_volume_get |
1514 | { | 1429 | #define alc_cap_vol_tlv snd_hda_mixer_amp_tlv |
1515 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1516 | struct alc_spec *spec = codec->spec; | ||
1517 | unsigned long val; | ||
1518 | int err; | ||
1519 | |||
1520 | mutex_lock(&codec->control_mutex); | ||
1521 | if (spec->vol_in_capsrc) | ||
1522 | val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT); | ||
1523 | else | ||
1524 | val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT); | ||
1525 | kcontrol->private_value = val; | ||
1526 | err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); | ||
1527 | mutex_unlock(&codec->control_mutex); | ||
1528 | return err; | ||
1529 | } | ||
1530 | |||
1531 | static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
1532 | unsigned int size, unsigned int __user *tlv) | ||
1533 | { | ||
1534 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1535 | struct alc_spec *spec = codec->spec; | ||
1536 | unsigned long val; | ||
1537 | int err; | ||
1538 | |||
1539 | mutex_lock(&codec->control_mutex); | ||
1540 | if (spec->vol_in_capsrc) | ||
1541 | val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT); | ||
1542 | else | ||
1543 | val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT); | ||
1544 | kcontrol->private_value = val; | ||
1545 | err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); | ||
1546 | mutex_unlock(&codec->control_mutex); | ||
1547 | return err; | ||
1548 | } | ||
1549 | 1430 | ||
1550 | typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, | 1431 | typedef int (*put_call_t)(struct snd_kcontrol *kcontrol, |
1551 | struct snd_ctl_elem_value *ucontrol); | 1432 | struct snd_ctl_elem_value *ucontrol); |
1552 | 1433 | ||
1553 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | 1434 | static int alc_cap_put_caller(struct snd_kcontrol *kcontrol, |
1554 | struct snd_ctl_elem_value *ucontrol, | 1435 | struct snd_ctl_elem_value *ucontrol, |
1555 | getput_call_t func, bool is_put) | 1436 | put_call_t func, int type) |
1556 | { | 1437 | { |
1557 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1438 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1558 | struct alc_spec *spec = codec->spec; | 1439 | struct alc_spec *spec = codec->spec; |
1559 | int i, err = 0; | 1440 | const struct hda_input_mux *imux; |
1441 | struct nid_path *path; | ||
1442 | int i, adc_idx, err = 0; | ||
1560 | 1443 | ||
1444 | imux = spec->input_mux; | ||
1445 | adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
1561 | mutex_lock(&codec->control_mutex); | 1446 | mutex_lock(&codec->control_mutex); |
1562 | if (is_put && spec->dyn_adc_switch) { | 1447 | codec->cached_write = 1; |
1563 | for (i = 0; i < spec->num_adc_nids; i++) { | 1448 | for (i = 0; i < imux->num_items; i++) { |
1564 | kcontrol->private_value = | 1449 | path = get_nid_path(codec, spec->imux_pins[i], |
1565 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | 1450 | get_adc_nid(codec, adc_idx, i)); |
1566 | 3, 0, HDA_INPUT); | 1451 | if (!path->ctls[type]) |
1567 | err = func(kcontrol, ucontrol); | 1452 | continue; |
1568 | if (err < 0) | 1453 | kcontrol->private_value = path->ctls[type]; |
1569 | goto error; | ||
1570 | } | ||
1571 | } else { | ||
1572 | i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
1573 | if (spec->vol_in_capsrc) | ||
1574 | kcontrol->private_value = | ||
1575 | HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i], | ||
1576 | 3, 0, HDA_OUTPUT); | ||
1577 | else | ||
1578 | kcontrol->private_value = | ||
1579 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | ||
1580 | 3, 0, HDA_INPUT); | ||
1581 | err = func(kcontrol, ucontrol); | 1454 | err = func(kcontrol, ucontrol); |
1455 | if (err < 0) | ||
1456 | goto error; | ||
1582 | } | 1457 | } |
1583 | if (err >= 0 && is_put) | ||
1584 | alc_inv_dmic_sync(codec, false); | ||
1585 | error: | 1458 | error: |
1459 | codec->cached_write = 0; | ||
1586 | mutex_unlock(&codec->control_mutex); | 1460 | mutex_unlock(&codec->control_mutex); |
1461 | snd_hda_codec_resume_amp(codec); | ||
1462 | if (err >= 0 && type == NID_PATH_MUTE_CTL && | ||
1463 | spec->inv_dmic_fixup && spec->inv_dmic_muted) | ||
1464 | alc_inv_dmic_sync_adc(codec, adc_idx); | ||
1587 | return err; | 1465 | return err; |
1588 | } | 1466 | } |
1589 | 1467 | ||
1590 | static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, | ||
1591 | struct snd_ctl_elem_value *ucontrol) | ||
1592 | { | ||
1593 | return alc_cap_getput_caller(kcontrol, ucontrol, | ||
1594 | snd_hda_mixer_amp_volume_get, false); | ||
1595 | } | ||
1596 | |||
1597 | static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, | 1468 | static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, |
1598 | struct snd_ctl_elem_value *ucontrol) | 1469 | struct snd_ctl_elem_value *ucontrol) |
1599 | { | 1470 | { |
1600 | return alc_cap_getput_caller(kcontrol, ucontrol, | 1471 | return alc_cap_put_caller(kcontrol, ucontrol, |
1601 | snd_hda_mixer_amp_volume_put, true); | 1472 | snd_hda_mixer_amp_volume_put, |
1473 | NID_PATH_VOL_CTL); | ||
1602 | } | 1474 | } |
1603 | 1475 | ||
1604 | /* capture mixer elements */ | 1476 | /* capture mixer elements */ |
1605 | #define alc_cap_sw_info snd_ctl_boolean_stereo_info | 1477 | #define alc_cap_sw_info snd_ctl_boolean_stereo_info |
1478 | #define alc_cap_sw_get snd_hda_mixer_amp_switch_get | ||
1606 | 1479 | ||
1607 | static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, | 1480 | static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, |
1608 | struct snd_ctl_elem_value *ucontrol) | 1481 | struct snd_ctl_elem_value *ucontrol) |
1609 | { | 1482 | { |
1610 | return alc_cap_getput_caller(kcontrol, ucontrol, | 1483 | return alc_cap_put_caller(kcontrol, ucontrol, |
1611 | snd_hda_mixer_amp_switch_get, false); | 1484 | snd_hda_mixer_amp_switch_put, |
1485 | NID_PATH_MUTE_CTL); | ||
1612 | } | 1486 | } |
1613 | 1487 | ||
1614 | static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, | 1488 | static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx) |
1615 | struct snd_ctl_elem_value *ucontrol) | ||
1616 | { | 1489 | { |
1617 | return alc_cap_getput_caller(kcontrol, ucontrol, | 1490 | struct alc_spec *spec = codec->spec; |
1618 | snd_hda_mixer_amp_switch_put, true); | 1491 | struct hda_input_mux *imux = &spec->private_imux[0]; |
1619 | } | 1492 | struct nid_path *path; |
1620 | 1493 | hda_nid_t nid; | |
1621 | #define _DEFINE_CAPMIX(num) \ | 1494 | int i, dir, parm; |
1622 | { \ | 1495 | unsigned int val; |
1623 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 1496 | |
1624 | .name = "Capture Switch", \ | 1497 | for (i = 0; i < imux->num_items; i++) { |
1625 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | 1498 | if (spec->imux_pins[i] == spec->inv_dmic_pin) |
1626 | .count = num, \ | 1499 | break; |
1627 | .info = alc_cap_sw_info, \ | 1500 | } |
1628 | .get = alc_cap_sw_get, \ | 1501 | if (i >= imux->num_items) |
1629 | .put = alc_cap_sw_put, \ | 1502 | return; |
1630 | }, \ | 1503 | |
1631 | { \ | 1504 | path = get_nid_path(codec, spec->inv_dmic_pin, |
1632 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 1505 | get_adc_nid(codec, adc_idx, i)); |
1633 | .name = "Capture Volume", \ | 1506 | val = path->ctls[NID_PATH_MUTE_CTL]; |
1634 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | 1507 | if (!val) |
1635 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | 1508 | return; |
1636 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ | 1509 | nid = get_amp_nid_(val); |
1637 | .count = num, \ | 1510 | dir = get_amp_direction_(val); |
1638 | .info = alc_cap_vol_info, \ | 1511 | parm = AC_AMP_SET_RIGHT | |
1639 | .get = alc_cap_vol_get, \ | 1512 | (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT); |
1640 | .put = alc_cap_vol_put, \ | 1513 | |
1641 | .tlv = { .c = alc_cap_vol_tlv }, \ | 1514 | /* we care only right channel */ |
1642 | } | 1515 | val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); |
1643 | 1516 | if (val & 0x80) /* if already muted, we don't need to touch */ | |
1644 | #define _DEFINE_CAPSRC(num) \ | 1517 | return; |
1645 | { \ | 1518 | val |= 0x80; |
1646 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 1519 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
1647 | /* .name = "Capture Source", */ \ | 1520 | parm | val); |
1648 | .name = "Input Source", \ | 1521 | } |
1649 | .count = num, \ | ||
1650 | .info = alc_mux_enum_info, \ | ||
1651 | .get = alc_mux_enum_get, \ | ||
1652 | .put = alc_mux_enum_put, \ | ||
1653 | } | ||
1654 | |||
1655 | #define DEFINE_CAPMIX(num) \ | ||
1656 | static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ | ||
1657 | _DEFINE_CAPMIX(num), \ | ||
1658 | _DEFINE_CAPSRC(num), \ | ||
1659 | { } /* end */ \ | ||
1660 | } | ||
1661 | |||
1662 | #define DEFINE_CAPMIX_NOSRC(num) \ | ||
1663 | static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ | ||
1664 | _DEFINE_CAPMIX(num), \ | ||
1665 | { } /* end */ \ | ||
1666 | } | ||
1667 | |||
1668 | /* up to three ADCs */ | ||
1669 | DEFINE_CAPMIX(1); | ||
1670 | DEFINE_CAPMIX(2); | ||
1671 | DEFINE_CAPMIX(3); | ||
1672 | DEFINE_CAPMIX_NOSRC(1); | ||
1673 | DEFINE_CAPMIX_NOSRC(2); | ||
1674 | DEFINE_CAPMIX_NOSRC(3); | ||
1675 | 1522 | ||
1676 | /* | 1523 | /* |
1677 | * Inverted digital-mic handling | 1524 | * Inverted digital-mic handling |
@@ -1691,40 +1538,22 @@ DEFINE_CAPMIX_NOSRC(3); | |||
1691 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) | 1538 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) |
1692 | { | 1539 | { |
1693 | struct alc_spec *spec = codec->spec; | 1540 | struct alc_spec *spec = codec->spec; |
1694 | int i; | 1541 | int src, nums; |
1695 | 1542 | ||
1696 | if (!spec->inv_dmic_fixup) | 1543 | if (!spec->inv_dmic_fixup) |
1697 | return; | 1544 | return; |
1698 | if (!spec->inv_dmic_muted && !force) | 1545 | if (!spec->inv_dmic_muted && !force) |
1699 | return; | 1546 | return; |
1700 | for (i = 0; i < spec->num_adc_nids; i++) { | 1547 | nums = spec->dyn_adc_switch ? 1 : spec->num_adc_nids; |
1701 | int src = spec->dyn_adc_switch ? 0 : i; | 1548 | for (src = 0; src < nums; src++) { |
1702 | bool dmic_fixup = false; | 1549 | bool dmic_fixup = false; |
1703 | hda_nid_t nid; | ||
1704 | int parm, dir, v; | ||
1705 | 1550 | ||
1706 | if (spec->inv_dmic_muted && | 1551 | if (spec->inv_dmic_muted && |
1707 | spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin) | 1552 | spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin) |
1708 | dmic_fixup = true; | 1553 | dmic_fixup = true; |
1709 | if (!dmic_fixup && !force) | 1554 | if (!dmic_fixup && !force) |
1710 | continue; | 1555 | continue; |
1711 | if (spec->vol_in_capsrc) { | 1556 | alc_inv_dmic_sync_adc(codec, src); |
1712 | nid = spec->capsrc_nids[i]; | ||
1713 | parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT; | ||
1714 | dir = HDA_OUTPUT; | ||
1715 | } else { | ||
1716 | nid = spec->adc_nids[i]; | ||
1717 | parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT; | ||
1718 | dir = HDA_INPUT; | ||
1719 | } | ||
1720 | /* we care only right channel */ | ||
1721 | v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); | ||
1722 | if (v & 0x80) /* if already muted, we don't need to touch */ | ||
1723 | continue; | ||
1724 | if (dmic_fixup) /* add mute for d-mic */ | ||
1725 | v |= 0x80; | ||
1726 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1727 | parm | v); | ||
1728 | } | 1557 | } |
1729 | } | 1558 | } |
1730 | 1559 | ||
@@ -1800,13 +1629,6 @@ static const char * const alc_slave_pfxs[] = { | |||
1800 | 1629 | ||
1801 | #define NID_MAPPING (-1) | 1630 | #define NID_MAPPING (-1) |
1802 | 1631 | ||
1803 | #define SUBDEV_SPEAKER_ (0 << 6) | ||
1804 | #define SUBDEV_HP_ (1 << 6) | ||
1805 | #define SUBDEV_LINE_ (2 << 6) | ||
1806 | #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) | ||
1807 | #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) | ||
1808 | #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) | ||
1809 | |||
1810 | static void alc_free_kctls(struct hda_codec *codec); | 1632 | static void alc_free_kctls(struct hda_codec *codec); |
1811 | 1633 | ||
1812 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 1634 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
@@ -1821,11 +1643,7 @@ static const struct snd_kcontrol_new alc_beep_mixer[] = { | |||
1821 | static int __alc_build_controls(struct hda_codec *codec) | 1643 | static int __alc_build_controls(struct hda_codec *codec) |
1822 | { | 1644 | { |
1823 | struct alc_spec *spec = codec->spec; | 1645 | struct alc_spec *spec = codec->spec; |
1824 | struct snd_kcontrol *kctl = NULL; | 1646 | int i, err; |
1825 | const struct snd_kcontrol_new *knew; | ||
1826 | int i, j, err; | ||
1827 | unsigned int u; | ||
1828 | hda_nid_t nid; | ||
1829 | 1647 | ||
1830 | for (i = 0; i < spec->num_mixers; i++) { | 1648 | for (i = 0; i < spec->num_mixers; i++) { |
1831 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 1649 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
@@ -1897,75 +1715,6 @@ static int __alc_build_controls(struct hda_codec *codec) | |||
1897 | return err; | 1715 | return err; |
1898 | } | 1716 | } |
1899 | 1717 | ||
1900 | /* assign Capture Source enums to NID */ | ||
1901 | if (spec->capsrc_nids || spec->adc_nids) { | ||
1902 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); | ||
1903 | if (!kctl) | ||
1904 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | ||
1905 | for (i = 0; kctl && i < kctl->count; i++) { | ||
1906 | err = snd_hda_add_nid(codec, kctl, i, | ||
1907 | get_capsrc(spec, i)); | ||
1908 | if (err < 0) | ||
1909 | return err; | ||
1910 | } | ||
1911 | } | ||
1912 | if (spec->cap_mixer && spec->adc_nids) { | ||
1913 | const char *kname = kctl ? kctl->id.name : NULL; | ||
1914 | for (knew = spec->cap_mixer; knew->name; knew++) { | ||
1915 | if (kname && strcmp(knew->name, kname) == 0) | ||
1916 | continue; | ||
1917 | kctl = snd_hda_find_mixer_ctl(codec, knew->name); | ||
1918 | for (i = 0; kctl && i < kctl->count; i++) { | ||
1919 | err = snd_hda_add_nid(codec, kctl, i, | ||
1920 | spec->adc_nids[i]); | ||
1921 | if (err < 0) | ||
1922 | return err; | ||
1923 | } | ||
1924 | } | ||
1925 | } | ||
1926 | |||
1927 | /* other nid->control mapping */ | ||
1928 | for (i = 0; i < spec->num_mixers; i++) { | ||
1929 | for (knew = spec->mixers[i]; knew->name; knew++) { | ||
1930 | if (knew->iface != NID_MAPPING) | ||
1931 | continue; | ||
1932 | kctl = snd_hda_find_mixer_ctl(codec, knew->name); | ||
1933 | if (kctl == NULL) | ||
1934 | continue; | ||
1935 | u = knew->subdevice; | ||
1936 | for (j = 0; j < 4; j++, u >>= 8) { | ||
1937 | nid = u & 0x3f; | ||
1938 | if (nid == 0) | ||
1939 | continue; | ||
1940 | switch (u & 0xc0) { | ||
1941 | case SUBDEV_SPEAKER_: | ||
1942 | nid = spec->autocfg.speaker_pins[nid]; | ||
1943 | break; | ||
1944 | case SUBDEV_LINE_: | ||
1945 | nid = spec->autocfg.line_out_pins[nid]; | ||
1946 | break; | ||
1947 | case SUBDEV_HP_: | ||
1948 | nid = spec->autocfg.hp_pins[nid]; | ||
1949 | break; | ||
1950 | default: | ||
1951 | continue; | ||
1952 | } | ||
1953 | err = snd_hda_add_nid(codec, kctl, 0, nid); | ||
1954 | if (err < 0) | ||
1955 | return err; | ||
1956 | } | ||
1957 | u = knew->private_value; | ||
1958 | for (j = 0; j < 4; j++, u >>= 8) { | ||
1959 | nid = u & 0xff; | ||
1960 | if (nid == 0) | ||
1961 | continue; | ||
1962 | err = snd_hda_add_nid(codec, kctl, 0, nid); | ||
1963 | if (err < 0) | ||
1964 | return err; | ||
1965 | } | ||
1966 | } | ||
1967 | } | ||
1968 | |||
1969 | alc_free_kctls(codec); /* no longer needed */ | 1718 | alc_free_kctls(codec); /* no longer needed */ |
1970 | 1719 | ||
1971 | return 0; | 1720 | return 0; |
@@ -2007,7 +1756,6 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2007 | * Common callbacks | 1756 | * Common callbacks |
2008 | */ | 1757 | */ |
2009 | 1758 | ||
2010 | static void alc_init_special_input_src(struct hda_codec *codec); | ||
2011 | static void alc_auto_init_std(struct hda_codec *codec); | 1759 | static void alc_auto_init_std(struct hda_codec *codec); |
2012 | 1760 | ||
2013 | static int alc_init(struct hda_codec *codec) | 1761 | static int alc_init(struct hda_codec *codec) |
@@ -2021,7 +1769,6 @@ static int alc_init(struct hda_codec *codec) | |||
2021 | alc_auto_init_amp(codec, spec->init_amp); | 1769 | alc_auto_init_amp(codec, spec->init_amp); |
2022 | 1770 | ||
2023 | snd_hda_gen_apply_verbs(codec); | 1771 | snd_hda_gen_apply_verbs(codec); |
2024 | alc_init_special_input_src(codec); | ||
2025 | alc_auto_init_std(codec); | 1772 | alc_auto_init_std(codec); |
2026 | 1773 | ||
2027 | alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); | 1774 | alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); |
@@ -2675,28 +2422,6 @@ static int new_analog_input(struct hda_codec *codec, hda_nid_t pin, | |||
2675 | return 0; | 2422 | return 0; |
2676 | } | 2423 | } |
2677 | 2424 | ||
2678 | static int new_capture_source(struct hda_codec *codec, int adc_idx, | ||
2679 | hda_nid_t pin, int idx, const char *label) | ||
2680 | { | ||
2681 | struct alc_spec *spec = codec->spec; | ||
2682 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
2683 | struct nid_path *path; | ||
2684 | |||
2685 | path = snd_array_new(&spec->paths); | ||
2686 | if (!path) | ||
2687 | return -ENOMEM; | ||
2688 | memset(path, 0, sizeof(*path)); | ||
2689 | if (!parse_nid_path(codec, pin, spec->adc_nids[adc_idx], 2, path)) { | ||
2690 | snd_printd(KERN_ERR "invalid input path 0x%x -> 0x%x\n", | ||
2691 | pin, spec->adc_nids[adc_idx]); | ||
2692 | return -EINVAL; | ||
2693 | } | ||
2694 | |||
2695 | spec->imux_pins[imux->num_items] = pin; | ||
2696 | snd_hda_add_imux_item(imux, label, idx, NULL); | ||
2697 | return 0; | ||
2698 | } | ||
2699 | |||
2700 | static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) | 2425 | static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) |
2701 | { | 2426 | { |
2702 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); | 2427 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); |
@@ -2712,54 +2437,217 @@ static bool is_reachable_path(struct hda_codec *codec, | |||
2712 | return snd_hda_get_conn_index(codec, to_nid, from_nid, true) >= 0; | 2437 | return snd_hda_get_conn_index(codec, to_nid, from_nid, true) >= 0; |
2713 | } | 2438 | } |
2714 | 2439 | ||
2715 | /* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */ | 2440 | /* Parse the codec tree and retrieve ADCs */ |
2716 | static int alc_auto_fill_adc_caps(struct hda_codec *codec) | 2441 | static int alc_auto_fill_adc_nids(struct hda_codec *codec) |
2717 | { | 2442 | { |
2718 | struct alc_spec *spec = codec->spec; | 2443 | struct alc_spec *spec = codec->spec; |
2719 | hda_nid_t nid; | 2444 | hda_nid_t nid; |
2720 | hda_nid_t *adc_nids = spec->private_adc_nids; | 2445 | hda_nid_t *adc_nids = spec->private_adc_nids; |
2721 | hda_nid_t *cap_nids = spec->private_capsrc_nids; | ||
2722 | int max_nums = ARRAY_SIZE(spec->private_adc_nids); | 2446 | int max_nums = ARRAY_SIZE(spec->private_adc_nids); |
2723 | int i, nums = 0; | 2447 | int i, nums = 0; |
2724 | 2448 | ||
2725 | nid = codec->start_nid; | 2449 | nid = codec->start_nid; |
2726 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 2450 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
2727 | hda_nid_t src; | ||
2728 | unsigned int caps = get_wcaps(codec, nid); | 2451 | unsigned int caps = get_wcaps(codec, nid); |
2729 | int type = get_wcaps_type(caps); | 2452 | int type = get_wcaps_type(caps); |
2730 | 2453 | ||
2731 | if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL)) | 2454 | if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL)) |
2732 | continue; | 2455 | continue; |
2733 | adc_nids[nums] = nid; | 2456 | adc_nids[nums] = nid; |
2734 | cap_nids[nums] = nid; | ||
2735 | src = nid; | ||
2736 | for (;;) { | ||
2737 | int n; | ||
2738 | type = get_wcaps_type(get_wcaps(codec, src)); | ||
2739 | if (type == AC_WID_PIN) | ||
2740 | break; | ||
2741 | if (type == AC_WID_AUD_SEL) { | ||
2742 | cap_nids[nums] = src; | ||
2743 | break; | ||
2744 | } | ||
2745 | n = snd_hda_get_num_conns(codec, src); | ||
2746 | if (n > 1) { | ||
2747 | cap_nids[nums] = src; | ||
2748 | break; | ||
2749 | } else if (n != 1) | ||
2750 | break; | ||
2751 | if (snd_hda_get_connections(codec, src, &src, 1) != 1) | ||
2752 | break; | ||
2753 | } | ||
2754 | if (++nums >= max_nums) | 2457 | if (++nums >= max_nums) |
2755 | break; | 2458 | break; |
2756 | } | 2459 | } |
2757 | spec->adc_nids = spec->private_adc_nids; | 2460 | spec->adc_nids = spec->private_adc_nids; |
2758 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
2759 | spec->num_adc_nids = nums; | 2461 | spec->num_adc_nids = nums; |
2760 | return nums; | 2462 | return nums; |
2761 | } | 2463 | } |
2762 | 2464 | ||
2465 | /* filter out invalid adc_nids that don't give all active input pins; | ||
2466 | * if needed, check whether dynamic ADC-switching is available | ||
2467 | */ | ||
2468 | static int check_dyn_adc_switch(struct hda_codec *codec) | ||
2469 | { | ||
2470 | struct alc_spec *spec = codec->spec; | ||
2471 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
2472 | hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)]; | ||
2473 | int i, n, nums; | ||
2474 | hda_nid_t pin, adc; | ||
2475 | |||
2476 | again: | ||
2477 | nums = 0; | ||
2478 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
2479 | adc = spec->adc_nids[n]; | ||
2480 | for (i = 0; i < imux->num_items; i++) { | ||
2481 | pin = spec->imux_pins[i]; | ||
2482 | if (!is_reachable_path(codec, pin, adc)) | ||
2483 | break; | ||
2484 | } | ||
2485 | if (i >= imux->num_items) | ||
2486 | adc_nids[nums++] = adc; | ||
2487 | } | ||
2488 | |||
2489 | if (!nums) { | ||
2490 | if (spec->shared_mic_hp) { | ||
2491 | spec->shared_mic_hp = 0; | ||
2492 | spec->private_imux[0].num_items = 1; | ||
2493 | goto again; | ||
2494 | } | ||
2495 | |||
2496 | /* check whether ADC-switch is possible */ | ||
2497 | for (i = 0; i < imux->num_items; i++) { | ||
2498 | pin = spec->imux_pins[i]; | ||
2499 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
2500 | adc = spec->adc_nids[n]; | ||
2501 | if (is_reachable_path(codec, pin, adc)) { | ||
2502 | spec->dyn_adc_idx[i] = n; | ||
2503 | break; | ||
2504 | } | ||
2505 | } | ||
2506 | } | ||
2507 | |||
2508 | snd_printdd("realtek: enabling ADC switching\n"); | ||
2509 | spec->dyn_adc_switch = 1; | ||
2510 | } else if (nums != spec->num_adc_nids) { | ||
2511 | memcpy(spec->private_adc_nids, adc_nids, | ||
2512 | nums * sizeof(hda_nid_t)); | ||
2513 | spec->num_adc_nids = nums; | ||
2514 | } | ||
2515 | |||
2516 | if (spec->input_mux->num_items == 1 || spec->shared_mic_hp) { | ||
2517 | snd_printdd("realtek: reducing to a single ADC\n"); | ||
2518 | spec->num_adc_nids = 1; /* reduce to a single ADC */ | ||
2519 | } | ||
2520 | |||
2521 | return 0; | ||
2522 | } | ||
2523 | |||
2524 | /* templates for capture controls */ | ||
2525 | static const struct snd_kcontrol_new cap_src_temp = { | ||
2526 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2527 | .name = "Input Source", | ||
2528 | .info = alc_mux_enum_info, | ||
2529 | .get = alc_mux_enum_get, | ||
2530 | .put = alc_mux_enum_put, | ||
2531 | }; | ||
2532 | |||
2533 | static const struct snd_kcontrol_new cap_vol_temp = { | ||
2534 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2535 | .name = "Capture Volume", | ||
2536 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
2537 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
2538 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), | ||
2539 | .info = alc_cap_vol_info, | ||
2540 | .get = alc_cap_vol_get, | ||
2541 | .put = alc_cap_vol_put, | ||
2542 | .tlv = { .c = alc_cap_vol_tlv }, | ||
2543 | }; | ||
2544 | |||
2545 | static const struct snd_kcontrol_new cap_sw_temp = { | ||
2546 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2547 | .name = "Capture Switch", | ||
2548 | .info = alc_cap_sw_info, | ||
2549 | .get = alc_cap_sw_get, | ||
2550 | .put = alc_cap_sw_put, | ||
2551 | }; | ||
2552 | |||
2553 | static int parse_capvol_in_path(struct hda_codec *codec, struct nid_path *path) | ||
2554 | { | ||
2555 | hda_nid_t nid; | ||
2556 | int i, depth; | ||
2557 | |||
2558 | path->ctls[NID_PATH_VOL_CTL] = path->ctls[NID_PATH_MUTE_CTL] = 0; | ||
2559 | for (depth = 0; depth < 3; depth++) { | ||
2560 | if (depth >= path->depth) | ||
2561 | return -EINVAL; | ||
2562 | i = path->depth - depth - 1; | ||
2563 | nid = path->path[i]; | ||
2564 | if (!path->ctls[NID_PATH_VOL_CTL]) { | ||
2565 | if (nid_has_volume(codec, nid, HDA_OUTPUT)) | ||
2566 | path->ctls[NID_PATH_VOL_CTL] = | ||
2567 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
2568 | else if (nid_has_volume(codec, nid, HDA_INPUT)) { | ||
2569 | int idx = path->idx[i]; | ||
2570 | if (!depth && codec->single_adc_amp) | ||
2571 | idx = 0; | ||
2572 | path->ctls[NID_PATH_VOL_CTL] = | ||
2573 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_INPUT); | ||
2574 | } | ||
2575 | } | ||
2576 | if (!path->ctls[NID_PATH_MUTE_CTL]) { | ||
2577 | if (nid_has_mute(codec, nid, HDA_OUTPUT)) | ||
2578 | path->ctls[NID_PATH_MUTE_CTL] = | ||
2579 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
2580 | else if (nid_has_mute(codec, nid, HDA_INPUT)) { | ||
2581 | int idx = path->idx[i]; | ||
2582 | if (!depth && codec->single_adc_amp) | ||
2583 | idx = 0; | ||
2584 | path->ctls[NID_PATH_MUTE_CTL] = | ||
2585 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_INPUT); | ||
2586 | } | ||
2587 | } | ||
2588 | } | ||
2589 | return 0; | ||
2590 | } | ||
2591 | |||
2592 | static int create_capture_mixers(struct hda_codec *codec) | ||
2593 | { | ||
2594 | struct alc_spec *spec = codec->spec; | ||
2595 | struct hda_input_mux *imux = &spec->private_imux[0]; | ||
2596 | struct snd_kcontrol_new *knew; | ||
2597 | int i, n, nums; | ||
2598 | |||
2599 | if (spec->dyn_adc_switch) | ||
2600 | nums = 1; | ||
2601 | else | ||
2602 | nums = spec->num_adc_nids; | ||
2603 | |||
2604 | if (!spec->auto_mic && imux->num_items > 1) { | ||
2605 | knew = alc_kcontrol_new(spec, "Input Source", &cap_src_temp); | ||
2606 | if (!knew) | ||
2607 | return -ENOMEM; | ||
2608 | knew->count = nums; | ||
2609 | } | ||
2610 | |||
2611 | for (n = 0; n < nums; n++) { | ||
2612 | int vol, sw; | ||
2613 | |||
2614 | vol = sw = 0; | ||
2615 | for (i = 0; i < imux->num_items; i++) { | ||
2616 | struct nid_path *path; | ||
2617 | path = get_nid_path(codec, spec->imux_pins[i], | ||
2618 | get_adc_nid(codec, n, i)); | ||
2619 | if (!path) | ||
2620 | continue; | ||
2621 | parse_capvol_in_path(codec, path); | ||
2622 | if (!vol) | ||
2623 | vol = path->ctls[NID_PATH_VOL_CTL]; | ||
2624 | if (!sw) | ||
2625 | sw = path->ctls[NID_PATH_MUTE_CTL]; | ||
2626 | } | ||
2627 | |||
2628 | if (vol) { | ||
2629 | knew = alc_kcontrol_new(spec, "Capture Volume", | ||
2630 | &cap_vol_temp); | ||
2631 | if (!knew) | ||
2632 | return -ENOMEM; | ||
2633 | knew->index = n; | ||
2634 | knew->private_value = vol; | ||
2635 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | ||
2636 | } | ||
2637 | if (sw) { | ||
2638 | knew = alc_kcontrol_new(spec, "Capture Switch", | ||
2639 | &cap_sw_temp); | ||
2640 | if (!knew) | ||
2641 | return -ENOMEM; | ||
2642 | knew->index = n; | ||
2643 | knew->private_value = sw; | ||
2644 | knew->subdevice = HDA_SUBDEV_AMP_FLAG; | ||
2645 | } | ||
2646 | } | ||
2647 | |||
2648 | return 0; | ||
2649 | } | ||
2650 | |||
2763 | /* create playback/capture controls for input pins */ | 2651 | /* create playback/capture controls for input pins */ |
2764 | static int alc_auto_create_input_ctls(struct hda_codec *codec) | 2652 | static int alc_auto_create_input_ctls(struct hda_codec *codec) |
2765 | { | 2653 | { |
@@ -2768,16 +2656,17 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) | |||
2768 | hda_nid_t mixer = spec->mixer_nid; | 2656 | hda_nid_t mixer = spec->mixer_nid; |
2769 | struct hda_input_mux *imux = &spec->private_imux[0]; | 2657 | struct hda_input_mux *imux = &spec->private_imux[0]; |
2770 | int num_adcs; | 2658 | int num_adcs; |
2771 | int i, c, err, idx, type_idx = 0; | 2659 | int i, c, err, type_idx = 0; |
2772 | const char *prev_label = NULL; | 2660 | const char *prev_label = NULL; |
2773 | 2661 | ||
2774 | num_adcs = alc_auto_fill_adc_caps(codec); | 2662 | num_adcs = alc_auto_fill_adc_nids(codec); |
2775 | if (num_adcs < 0) | 2663 | if (num_adcs < 0) |
2776 | return 0; | 2664 | return 0; |
2777 | 2665 | ||
2778 | for (i = 0; i < cfg->num_inputs; i++) { | 2666 | for (i = 0; i < cfg->num_inputs; i++) { |
2779 | hda_nid_t pin; | 2667 | hda_nid_t pin; |
2780 | const char *label; | 2668 | const char *label; |
2669 | bool imux_added; | ||
2781 | 2670 | ||
2782 | pin = cfg->inputs[i].pin; | 2671 | pin = cfg->inputs[i].pin; |
2783 | if (!alc_is_input_pin(codec, pin)) | 2672 | if (!alc_is_input_pin(codec, pin)) |
@@ -2801,21 +2690,35 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) | |||
2801 | } | 2690 | } |
2802 | } | 2691 | } |
2803 | 2692 | ||
2693 | imux_added = false; | ||
2804 | for (c = 0; c < num_adcs; c++) { | 2694 | for (c = 0; c < num_adcs; c++) { |
2805 | hda_nid_t cap = get_capsrc(spec, c); | 2695 | struct nid_path *path; |
2806 | idx = get_connection_index(codec, cap, pin); | 2696 | hda_nid_t adc = spec->adc_nids[c]; |
2807 | if (idx >= 0) { | 2697 | |
2808 | err = new_capture_source(codec, c, pin, idx, label); | 2698 | if (!is_reachable_path(codec, pin, adc)) |
2809 | if (err < 0) | 2699 | continue; |
2810 | return err; | 2700 | path = snd_array_new(&spec->paths); |
2811 | break; | 2701 | if (!path) |
2702 | return -ENOMEM; | ||
2703 | memset(path, 0, sizeof(*path)); | ||
2704 | if (!parse_nid_path(codec, pin, adc, 2, path)) { | ||
2705 | snd_printd(KERN_ERR | ||
2706 | "invalid input path 0x%x -> 0x%x\n", | ||
2707 | pin, adc); | ||
2708 | spec->paths.used--; | ||
2709 | continue; | ||
2710 | } | ||
2711 | |||
2712 | if (!imux_added) { | ||
2713 | spec->imux_pins[imux->num_items] = pin; | ||
2714 | snd_hda_add_imux_item(imux, label, | ||
2715 | imux->num_items, NULL); | ||
2716 | imux_added = true; | ||
2812 | } | 2717 | } |
2813 | } | 2718 | } |
2814 | } | 2719 | } |
2815 | 2720 | ||
2816 | spec->num_mux_defs = 1; | ||
2817 | spec->input_mux = imux; | 2721 | spec->input_mux = imux; |
2818 | |||
2819 | return 0; | 2722 | return 0; |
2820 | } | 2723 | } |
2821 | 2724 | ||
@@ -2852,11 +2755,6 @@ static int alc_auto_create_shared_input(struct hda_codec *codec) | |||
2852 | return 0; | 2755 | return 0; |
2853 | } | 2756 | } |
2854 | 2757 | ||
2855 | static struct nid_path * | ||
2856 | get_nid_path(struct hda_codec *codec, hda_nid_t from_nid, hda_nid_t to_nid); | ||
2857 | static void activate_path(struct hda_codec *codec, struct nid_path *path, | ||
2858 | bool enable); | ||
2859 | |||
2860 | static int get_pin_type(int line_out_type) | 2758 | static int get_pin_type(int line_out_type) |
2861 | { | 2759 | { |
2862 | if (line_out_type == AUTO_PIN_HP_OUT) | 2760 | if (line_out_type == AUTO_PIN_HP_OUT) |
@@ -2886,7 +2784,7 @@ static void alc_auto_init_analog_input(struct hda_codec *codec) | |||
2886 | struct nid_path *path; | 2784 | struct nid_path *path; |
2887 | path = get_nid_path(codec, nid, spec->mixer_nid); | 2785 | path = get_nid_path(codec, nid, spec->mixer_nid); |
2888 | if (path) | 2786 | if (path) |
2889 | activate_path(codec, path, path->active); | 2787 | activate_path(codec, path, path->active, false); |
2890 | } | 2788 | } |
2891 | } | 2789 | } |
2892 | } | 2790 | } |
@@ -3930,15 +3828,18 @@ static void activate_amp_out(struct hda_codec *codec, struct nid_path *path, | |||
3930 | } | 3828 | } |
3931 | 3829 | ||
3932 | static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, | 3830 | static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, |
3933 | int i, bool enable) | 3831 | int i, bool enable, bool add_aamix) |
3934 | { | 3832 | { |
3935 | struct alc_spec *spec = codec->spec; | 3833 | struct alc_spec *spec = codec->spec; |
3936 | hda_nid_t conn[16]; | 3834 | hda_nid_t conn[16]; |
3937 | int n, nums, idx; | 3835 | int n, nums, idx; |
3836 | int type; | ||
3938 | hda_nid_t nid = path->path[i]; | 3837 | hda_nid_t nid = path->path[i]; |
3939 | 3838 | ||
3940 | nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn)); | 3839 | nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn)); |
3941 | if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN) { | 3840 | type = get_wcaps_type(get_wcaps(codec, nid)); |
3841 | if (type == AC_WID_PIN || | ||
3842 | (type == AC_WID_AUD_IN && codec->single_adc_amp)) { | ||
3942 | nums = 1; | 3843 | nums = 1; |
3943 | idx = 0; | 3844 | idx = 0; |
3944 | } else | 3845 | } else |
@@ -3954,14 +3855,14 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, | |||
3954 | * when aa-mixer is available, we need to enable the path as well | 3855 | * when aa-mixer is available, we need to enable the path as well |
3955 | */ | 3856 | */ |
3956 | for (n = 0; n < nums; n++) { | 3857 | for (n = 0; n < nums; n++) { |
3957 | if (n != idx && conn[n] != spec->mixer_nid) | 3858 | if (n != idx && (!add_aamix || conn[n] != spec->mixer_nid)) |
3958 | continue; | 3859 | continue; |
3959 | activate_amp(codec, nid, HDA_INPUT, n, enable); | 3860 | activate_amp(codec, nid, HDA_INPUT, n, enable); |
3960 | } | 3861 | } |
3961 | } | 3862 | } |
3962 | 3863 | ||
3963 | static void activate_path(struct hda_codec *codec, struct nid_path *path, | 3864 | static void activate_path(struct hda_codec *codec, struct nid_path *path, |
3964 | bool enable) | 3865 | bool enable, bool add_aamix) |
3965 | { | 3866 | { |
3966 | int i; | 3867 | int i; |
3967 | 3868 | ||
@@ -3974,7 +3875,7 @@ static void activate_path(struct hda_codec *codec, struct nid_path *path, | |||
3974 | AC_VERB_SET_CONNECT_SEL, | 3875 | AC_VERB_SET_CONNECT_SEL, |
3975 | path->idx[i]); | 3876 | path->idx[i]); |
3976 | if (has_amp_in(codec, path, i)) | 3877 | if (has_amp_in(codec, path, i)) |
3977 | activate_amp_in(codec, path, i, enable); | 3878 | activate_amp_in(codec, path, i, enable, add_aamix); |
3978 | if (has_amp_out(codec, path, i)) | 3879 | if (has_amp_out(codec, path, i)) |
3979 | activate_amp_out(codec, path, i, enable); | 3880 | activate_amp_out(codec, path, i, enable); |
3980 | } | 3881 | } |
@@ -3996,7 +3897,7 @@ static void alc_auto_set_output_and_unmute(struct hda_codec *codec, | |||
3996 | return; | 3897 | return; |
3997 | if (path->active) | 3898 | if (path->active) |
3998 | return; | 3899 | return; |
3999 | activate_path(codec, path, true); | 3900 | activate_path(codec, path, true, true); |
4000 | } | 3901 | } |
4001 | 3902 | ||
4002 | static void alc_auto_init_multi_out(struct hda_codec *codec) | 3903 | static void alc_auto_init_multi_out(struct hda_codec *codec) |
@@ -4210,9 +4111,9 @@ static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output) | |||
4210 | 4111 | ||
4211 | if (output) { | 4112 | if (output) { |
4212 | snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT); | 4113 | snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT); |
4213 | activate_path(codec, path, true); | 4114 | activate_path(codec, path, true, true); |
4214 | } else { | 4115 | } else { |
4215 | activate_path(codec, path, false); | 4116 | activate_path(codec, path, false, true); |
4216 | snd_hda_set_pin_ctl_cache(codec, nid, | 4117 | snd_hda_set_pin_ctl_cache(codec, nid, |
4217 | spec->multi_io[idx].ctl_in); | 4118 | spec->multi_io[idx].ctl_in); |
4218 | } | 4119 | } |
@@ -4276,112 +4177,41 @@ static void alc_auto_init_multi_io(struct hda_codec *codec) | |||
4276 | spec->multi_io[i].ctl_in = | 4177 | spec->multi_io[i].ctl_in = |
4277 | snd_hda_codec_update_cache(codec, pin, 0, | 4178 | snd_hda_codec_update_cache(codec, pin, 0, |
4278 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 4179 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
4279 | activate_path(codec, path, path->active); | 4180 | activate_path(codec, path, path->active, true); |
4280 | } | ||
4281 | } | ||
4282 | |||
4283 | /* filter out invalid adc_nids (and capsrc_nids) that don't give all | ||
4284 | * active input pins | ||
4285 | */ | ||
4286 | static void alc_remove_invalid_adc_nids(struct hda_codec *codec) | ||
4287 | { | ||
4288 | struct alc_spec *spec = codec->spec; | ||
4289 | const struct hda_input_mux *imux; | ||
4290 | hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)]; | ||
4291 | hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)]; | ||
4292 | int i, n, nums; | ||
4293 | |||
4294 | imux = spec->input_mux; | ||
4295 | if (!imux) | ||
4296 | return; | ||
4297 | if (spec->dyn_adc_switch) | ||
4298 | return; | ||
4299 | |||
4300 | again: | ||
4301 | nums = 0; | ||
4302 | for (n = 0; n < spec->num_adc_nids; n++) { | ||
4303 | hda_nid_t cap = spec->private_capsrc_nids[n]; | ||
4304 | int num_conns = snd_hda_get_num_conns(codec, cap); | ||
4305 | for (i = 0; i < imux->num_items; i++) { | ||
4306 | hda_nid_t pin = spec->imux_pins[i]; | ||
4307 | if (pin) { | ||
4308 | if (get_connection_index(codec, cap, pin) < 0) | ||
4309 | break; | ||
4310 | } else if (num_conns <= imux->items[i].index) | ||
4311 | break; | ||
4312 | } | ||
4313 | if (i >= imux->num_items) { | ||
4314 | adc_nids[nums] = spec->private_adc_nids[n]; | ||
4315 | capsrc_nids[nums++] = cap; | ||
4316 | } | ||
4317 | } | 4181 | } |
4318 | if (!nums) { | ||
4319 | /* check whether ADC-switch is possible */ | ||
4320 | if (!alc_check_dyn_adc_switch(codec)) { | ||
4321 | if (spec->shared_mic_hp) { | ||
4322 | spec->shared_mic_hp = 0; | ||
4323 | spec->private_imux[0].num_items = 1; | ||
4324 | goto again; | ||
4325 | } | ||
4326 | printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" | ||
4327 | " using fallback 0x%x\n", | ||
4328 | codec->chip_name, spec->private_adc_nids[0]); | ||
4329 | spec->num_adc_nids = 1; | ||
4330 | spec->auto_mic = 0; | ||
4331 | return; | ||
4332 | } | ||
4333 | } else if (nums != spec->num_adc_nids) { | ||
4334 | memcpy(spec->private_adc_nids, adc_nids, | ||
4335 | nums * sizeof(hda_nid_t)); | ||
4336 | memcpy(spec->private_capsrc_nids, capsrc_nids, | ||
4337 | nums * sizeof(hda_nid_t)); | ||
4338 | spec->num_adc_nids = nums; | ||
4339 | } | ||
4340 | |||
4341 | if (spec->auto_mic) | ||
4342 | alc_auto_mic_check_imux(codec); /* check auto-mic setups */ | ||
4343 | else if (spec->input_mux->num_items == 1 || spec->shared_mic_hp) | ||
4344 | spec->num_adc_nids = 1; /* reduce to a single ADC */ | ||
4345 | } | 4182 | } |
4346 | 4183 | ||
4347 | /* | 4184 | /* |
4348 | * initialize ADC paths | 4185 | * initialize ADC paths |
4349 | */ | 4186 | */ |
4350 | static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx) | ||
4351 | { | ||
4352 | struct alc_spec *spec = codec->spec; | ||
4353 | hda_nid_t nid; | ||
4354 | |||
4355 | nid = spec->adc_nids[adc_idx]; | ||
4356 | /* mute ADC */ | ||
4357 | if (nid_has_mute(codec, nid, HDA_INPUT)) { | ||
4358 | snd_hda_codec_write(codec, nid, 0, | ||
4359 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
4360 | AMP_IN_MUTE(0)); | ||
4361 | return; | ||
4362 | } | ||
4363 | if (!spec->capsrc_nids) | ||
4364 | return; | ||
4365 | nid = spec->capsrc_nids[adc_idx]; | ||
4366 | if (nid_has_mute(codec, nid, HDA_OUTPUT)) | ||
4367 | snd_hda_codec_write(codec, nid, 0, | ||
4368 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
4369 | AMP_OUT_MUTE); | ||
4370 | } | ||
4371 | |||
4372 | static void alc_auto_init_input_src(struct hda_codec *codec) | 4187 | static void alc_auto_init_input_src(struct hda_codec *codec) |
4373 | { | 4188 | { |
4374 | struct alc_spec *spec = codec->spec; | 4189 | struct alc_spec *spec = codec->spec; |
4375 | int c, nums; | 4190 | struct hda_input_mux *imux = &spec->private_imux[0]; |
4191 | struct nid_path *path; | ||
4192 | int i, c, nums; | ||
4376 | 4193 | ||
4377 | for (c = 0; c < spec->num_adc_nids; c++) | ||
4378 | alc_auto_init_adc(codec, c); | ||
4379 | if (spec->dyn_adc_switch) | 4194 | if (spec->dyn_adc_switch) |
4380 | nums = 1; | 4195 | nums = 1; |
4381 | else | 4196 | else |
4382 | nums = spec->num_adc_nids; | 4197 | nums = spec->num_adc_nids; |
4383 | for (c = 0; c < nums; c++) | 4198 | |
4384 | alc_mux_select(codec, c, spec->cur_mux[c], true); | 4199 | for (c = 0; c < nums; c++) { |
4200 | for (i = 0; i < imux->num_items; i++) { | ||
4201 | path = get_nid_path(codec, spec->imux_pins[i], | ||
4202 | get_adc_nid(codec, c, i)); | ||
4203 | if (path) { | ||
4204 | bool active = path->active; | ||
4205 | if (i == spec->cur_mux[c]) | ||
4206 | active = true; | ||
4207 | activate_path(codec, path, active, false); | ||
4208 | } | ||
4209 | } | ||
4210 | } | ||
4211 | |||
4212 | alc_inv_dmic_sync(codec, true); | ||
4213 | if (spec->shared_mic_hp) | ||
4214 | update_shared_mic_hp(codec, spec->cur_mux[0]); | ||
4385 | } | 4215 | } |
4386 | 4216 | ||
4387 | /* add mic boosts if needed */ | 4217 | /* add mic boosts if needed */ |
@@ -4429,94 +4259,6 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
4429 | return 0; | 4259 | return 0; |
4430 | } | 4260 | } |
4431 | 4261 | ||
4432 | /* select or unmute the given capsrc route */ | ||
4433 | static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, | ||
4434 | int idx) | ||
4435 | { | ||
4436 | if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { | ||
4437 | snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, | ||
4438 | HDA_AMP_MUTE, 0); | ||
4439 | } else if (snd_hda_get_num_conns(codec, cap) > 1) { | ||
4440 | snd_hda_codec_write_cache(codec, cap, 0, | ||
4441 | AC_VERB_SET_CONNECT_SEL, idx); | ||
4442 | } | ||
4443 | } | ||
4444 | |||
4445 | /* set the default connection to that pin */ | ||
4446 | static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | ||
4447 | { | ||
4448 | struct alc_spec *spec = codec->spec; | ||
4449 | int i; | ||
4450 | |||
4451 | if (!pin) | ||
4452 | return 0; | ||
4453 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
4454 | hda_nid_t cap = get_capsrc(spec, i); | ||
4455 | int idx; | ||
4456 | |||
4457 | idx = get_connection_index(codec, cap, pin); | ||
4458 | if (idx < 0) | ||
4459 | continue; | ||
4460 | select_or_unmute_capsrc(codec, cap, idx); | ||
4461 | return i; /* return the found index */ | ||
4462 | } | ||
4463 | return -1; /* not found */ | ||
4464 | } | ||
4465 | |||
4466 | /* initialize some special cases for input sources */ | ||
4467 | static void alc_init_special_input_src(struct hda_codec *codec) | ||
4468 | { | ||
4469 | struct alc_spec *spec = codec->spec; | ||
4470 | int i; | ||
4471 | |||
4472 | for (i = 0; i < spec->autocfg.num_inputs; i++) | ||
4473 | init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin); | ||
4474 | } | ||
4475 | |||
4476 | /* assign appropriate capture mixers */ | ||
4477 | static void set_capture_mixer(struct hda_codec *codec) | ||
4478 | { | ||
4479 | struct alc_spec *spec = codec->spec; | ||
4480 | static const struct snd_kcontrol_new *caps[2][3] = { | ||
4481 | { alc_capture_mixer_nosrc1, | ||
4482 | alc_capture_mixer_nosrc2, | ||
4483 | alc_capture_mixer_nosrc3 }, | ||
4484 | { alc_capture_mixer1, | ||
4485 | alc_capture_mixer2, | ||
4486 | alc_capture_mixer3 }, | ||
4487 | }; | ||
4488 | |||
4489 | /* check whether either of ADC or MUX has a volume control */ | ||
4490 | if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) { | ||
4491 | if (!spec->capsrc_nids) | ||
4492 | return; /* no volume */ | ||
4493 | if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT)) | ||
4494 | return; /* no volume in capsrc, too */ | ||
4495 | spec->vol_in_capsrc = 1; | ||
4496 | } | ||
4497 | |||
4498 | if (spec->num_adc_nids > 0) { | ||
4499 | int mux = 0; | ||
4500 | int num_adcs = 0; | ||
4501 | |||
4502 | if (spec->input_mux && spec->input_mux->num_items > 1) | ||
4503 | mux = 1; | ||
4504 | if (spec->auto_mic) { | ||
4505 | num_adcs = 1; | ||
4506 | mux = 0; | ||
4507 | } else if (spec->dyn_adc_switch) | ||
4508 | num_adcs = 1; | ||
4509 | if (!num_adcs) { | ||
4510 | if (spec->num_adc_nids > 3) | ||
4511 | spec->num_adc_nids = 3; | ||
4512 | else if (!spec->num_adc_nids) | ||
4513 | return; | ||
4514 | num_adcs = spec->num_adc_nids; | ||
4515 | } | ||
4516 | spec->cap_mixer = caps[mux][num_adcs - 1]; | ||
4517 | } | ||
4518 | } | ||
4519 | |||
4520 | /* | 4262 | /* |
4521 | * standard auto-parser initializations | 4263 | * standard auto-parser initializations |
4522 | */ | 4264 | */ |
@@ -4639,16 +4381,28 @@ static int alc_parse_auto_config(struct hda_codec *codec, | |||
4639 | dig_only: | 4381 | dig_only: |
4640 | alc_auto_parse_digital(codec); | 4382 | alc_auto_parse_digital(codec); |
4641 | 4383 | ||
4642 | if (!spec->no_analog) | ||
4643 | alc_remove_invalid_adc_nids(codec); | ||
4644 | |||
4645 | if (ssid_nids) | 4384 | if (ssid_nids) |
4646 | alc_ssid_check(codec, ssid_nids); | 4385 | alc_ssid_check(codec, ssid_nids); |
4647 | 4386 | ||
4648 | if (!spec->no_analog) { | 4387 | if (!spec->no_analog) { |
4649 | err = alc_auto_check_switches(codec); | 4388 | err = alc_init_automute(codec); |
4650 | if (err < 0) | 4389 | if (err < 0) |
4651 | return err; | 4390 | return err; |
4391 | |||
4392 | err = check_dyn_adc_switch(codec); | ||
4393 | if (err < 0) | ||
4394 | return err; | ||
4395 | |||
4396 | if (!spec->shared_mic_hp) { | ||
4397 | err = alc_init_auto_mic(codec); | ||
4398 | if (err < 0) | ||
4399 | return err; | ||
4400 | } | ||
4401 | |||
4402 | err = create_capture_mixers(codec); | ||
4403 | if (err < 0) | ||
4404 | return err; | ||
4405 | |||
4652 | err = alc_auto_add_mic_boost(codec); | 4406 | err = alc_auto_add_mic_boost(codec); |
4653 | if (err < 0) | 4407 | if (err < 0) |
4654 | return err; | 4408 | return err; |
@@ -4657,9 +4411,6 @@ static int alc_parse_auto_config(struct hda_codec *codec, | |||
4657 | if (spec->kctls.list) | 4411 | if (spec->kctls.list) |
4658 | add_mixer(spec, spec->kctls.list); | 4412 | add_mixer(spec, spec->kctls.list); |
4659 | 4413 | ||
4660 | if (!spec->no_analog && !spec->cap_mixer) | ||
4661 | set_capture_mixer(codec); | ||
4662 | |||
4663 | return 1; | 4414 | return 1; |
4664 | } | 4415 | } |
4665 | 4416 | ||