aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-12-14 10:54:44 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-12 02:30:10 -0500
commitfef7fbbc5d6643513b27a706ed02ed4c46a0eef2 (patch)
tree52f9567d63fe8b32f83888ccfc34d6d921a7ebfb
parentc9967f1cbadd3a6af2be54a5baed2cc0dcef50e6 (diff)
ALSA: hda/realtek - Use path-based parser for digital outputs
Similar like analog output paths, use the path list for parsing and initializing digital outputs as well. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/patch_realtek.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9a38107cf0f5..e25b13a09e58 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1424,6 +1424,14 @@ static unsigned int alc_get_coef0(struct hda_codec *codec)
1424 return spec->coef0; 1424 return spec->coef0;
1425} 1425}
1426 1426
1427static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
1428 hda_nid_t pin, int pin_type,
1429 hda_nid_t dac);
1430static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin,
1431 bool is_digital);
1432static bool add_new_out_path(struct hda_codec *codec, hda_nid_t pin,
1433 hda_nid_t dac);
1434
1427/* 1435/*
1428 * Digital I/O handling 1436 * Digital I/O handling
1429 */ 1437 */
@@ -1433,22 +1441,13 @@ static void alc_auto_init_digital(struct hda_codec *codec)
1433{ 1441{
1434 struct alc_spec *spec = codec->spec; 1442 struct alc_spec *spec = codec->spec;
1435 int i; 1443 int i;
1436 hda_nid_t pin, dac; 1444 hda_nid_t pin;
1437 1445
1438 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1446 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1439 pin = spec->autocfg.dig_out_pins[i]; 1447 pin = spec->autocfg.dig_out_pins[i];
1440 if (!pin) 1448 if (!pin)
1441 continue; 1449 continue;
1442 snd_hda_set_pin_ctl(codec, pin, PIN_OUT); 1450 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
1443 if (!i)
1444 dac = spec->multiout.dig_out_nid;
1445 else
1446 dac = spec->slave_dig_outs[i - 1];
1447 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
1448 continue;
1449 snd_hda_codec_write(codec, dac, 0,
1450 AC_VERB_SET_AMP_GAIN_MUTE,
1451 AMP_OUT_UNMUTE);
1452 } 1451 }
1453 pin = spec->autocfg.dig_in_pin; 1452 pin = spec->autocfg.dig_in_pin;
1454 if (pin) 1453 if (pin)
@@ -1465,13 +1464,10 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
1465 /* support multiple SPDIFs; the secondary is set up as a slave */ 1464 /* support multiple SPDIFs; the secondary is set up as a slave */
1466 nums = 0; 1465 nums = 0;
1467 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1466 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1468 hda_nid_t conn[4]; 1467 hda_nid_t pin = spec->autocfg.dig_out_pins[i];
1469 err = snd_hda_get_connections(codec, 1468 dig_nid = alc_auto_look_for_dac(codec, pin, true);
1470 spec->autocfg.dig_out_pins[i], 1469 if (!dig_nid)
1471 conn, ARRAY_SIZE(conn));
1472 if (err <= 0)
1473 continue; 1470 continue;
1474 dig_nid = conn[0]; /* assume the first element is audio-out */
1475 if (!nums) { 1471 if (!nums) {
1476 spec->multiout.dig_out_nid = dig_nid; 1472 spec->multiout.dig_out_nid = dig_nid;
1477 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1473 spec->dig_out_type = spec->autocfg.dig_out_type[0];
@@ -1481,6 +1477,7 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
1481 break; 1477 break;
1482 spec->slave_dig_outs[nums - 1] = dig_nid; 1478 spec->slave_dig_outs[nums - 1] = dig_nid;
1483 } 1479 }
1480 add_new_out_path(codec, pin, dig_nid);
1484 nums++; 1481 nums++;
1485 } 1482 }
1486 1483
@@ -2895,15 +2892,20 @@ static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
2895} 2892}
2896 2893
2897/* look for an empty DAC slot */ 2894/* look for an empty DAC slot */
2898static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 2895static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin,
2896 bool is_digital)
2899{ 2897{
2900 struct alc_spec *spec = codec->spec; 2898 struct alc_spec *spec = codec->spec;
2899 bool cap_digital;
2901 int i; 2900 int i;
2902 2901
2903 for (i = 0; i < spec->num_all_dacs; i++) { 2902 for (i = 0; i < spec->num_all_dacs; i++) {
2904 hda_nid_t nid = spec->all_dacs[i]; 2903 hda_nid_t nid = spec->all_dacs[i];
2905 if (!nid || alc_is_dac_already_used(codec, nid)) 2904 if (!nid || alc_is_dac_already_used(codec, nid))
2906 continue; 2905 continue;
2906 cap_digital = !!(get_wcaps(codec, nid) & AC_WCAP_DIGITAL);
2907 if (is_digital != cap_digital)
2908 continue;
2907 if (is_reachable_path(codec, nid, pin)) 2909 if (is_reachable_path(codec, nid, pin))
2908 return nid; 2910 return nid;
2909 } 2911 }
@@ -3169,7 +3171,7 @@ static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
3169 for (i = 0; i < num_outs; i++) { 3171 for (i = 0; i < num_outs; i++) {
3170 hda_nid_t pin = pins[i]; 3172 hda_nid_t pin = pins[i];
3171 if (!dacs[i]) 3173 if (!dacs[i])
3172 dacs[i] = alc_auto_look_for_dac(codec, pin); 3174 dacs[i] = alc_auto_look_for_dac(codec, pin, false);
3173 if (!dacs[i] && !i) { 3175 if (!dacs[i] && !i) {
3174 for (j = 1; j < num_outs; j++) { 3176 for (j = 1; j < num_outs; j++) {
3175 if (is_reachable_path(codec, dacs[j], pin)) { 3177 if (is_reachable_path(codec, dacs[j], pin)) {
@@ -4110,7 +4112,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec,
4110 if (hardwired) 4112 if (hardwired)
4111 dac = get_dac_if_single(codec, nid); 4113 dac = get_dac_if_single(codec, nid);
4112 else if (!dac) 4114 else if (!dac)
4113 dac = alc_auto_look_for_dac(codec, nid); 4115 dac = alc_auto_look_for_dac(codec, nid, false);
4114 if (!dac) { 4116 if (!dac) {
4115 badness++; 4117 badness++;
4116 continue; 4118 continue;