diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-08-30 07:06:30 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-08-30 07:06:30 -0400 |
commit | 7b315bb4980448250c80a7464c256b54d546cb26 (patch) | |
tree | bfc0466dd84f936be976797ed47aa48fb64a7527 /sound/pci/hda/patch_via.c | |
parent | eea7dc932bfa802ad0377755ea821f416f4f8623 (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.c | 144 |
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 */ |
447 | static int via_add_control(struct via_spec *spec, int type, const char *name, | 447 | static 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 | |||
466 | static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, | 469 | static 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 */ |
496 | static int via_new_analog_input(struct via_spec *spec, const char *ctlname, | 499 | static 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); | |||
557 | static void via_auto_init_analog_input(struct hda_codec *codec) | 560 | static 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 | } |
1323 | static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) | 1324 | static 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 | ||
1336 | static int via_smart51_info(struct snd_kcontrol *kcontrol, | 1336 | static 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] = { | |||
1442 | static int via_smart51_build(struct via_spec *spec) | 1440 | static 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 | ||