aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_via.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r--sound/pci/hda/patch_via.c587
1 files changed, 152 insertions, 435 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index ae3acb2b42d1..d1c3f8defc48 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -444,8 +444,8 @@ static hda_nid_t vt1812_adc_nids[2] = {
444 444
445 445
446/* add dynamic controls */ 446/* add dynamic controls */
447static int via_add_control(struct via_spec *spec, int type, const char *name, 447static int __via_add_control(struct via_spec *spec, int type, const char *name,
448 unsigned long val) 448 int idx, unsigned long val)
449{ 449{
450 struct snd_kcontrol_new *knew; 450 struct snd_kcontrol_new *knew;
451 451
@@ -463,6 +463,9 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
463 return 0; 463 return 0;
464} 464}
465 465
466#define via_add_control(spec, type, name, val) \
467 __via_add_control(spec, type, name, 0, val)
468
466static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, 469static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
467 struct snd_kcontrol_new *tmpl) 470 struct snd_kcontrol_new *tmpl)
468{ 471{
@@ -494,18 +497,18 @@ static void via_free_kctls(struct hda_codec *codec)
494 497
495/* create input playback/capture controls for the given pin */ 498/* create input playback/capture controls for the given pin */
496static int via_new_analog_input(struct via_spec *spec, const char *ctlname, 499static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
497 int idx, int mix_nid) 500 int type_idx, int idx, int mix_nid)
498{ 501{
499 char name[32]; 502 char name[32];
500 int err; 503 int err;
501 504
502 sprintf(name, "%s Playback Volume", ctlname); 505 sprintf(name, "%s Playback Volume", ctlname);
503 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 506 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
504 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 507 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
505 if (err < 0) 508 if (err < 0)
506 return err; 509 return err;
507 sprintf(name, "%s Playback Switch", ctlname); 510 sprintf(name, "%s Playback Switch", ctlname);
508 err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, 511 err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
509 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 512 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
510 if (err < 0) 513 if (err < 0)
511 return err; 514 return err;
@@ -557,17 +560,15 @@ static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
557static void via_auto_init_analog_input(struct hda_codec *codec) 560static void via_auto_init_analog_input(struct hda_codec *codec)
558{ 561{
559 struct via_spec *spec = codec->spec; 562 struct via_spec *spec = codec->spec;
563 const struct auto_pin_cfg *cfg = &spec->autocfg;
560 unsigned int ctl; 564 unsigned int ctl;
561 int i; 565 int i;
562 566
563 for (i = 0; i < AUTO_PIN_LAST; i++) { 567 for (i = 0; i < cfg->num_inputs; i++) {
564 hda_nid_t nid = spec->autocfg.input_pins[i]; 568 hda_nid_t nid = cfg->inputs[i].pin;
565 if (!nid)
566 continue;
567
568 if (spec->smart51_enabled && is_smart51_pins(spec, nid)) 569 if (spec->smart51_enabled && is_smart51_pins(spec, nid))
569 ctl = PIN_OUT; 570 ctl = PIN_OUT;
570 else if (i <= AUTO_PIN_FRONT_MIC) 571 else if (i == AUTO_PIN_MIC)
571 ctl = PIN_VREF50; 572 ctl = PIN_VREF50;
572 else 573 else
573 ctl = PIN_IN; 574 ctl = PIN_IN;
@@ -1322,15 +1323,14 @@ static void mute_aa_path(struct hda_codec *codec, int mute)
1322} 1323}
1323static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) 1324static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1324{ 1325{
1325 int res = 0; 1326 const struct auto_pin_cfg *cfg = &spec->autocfg;
1326 int index; 1327 int i;
1327 for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) { 1328
1328 if (pin == spec->autocfg.input_pins[index]) { 1329 for (i = 0; i < cfg->num_inputs; i++) {
1329 res = 1; 1330 if (pin == cfg->inputs[i].pin)
1330 break; 1331 return cfg->inputs[i].type <= AUTO_PIN_LINE_IN;
1331 }
1332 } 1332 }
1333 return res; 1333 return 0;
1334} 1334}
1335 1335
1336static int via_smart51_info(struct snd_kcontrol *kcontrol, 1336static int via_smart51_info(struct snd_kcontrol *kcontrol,
@@ -1348,25 +1348,21 @@ static int via_smart51_get(struct snd_kcontrol *kcontrol,
1348{ 1348{
1349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1350 struct via_spec *spec = codec->spec; 1350 struct via_spec *spec = codec->spec;
1351 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; 1351 const struct auto_pin_cfg *cfg = &spec->autocfg;
1352 int on = 1; 1352 int on = 1;
1353 int i; 1353 int i;
1354 1354
1355 for (i = 0; i < ARRAY_SIZE(index); i++) { 1355 for (i = 0; i < cfg->num_inputs; i++) {
1356 hda_nid_t nid = spec->autocfg.input_pins[index[i]]; 1356 hda_nid_t nid = cfg->inputs[i].pin;
1357 if (nid) { 1357 int ctl = snd_hda_codec_read(codec, nid, 0,
1358 int ctl = 1358 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1359 snd_hda_codec_read(codec, nid, 0, 1359 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1360 AC_VERB_GET_PIN_WIDGET_CONTROL, 1360 continue;
1361 0); 1361 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1362 if (i == AUTO_PIN_FRONT_MIC 1362 spec->hp_independent_mode && spec->codec_type != VT1718S)
1363 && spec->hp_independent_mode 1363 continue; /* ignore FMic for independent HP */
1364 && spec->codec_type != VT1718S) 1364 if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
1365 continue; /* ignore FMic for independent HP */ 1365 on = 0;
1366 if (ctl & AC_PINCTL_IN_EN
1367 && !(ctl & AC_PINCTL_OUT_EN))
1368 on = 0;
1369 }
1370 } 1366 }
1371 *ucontrol->value.integer.value = on; 1367 *ucontrol->value.integer.value = on;
1372 return 0; 1368 return 0;
@@ -1377,36 +1373,38 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1377{ 1373{
1378 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1379 struct via_spec *spec = codec->spec; 1375 struct via_spec *spec = codec->spec;
1376 const struct auto_pin_cfg *cfg = &spec->autocfg;
1380 int out_in = *ucontrol->value.integer.value 1377 int out_in = *ucontrol->value.integer.value
1381 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN; 1378 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1382 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1383 int i; 1379 int i;
1384 1380
1385 for (i = 0; i < ARRAY_SIZE(index); i++) { 1381 for (i = 0; i < cfg->num_inputs; i++) {
1386 hda_nid_t nid = spec->autocfg.input_pins[index[i]]; 1382 hda_nid_t nid = cfg->inputs[i].pin;
1387 if (i == AUTO_PIN_FRONT_MIC 1383 unsigned int parm;
1388 && spec->hp_independent_mode 1384
1389 && spec->codec_type != VT1718S) 1385 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1386 continue;
1387 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1388 spec->hp_independent_mode && spec->codec_type != VT1718S)
1390 continue; /* don't retask FMic for independent HP */ 1389 continue; /* don't retask FMic for independent HP */
1391 if (nid) { 1390
1392 unsigned int parm = snd_hda_codec_read( 1391 parm = snd_hda_codec_read(codec, nid, 0,
1393 codec, nid, 0, 1392 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1394 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 1393 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1395 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); 1394 parm |= out_in;
1396 parm |= out_in; 1395 snd_hda_codec_write(codec, nid, 0,
1397 snd_hda_codec_write(codec, nid, 0, 1396 AC_VERB_SET_PIN_WIDGET_CONTROL,
1398 AC_VERB_SET_PIN_WIDGET_CONTROL, 1397 parm);
1399 parm); 1398 if (out_in == AC_PINCTL_OUT_EN) {
1400 if (out_in == AC_PINCTL_OUT_EN) { 1399 mute_aa_path(codec, 1);
1401 mute_aa_path(codec, 1); 1400 notify_aa_path_ctls(codec);
1402 notify_aa_path_ctls(codec); 1401 }
1403 } 1402 if (spec->codec_type == VT1718S) {
1404 if (spec->codec_type == VT1718S) 1403 snd_hda_codec_amp_stereo(
1405 snd_hda_codec_amp_stereo(
1406 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, 1404 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1407 HDA_AMP_UNMUTE); 1405 HDA_AMP_UNMUTE);
1408 } 1406 }
1409 if (i == AUTO_PIN_FRONT_MIC) { 1407 if (cfg->inputs[i].type == AUTO_PIN_MIC) {
1410 if (spec->codec_type == VT1708S 1408 if (spec->codec_type == VT1708S
1411 || spec->codec_type == VT1716S) { 1409 || spec->codec_type == VT1716S) {
1412 /* input = index 1 (AOW3) */ 1410 /* input = index 1 (AOW3) */
@@ -1442,7 +1440,7 @@ static struct snd_kcontrol_new via_smart51_mixer[2] = {
1442static int via_smart51_build(struct via_spec *spec) 1440static int via_smart51_build(struct via_spec *spec)
1443{ 1441{
1444 struct snd_kcontrol_new *knew; 1442 struct snd_kcontrol_new *knew;
1445 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; 1443 const struct auto_pin_cfg *cfg = &spec->autocfg;
1446 hda_nid_t nid; 1444 hda_nid_t nid;
1447 int i; 1445 int i;
1448 1446
@@ -1450,13 +1448,14 @@ static int via_smart51_build(struct via_spec *spec)
1450 if (knew == NULL) 1448 if (knew == NULL)
1451 return -ENOMEM; 1449 return -ENOMEM;
1452 1450
1453 for (i = 0; i < ARRAY_SIZE(index); i++) { 1451 for (i = 0; i < cfg->num_inputs; i++) {
1454 nid = spec->autocfg.input_pins[index[i]]; 1452 nid = cfg->inputs[i].pin;
1455 if (nid) { 1453 if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) {
1456 knew = via_clone_control(spec, &via_smart51_mixer[1]); 1454 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1457 if (knew == NULL) 1455 if (knew == NULL)
1458 return -ENOMEM; 1456 return -ENOMEM;
1459 knew->subdevice = nid; 1457 knew->subdevice = nid;
1458 break;
1460 } 1459 }
1461 } 1460 }
1462 1461
@@ -2375,13 +2374,8 @@ static void create_hp_imux(struct via_spec *spec)
2375 static const char *texts[] = { "OFF", "ON", NULL}; 2374 static const char *texts[] = { "OFF", "ON", NULL};
2376 2375
2377 /* for hp mode select */ 2376 /* for hp mode select */
2378 i = 0; 2377 for (i = 0; texts[i]; i++)
2379 while (texts[i] != NULL) { 2378 snd_hda_add_imux_item(imux, texts[i], i, NULL);
2380 imux->items[imux->num_items].label = texts[i];
2381 imux->items[imux->num_items].index = i;
2382 imux->num_items++;
2383 i++;
2384 }
2385 2379
2386 spec->hp_mux = &spec->private_imux[1]; 2380 spec->hp_mux = &spec->private_imux[1];
2387} 2381}
@@ -2413,51 +2407,53 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2413} 2407}
2414 2408
2415/* create playback/capture controls for input pins */ 2409/* create playback/capture controls for input pins */
2416static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, 2410static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
2417 const struct auto_pin_cfg *cfg) 2411 const struct auto_pin_cfg *cfg,
2412 hda_nid_t cap_nid,
2413 hda_nid_t pin_idxs[], int num_idxs)
2418{ 2414{
2419 static char *labels[] = { 2415 struct via_spec *spec = codec->spec;
2420 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2421 };
2422 struct hda_input_mux *imux = &spec->private_imux[0]; 2416 struct hda_input_mux *imux = &spec->private_imux[0];
2423 int i, err, idx = 0; 2417 int i, err, idx, type, type_idx = 0;
2424 2418
2425 /* for internal loopback recording select */ 2419 /* for internal loopback recording select */
2426 imux->items[imux->num_items].label = "Stereo Mixer"; 2420 for (idx = 0; idx < num_idxs; idx++) {
2427 imux->items[imux->num_items].index = idx; 2421 if (pin_idxs[idx] == 0xff) {
2428 imux->num_items++; 2422 snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL);
2429
2430 for (i = 0; i < AUTO_PIN_LAST; i++) {
2431 if (!cfg->input_pins[i])
2432 continue;
2433
2434 switch (cfg->input_pins[i]) {
2435 case 0x1d: /* Mic */
2436 idx = 2;
2437 break;
2438
2439 case 0x1e: /* Line In */
2440 idx = 3;
2441 break;
2442
2443 case 0x21: /* Front Mic */
2444 idx = 4;
2445 break;
2446
2447 case 0x24: /* CD */
2448 idx = 1;
2449 break; 2423 break;
2450 } 2424 }
2451 err = via_new_analog_input(spec, labels[i], idx, 0x17); 2425 }
2426
2427 for (i = 0; i < cfg->num_inputs; i++) {
2428 const char *label;
2429 type = cfg->inputs[i].type;
2430 for (idx = 0; idx < num_idxs; idx++)
2431 if (pin_idxs[idx] == cfg->inputs[i].pin)
2432 break;
2433 if (idx >= num_idxs)
2434 continue;
2435 if (i > 0 && type == cfg->inputs[i - 1].type)
2436 type_idx++;
2437 else
2438 type_idx = 0;
2439 label = hda_get_autocfg_input_label(codec, cfg, i);
2440 err = via_new_analog_input(spec, label, type_idx, idx, cap_nid);
2452 if (err < 0) 2441 if (err < 0)
2453 return err; 2442 return err;
2454 imux->items[imux->num_items].label = labels[i]; 2443 snd_hda_add_imux_item(imux, label, idx, NULL);
2455 imux->items[imux->num_items].index = idx;
2456 imux->num_items++;
2457 } 2444 }
2458 return 0; 2445 return 0;
2459} 2446}
2460 2447
2448/* create playback/capture controls for input pins */
2449static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec,
2450 const struct auto_pin_cfg *cfg)
2451{
2452 static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
2453 return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs,
2454 ARRAY_SIZE(pin_idxs));
2455}
2456
2461#ifdef CONFIG_SND_HDA_POWER_SAVE 2457#ifdef CONFIG_SND_HDA_POWER_SAVE
2462static struct hda_amp_list vt1708_loopbacks[] = { 2458static struct hda_amp_list vt1708_loopbacks[] = {
2463 { 0x17, HDA_INPUT, 1 }, 2459 { 0x17, HDA_INPUT, 1 },
@@ -2554,7 +2550,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
2554 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 2550 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2555 if (err < 0) 2551 if (err < 0)
2556 return err; 2552 return err;
2557 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg); 2553 err = vt1708_auto_create_analog_input_ctls(codec, &spec->autocfg);
2558 if (err < 0) 2554 if (err < 0)
2559 return err; 2555 return err;
2560 /* add jack detect on/off control */ 2556 /* add jack detect on/off control */
@@ -3021,49 +3017,12 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3021} 3017}
3022 3018
3023/* create playback/capture controls for input pins */ 3019/* create playback/capture controls for input pins */
3024static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec, 3020static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
3025 const struct auto_pin_cfg *cfg) 3021 const struct auto_pin_cfg *cfg)
3026{ 3022{
3027 static char *labels[] = { 3023 static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
3028 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 3024 return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
3029 }; 3025 ARRAY_SIZE(pin_idxs));
3030 struct hda_input_mux *imux = &spec->private_imux[0];
3031 int i, err, idx = 0;
3032
3033 /* for internal loopback recording select */
3034 imux->items[imux->num_items].label = "Stereo Mixer";
3035 imux->items[imux->num_items].index = idx;
3036 imux->num_items++;
3037
3038 for (i = 0; i < AUTO_PIN_LAST; i++) {
3039 if (!cfg->input_pins[i])
3040 continue;
3041
3042 switch (cfg->input_pins[i]) {
3043 case 0x1d: /* Mic */
3044 idx = 2;
3045 break;
3046
3047 case 0x1e: /* Line In */
3048 idx = 3;
3049 break;
3050
3051 case 0x21: /* Front Mic */
3052 idx = 4;
3053 break;
3054
3055 case 0x23: /* CD */
3056 idx = 1;
3057 break;
3058 }
3059 err = via_new_analog_input(spec, labels[i], idx, 0x18);
3060 if (err < 0)
3061 return err;
3062 imux->items[imux->num_items].label = labels[i];
3063 imux->items[imux->num_items].index = idx;
3064 imux->num_items++;
3065 }
3066 return 0;
3067} 3026}
3068 3027
3069static int vt1709_parse_auto_config(struct hda_codec *codec) 3028static int vt1709_parse_auto_config(struct hda_codec *codec)
@@ -3086,7 +3045,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3086 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 3045 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3087 if (err < 0) 3046 if (err < 0)
3088 return err; 3047 return err;
3089 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg); 3048 err = vt1709_auto_create_analog_input_ctls(codec, &spec->autocfg);
3090 if (err < 0) 3049 if (err < 0)
3091 return err; 3050 return err;
3092 3051
@@ -3588,49 +3547,12 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3588} 3547}
3589 3548
3590/* create playback/capture controls for input pins */ 3549/* create playback/capture controls for input pins */
3591static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec, 3550static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
3592 const struct auto_pin_cfg *cfg) 3551 const struct auto_pin_cfg *cfg)
3593{ 3552{
3594 static char *labels[] = { 3553 static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3595 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 3554 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3596 }; 3555 ARRAY_SIZE(pin_idxs));
3597 struct hda_input_mux *imux = &spec->private_imux[0];
3598 int i, err, idx = 0;
3599
3600 /* for internal loopback recording select */
3601 imux->items[imux->num_items].label = "Stereo Mixer";
3602 imux->items[imux->num_items].index = idx;
3603 imux->num_items++;
3604
3605 for (i = 0; i < AUTO_PIN_LAST; i++) {
3606 if (!cfg->input_pins[i])
3607 continue;
3608
3609 switch (cfg->input_pins[i]) {
3610 case 0x1a: /* Mic */
3611 idx = 2;
3612 break;
3613
3614 case 0x1b: /* Line In */
3615 idx = 3;
3616 break;
3617
3618 case 0x1e: /* Front Mic */
3619 idx = 4;
3620 break;
3621
3622 case 0x1f: /* CD */
3623 idx = 1;
3624 break;
3625 }
3626 err = via_new_analog_input(spec, labels[i], idx, 0x16);
3627 if (err < 0)
3628 return err;
3629 imux->items[imux->num_items].label = labels[i];
3630 imux->items[imux->num_items].index = idx;
3631 imux->num_items++;
3632 }
3633 return 0;
3634} 3556}
3635 3557
3636static int vt1708B_parse_auto_config(struct hda_codec *codec) 3558static int vt1708B_parse_auto_config(struct hda_codec *codec)
@@ -3653,7 +3575,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3653 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 3575 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3654 if (err < 0) 3576 if (err < 0)
3655 return err; 3577 return err;
3656 err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg); 3578 err = vt1708B_auto_create_analog_input_ctls(codec, &spec->autocfg);
3657 if (err < 0) 3579 if (err < 0)
3658 return err; 3580 return err;
3659 3581
@@ -4061,49 +3983,12 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4061} 3983}
4062 3984
4063/* create playback/capture controls for input pins */ 3985/* create playback/capture controls for input pins */
4064static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec, 3986static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
4065 const struct auto_pin_cfg *cfg) 3987 const struct auto_pin_cfg *cfg)
4066{ 3988{
4067 static char *labels[] = { 3989 static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
4068 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 3990 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
4069 }; 3991 ARRAY_SIZE(pin_idxs));
4070 struct hda_input_mux *imux = &spec->private_imux[0];
4071 int i, err, idx = 0;
4072
4073 /* for internal loopback recording select */
4074 imux->items[imux->num_items].label = "Stereo Mixer";
4075 imux->items[imux->num_items].index = 5;
4076 imux->num_items++;
4077
4078 for (i = 0; i < AUTO_PIN_LAST; i++) {
4079 if (!cfg->input_pins[i])
4080 continue;
4081
4082 switch (cfg->input_pins[i]) {
4083 case 0x1a: /* Mic */
4084 idx = 2;
4085 break;
4086
4087 case 0x1b: /* Line In */
4088 idx = 3;
4089 break;
4090
4091 case 0x1e: /* Front Mic */
4092 idx = 4;
4093 break;
4094
4095 case 0x1f: /* CD */
4096 idx = 1;
4097 break;
4098 }
4099 err = via_new_analog_input(spec, labels[i], idx, 0x16);
4100 if (err < 0)
4101 return err;
4102 imux->items[imux->num_items].label = labels[i];
4103 imux->items[imux->num_items].index = idx-1;
4104 imux->num_items++;
4105 }
4106 return 0;
4107} 3992}
4108 3993
4109/* fill out digital output widgets; one for master and one for slave outputs */ 3994/* fill out digital output widgets; one for master and one for slave outputs */
@@ -4151,7 +4036,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4151 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 4036 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4152 if (err < 0) 4037 if (err < 0)
4153 return err; 4038 return err;
4154 err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg); 4039 err = vt1708S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4155 if (err < 0) 4040 if (err < 0)
4156 return err; 4041 return err;
4157 4042
@@ -4441,58 +4326,20 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4441 imux = &spec->private_imux[1]; 4326 imux = &spec->private_imux[1];
4442 4327
4443 /* for hp mode select */ 4328 /* for hp mode select */
4444 i = 0; 4329 for (i = 0; texts[i]; i++)
4445 while (texts[i] != NULL) { 4330 snd_hda_add_imux_item(imux, texts[i], i, NULL);
4446 imux->items[imux->num_items].label = texts[i];
4447 imux->items[imux->num_items].index = i;
4448 imux->num_items++;
4449 i++;
4450 }
4451 4331
4452 spec->hp_mux = &spec->private_imux[1]; 4332 spec->hp_mux = &spec->private_imux[1];
4453 return 0; 4333 return 0;
4454} 4334}
4455 4335
4456/* create playback/capture controls for input pins */ 4336/* create playback/capture controls for input pins */
4457static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec, 4337static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec,
4458 const struct auto_pin_cfg *cfg) 4338 const struct auto_pin_cfg *cfg)
4459{ 4339{
4460 static char *labels[] = { 4340 static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
4461 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 4341 return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs,
4462 }; 4342 ARRAY_SIZE(pin_idxs));
4463 struct hda_input_mux *imux = &spec->private_imux[0];
4464 int i, err, idx = 0;
4465
4466 /* for internal loopback recording select */
4467 imux->items[imux->num_items].label = "Stereo Mixer";
4468 imux->items[imux->num_items].index = 3;
4469 imux->num_items++;
4470
4471 for (i = 0; i < AUTO_PIN_LAST; i++) {
4472 if (!cfg->input_pins[i])
4473 continue;
4474
4475 switch (cfg->input_pins[i]) {
4476 case 0x14: /* Mic */
4477 idx = 1;
4478 break;
4479
4480 case 0x15: /* Line In */
4481 idx = 2;
4482 break;
4483
4484 case 0x18: /* Front Mic */
4485 idx = 3;
4486 break;
4487 }
4488 err = via_new_analog_input(spec, labels[i], idx, 0x1A);
4489 if (err < 0)
4490 return err;
4491 imux->items[imux->num_items].label = labels[i];
4492 imux->items[imux->num_items].index = idx-1;
4493 imux->num_items++;
4494 }
4495 return 0;
4496} 4343}
4497 4344
4498static int vt1702_parse_auto_config(struct hda_codec *codec) 4345static int vt1702_parse_auto_config(struct hda_codec *codec)
@@ -4521,7 +4368,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4521 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 4368 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4522 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) | 4369 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4523 (1 << AC_AMPCAP_MUTE_SHIFT)); 4370 (1 << AC_AMPCAP_MUTE_SHIFT));
4524 err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg); 4371 err = vt1702_auto_create_analog_input_ctls(codec, &spec->autocfg);
4525 if (err < 0) 4372 if (err < 0)
4526 return err; 4373 return err;
4527 4374
@@ -4872,49 +4719,12 @@ static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4872} 4719}
4873 4720
4874/* create playback/capture controls for input pins */ 4721/* create playback/capture controls for input pins */
4875static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec, 4722static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec,
4876 const struct auto_pin_cfg *cfg) 4723 const struct auto_pin_cfg *cfg)
4877{ 4724{
4878 static char *labels[] = { 4725 static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
4879 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 4726 return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
4880 }; 4727 ARRAY_SIZE(pin_idxs));
4881 struct hda_input_mux *imux = &spec->private_imux[0];
4882 int i, err, idx = 0;
4883
4884 /* for internal loopback recording select */
4885 imux->items[imux->num_items].label = "Stereo Mixer";
4886 imux->items[imux->num_items].index = 5;
4887 imux->num_items++;
4888
4889 for (i = 0; i < AUTO_PIN_LAST; i++) {
4890 if (!cfg->input_pins[i])
4891 continue;
4892
4893 switch (cfg->input_pins[i]) {
4894 case 0x2b: /* Mic */
4895 idx = 1;
4896 break;
4897
4898 case 0x2a: /* Line In */
4899 idx = 2;
4900 break;
4901
4902 case 0x29: /* Front Mic */
4903 idx = 3;
4904 break;
4905
4906 case 0x2c: /* CD */
4907 idx = 0;
4908 break;
4909 }
4910 err = via_new_analog_input(spec, labels[i], idx, 0x21);
4911 if (err < 0)
4912 return err;
4913 imux->items[imux->num_items].label = labels[i];
4914 imux->items[imux->num_items].index = idx;
4915 imux->num_items++;
4916 }
4917 return 0;
4918} 4728}
4919 4729
4920static int vt1718S_parse_auto_config(struct hda_codec *codec) 4730static int vt1718S_parse_auto_config(struct hda_codec *codec)
@@ -4938,7 +4748,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4938 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 4748 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4939 if (err < 0) 4749 if (err < 0)
4940 return err; 4750 return err;
4941 err = vt1718S_auto_create_analog_input_ctls(spec, &spec->autocfg); 4751 err = vt1718S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4942 if (err < 0) 4752 if (err < 0)
4943 return err; 4753 return err;
4944 4754
@@ -5371,49 +5181,12 @@ static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5371} 5181}
5372 5182
5373/* create playback/capture controls for input pins */ 5183/* create playback/capture controls for input pins */
5374static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec, 5184static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec,
5375 const struct auto_pin_cfg *cfg) 5185 const struct auto_pin_cfg *cfg)
5376{ 5186{
5377 static char *labels[] = { 5187 static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
5378 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 5188 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
5379 }; 5189 ARRAY_SIZE(pin_idxs));
5380 struct hda_input_mux *imux = &spec->private_imux[0];
5381 int i, err, idx = 0;
5382
5383 /* for internal loopback recording select */
5384 imux->items[imux->num_items].label = "Stereo Mixer";
5385 imux->items[imux->num_items].index = 5;
5386 imux->num_items++;
5387
5388 for (i = 0; i < AUTO_PIN_LAST; i++) {
5389 if (!cfg->input_pins[i])
5390 continue;
5391
5392 switch (cfg->input_pins[i]) {
5393 case 0x1a: /* Mic */
5394 idx = 2;
5395 break;
5396
5397 case 0x1b: /* Line In */
5398 idx = 3;
5399 break;
5400
5401 case 0x1e: /* Front Mic */
5402 idx = 4;
5403 break;
5404
5405 case 0x1f: /* CD */
5406 idx = 1;
5407 break;
5408 }
5409 err = via_new_analog_input(spec, labels[i], idx, 0x16);
5410 if (err < 0)
5411 return err;
5412 imux->items[imux->num_items].label = labels[i];
5413 imux->items[imux->num_items].index = idx-1;
5414 imux->num_items++;
5415 }
5416 return 0;
5417} 5190}
5418 5191
5419static int vt1716S_parse_auto_config(struct hda_codec *codec) 5192static int vt1716S_parse_auto_config(struct hda_codec *codec)
@@ -5436,7 +5209,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5436 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 5209 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5437 if (err < 0) 5210 if (err < 0)
5438 return err; 5211 return err;
5439 err = vt1716S_auto_create_analog_input_ctls(spec, &spec->autocfg); 5212 err = vt1716S_auto_create_analog_input_ctls(codec, &spec->autocfg);
5440 if (err < 0) 5213 if (err < 0)
5441 return err; 5214 return err;
5442 5215
@@ -5717,54 +5490,25 @@ static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5717} 5490}
5718 5491
5719/* create playback/capture controls for input pins */ 5492/* create playback/capture controls for input pins */
5720static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec, 5493static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec,
5721 const struct auto_pin_cfg *cfg) 5494 const struct auto_pin_cfg *cfg)
5722{ 5495{
5723 static char *labels[] = { 5496 struct via_spec *spec = codec->spec;
5724 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
5725 };
5726 struct hda_input_mux *imux = &spec->private_imux[0]; 5497 struct hda_input_mux *imux = &spec->private_imux[0];
5727 int i, err, idx = 0; 5498 static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
5728 5499 int err;
5729 for (i = 0; i < AUTO_PIN_LAST; i++) {
5730 if (!cfg->input_pins[i])
5731 continue;
5732
5733 switch (cfg->input_pins[i]) {
5734 case 0x2b: /* Mic */
5735 idx = 0;
5736 break;
5737
5738 case 0x2a: /* Line In */
5739 idx = 1;
5740 break;
5741
5742 case 0x29: /* Front Mic */
5743 idx = 2;
5744 break;
5745 }
5746 err = via_new_analog_input(spec, labels[i], idx, 0x21);
5747 if (err < 0)
5748 return err;
5749 imux->items[imux->num_items].label = labels[i];
5750 imux->items[imux->num_items].index = idx;
5751 imux->num_items++;
5752 }
5753 5500
5501 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5502 ARRAY_SIZE(pin_idxs));
5503 if (err < 0)
5504 return err;
5754 /* build volume/mute control of loopback */ 5505 /* build volume/mute control of loopback */
5755 err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21); 5506 err = via_new_analog_input(spec, "Stereo Mixer", 0, 3, 0x21);
5756 if (err < 0) 5507 if (err < 0)
5757 return err; 5508 return err;
5758 5509
5759 /* for internal loopback recording select */
5760 imux->items[imux->num_items].label = "Stereo Mixer";
5761 imux->items[imux->num_items].index = 3;
5762 imux->num_items++;
5763
5764 /* for digital mic select */ 5510 /* for digital mic select */
5765 imux->items[imux->num_items].label = "Digital Mic"; 5511 snd_hda_add_imux_item(imux, "Digital Mic", 4, NULL);
5766 imux->items[imux->num_items].index = 4;
5767 imux->num_items++;
5768 5512
5769 return 0; 5513 return 0;
5770} 5514}
@@ -5792,7 +5536,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5792 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 5536 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5793 if (err < 0) 5537 if (err < 0)
5794 return err; 5538 return err;
5795 err = vt2002P_auto_create_analog_input_ctls(spec, &spec->autocfg); 5539 err = vt2002P_auto_create_analog_input_ctls(codec, &spec->autocfg);
5796 if (err < 0) 5540 if (err < 0)
5797 return err; 5541 return err;
5798 5542
@@ -6067,53 +5811,26 @@ static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
6067} 5811}
6068 5812
6069/* create playback/capture controls for input pins */ 5813/* create playback/capture controls for input pins */
6070static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec, 5814static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec,
6071 const struct auto_pin_cfg *cfg) 5815 const struct auto_pin_cfg *cfg)
6072{ 5816{
6073 static char *labels[] = { 5817 struct via_spec *spec = codec->spec;
6074 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
6075 };
6076 struct hda_input_mux *imux = &spec->private_imux[0]; 5818 struct hda_input_mux *imux = &spec->private_imux[0];
6077 int i, err, idx = 0; 5819 static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
6078 5820 int err;
6079 for (i = 0; i < AUTO_PIN_LAST; i++) {
6080 if (!cfg->input_pins[i])
6081 continue;
6082
6083 switch (cfg->input_pins[i]) {
6084 case 0x2b: /* Mic */
6085 idx = 0;
6086 break;
6087 5821
6088 case 0x2a: /* Line In */ 5822 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
6089 idx = 1; 5823 ARRAY_SIZE(pin_idxs));
6090 break; 5824 if (err < 0)
5825 return err;
6091 5826
6092 case 0x29: /* Front Mic */
6093 idx = 2;
6094 break;
6095 }
6096 err = via_new_analog_input(spec, labels[i], idx, 0x21);
6097 if (err < 0)
6098 return err;
6099 imux->items[imux->num_items].label = labels[i];
6100 imux->items[imux->num_items].index = idx;
6101 imux->num_items++;
6102 }
6103 /* build volume/mute control of loopback */ 5827 /* build volume/mute control of loopback */
6104 err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21); 5828 err = via_new_analog_input(spec, "Stereo Mixer", 0, 5, 0x21);
6105 if (err < 0) 5829 if (err < 0)
6106 return err; 5830 return err;
6107 5831
6108 /* for internal loopback recording select */
6109 imux->items[imux->num_items].label = "Stereo Mixer";
6110 imux->items[imux->num_items].index = 5;
6111 imux->num_items++;
6112
6113 /* for digital mic select */ 5832 /* for digital mic select */
6114 imux->items[imux->num_items].label = "Digital Mic"; 5833 snd_hda_add_imux_item(imux, "Digital Mic", 6, NULL);
6115 imux->items[imux->num_items].index = 6;
6116 imux->num_items++;
6117 5834
6118 return 0; 5835 return 0;
6119} 5836}
@@ -6141,7 +5858,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6141 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 5858 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
6142 if (err < 0) 5859 if (err < 0)
6143 return err; 5860 return err;
6144 err = vt1812_auto_create_analog_input_ctls(spec, &spec->autocfg); 5861 err = vt1812_auto_create_analog_input_ctls(codec, &spec->autocfg);
6145 if (err < 0) 5862 if (err < 0)
6146 return err; 5863 return err;
6147 5864