aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_via.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-08-30 07:06:30 -0400
committerTakashi Iwai <tiwai@suse.de>2010-08-30 07:06:30 -0400
commit7b315bb4980448250c80a7464c256b54d546cb26 (patch)
treebfc0466dd84f936be976797ed47aa48fb64a7527 /sound/pci/hda/patch_via.c
parenteea7dc932bfa802ad0377755ea821f416f4f8623 (diff)
ALSA: hda - Use new inputs[] field to parse input-pins for VIA codecs
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r--sound/pci/hda/patch_via.c144
1 files changed, 73 insertions, 71 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 41861388f43a..93b86adbce63 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,14 +560,12 @@ 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_FRONT_MIC)
@@ -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_FRONT_LINE;
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_FRONT_LINE)
1360 AC_VERB_GET_PIN_WIDGET_CONTROL, 1360 continue;
1361 0); 1361 if (cfg->inputs[i].type == AUTO_PIN_FRONT_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_FRONT_LINE)
1386 continue;
1387 if (cfg->inputs[i].type == AUTO_PIN_FRONT_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_FRONT_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_FRONT_LINE) {
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
@@ -2419,7 +2418,7 @@ static int vt_auto_create_analog_input_ctls(struct via_spec *spec,
2419 hda_nid_t pin_idxs[], int num_idxs) 2418 hda_nid_t pin_idxs[], int num_idxs)
2420{ 2419{
2421 struct hda_input_mux *imux = &spec->private_imux[0]; 2420 struct hda_input_mux *imux = &spec->private_imux[0];
2422 int i, err, idx; 2421 int i, err, idx, type, type_idx = 0;
2423 2422
2424 /* for internal loopback recording select */ 2423 /* for internal loopback recording select */
2425 for (idx = 0; idx < num_idxs; idx++) { 2424 for (idx = 0; idx < num_idxs; idx++) {
@@ -2431,20 +2430,23 @@ static int vt_auto_create_analog_input_ctls(struct via_spec *spec,
2431 } 2430 }
2432 } 2431 }
2433 2432
2434 for (i = 0; i < AUTO_PIN_LAST; i++) { 2433 for (i = 0; i < cfg->num_inputs; i++) {
2435 if (!cfg->input_pins[i]) 2434 type = cfg->inputs[i].type;
2436 continue;
2437
2438 for (idx = 0; idx < num_idxs; idx++) 2435 for (idx = 0; idx < num_idxs; idx++)
2439 if (pin_idxs[idx] == cfg->input_pins[i]) 2436 if (pin_idxs[idx] == cfg->inputs[i].pin)
2440 break; 2437 break;
2441 if (idx >= num_idxs) 2438 if (idx >= num_idxs)
2442 continue; 2439 continue;
2443 err = via_new_analog_input(spec, auto_pin_cfg_labels[i], 2440 if (i > 0 && type == cfg->inputs[i - 1].type)
2444 idx, cap_nid); 2441 type_idx++;
2442 else
2443 type_idx = 0;
2444 err = via_new_analog_input(spec, auto_pin_cfg_labels[type],
2445 type_idx, idx, cap_nid);
2445 if (err < 0) 2446 if (err < 0)
2446 return err; 2447 return err;
2447 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 2448 imux->items[imux->num_items].label =
2449 snd_hda_get_input_pin_label(cfg, i);
2448 imux->items[imux->num_items].index = idx; 2450 imux->items[imux->num_items].index = idx;
2449 imux->num_items++; 2451 imux->num_items++;
2450 } 2452 }
@@ -5513,7 +5515,7 @@ static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec,
5513 if (err < 0) 5515 if (err < 0)
5514 return err; 5516 return err;
5515 /* build volume/mute control of loopback */ 5517 /* build volume/mute control of loopback */
5516 err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21); 5518 err = via_new_analog_input(spec, "Stereo Mixer", 0, 3, 0x21);
5517 if (err < 0) 5519 if (err < 0)
5518 return err; 5520 return err;
5519 5521
@@ -5836,7 +5838,7 @@ static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec,
5836 return err; 5838 return err;
5837 5839
5838 /* build volume/mute control of loopback */ 5840 /* build volume/mute control of loopback */
5839 err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21); 5841 err = via_new_analog_input(spec, "Stereo Mixer", 0, 5, 0x21);
5840 if (err < 0) 5842 if (err < 0)
5841 return err; 5843 return err;
5842 5844