aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-04 09:01:40 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-12 02:43:37 -0500
commit196c17668056ed5226070d06878242c116dfece2 (patch)
tree36fe0f1463d530d762d886cffff4cda258c03d62
parent05453b7e97996a37db4dd7b97a788124b117dbde (diff)
ALSA: hda - Manage using output/loopback path indices
Instead of search for the path with the certain route at each time, keep the path index for each output and loopback, and just use it when referred. In this implementation, the path index number begins with one, not zero (although I've been writing in C over decades). It's just to make the check for uninitialized values easier. So far, the input paths aren't handled with indices yet, but still picked up via snd_hda_get_nid_path() at each time. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_generic.c139
-rw-r--r--sound/pci/hda/hda_generic.h9
2 files changed, 98 insertions, 50 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 93db02121efb..c8bf81230206 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -147,6 +147,33 @@ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
147} 147}
148EXPORT_SYMBOL_HDA(snd_hda_get_nid_path); 148EXPORT_SYMBOL_HDA(snd_hda_get_nid_path);
149 149
150/* get the index number corresponding to the path instance;
151 * the index starts from 1, for easier checking the invalid value
152 */
153int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path)
154{
155 struct hda_gen_spec *spec = codec->spec;
156 struct nid_path *array = spec->paths.list;
157 ssize_t idx;
158
159 if (!spec->paths.used)
160 return 0;
161 idx = path - array;
162 if (idx < 0 || idx >= spec->paths.used)
163 return 0;
164 return idx + 1;
165}
166
167/* get the path instance corresponding to the given index number */
168struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx)
169{
170 struct hda_gen_spec *spec = codec->spec;
171
172 if (idx <= 0 || idx > spec->paths.used)
173 return NULL;
174 return snd_array_elem(&spec->paths, idx - 1);
175}
176
150/* check whether the given DAC is already found in any existing paths */ 177/* check whether the given DAC is already found in any existing paths */
151static bool is_dac_already_used(struct hda_codec *codec, hda_nid_t nid) 178static bool is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
152{ 179{
@@ -836,6 +863,7 @@ static struct badness_table extra_out_badness = {
836/* try to assign DACs to pins and return the resultant badness */ 863/* try to assign DACs to pins and return the resultant badness */
837static int try_assign_dacs(struct hda_codec *codec, int num_outs, 864static int try_assign_dacs(struct hda_codec *codec, int num_outs,
838 const hda_nid_t *pins, hda_nid_t *dacs, 865 const hda_nid_t *pins, hda_nid_t *dacs,
866 int *path_idx,
839 const struct badness_table *bad) 867 const struct badness_table *bad)
840{ 868{
841 struct hda_gen_spec *spec = codec->spec; 869 struct hda_gen_spec *spec = codec->spec;
@@ -862,6 +890,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
862 if (is_reachable_path(codec, dacs[j], pin)) { 890 if (is_reachable_path(codec, dacs[j], pin)) {
863 dacs[0] = dacs[j]; 891 dacs[0] = dacs[j];
864 dacs[j] = 0; 892 dacs[j] = 0;
893 path_idx[j] = 0;
865 break; 894 break;
866 } 895 }
867 } 896 }
@@ -898,6 +927,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
898 else { 927 else {
899 print_nid_path("output", path); 928 print_nid_path("output", path);
900 path->active = true; 929 path->active = true;
930 path_idx[i] = snd_hda_get_path_idx(codec, path);
901 } 931 }
902 if (dac) 932 if (dac)
903 badness += assign_out_path_ctls(codec, pin, dac); 933 badness += assign_out_path_ctls(codec, pin, dac);
@@ -1025,6 +1055,8 @@ static int fill_multi_ios(struct hda_codec *codec,
1025 print_nid_path("multiio", path); 1055 print_nid_path("multiio", path);
1026 spec->multi_io[spec->multi_ios].pin = nid; 1056 spec->multi_io[spec->multi_ios].pin = nid;
1027 spec->multi_io[spec->multi_ios].dac = dac; 1057 spec->multi_io[spec->multi_ios].dac = dac;
1058 spec->out_paths[cfg->line_outs + spec->multi_ios] =
1059 snd_hda_get_path_idx(codec, path);
1028 spec->multi_ios++; 1060 spec->multi_ios++;
1029 if (spec->multi_ios >= 2) 1061 if (spec->multi_ios >= 2)
1030 break; 1062 break;
@@ -1056,7 +1088,7 @@ static int fill_multi_ios(struct hda_codec *codec,
1056 1088
1057/* map DACs for all pins in the list if they are single connections */ 1089/* map DACs for all pins in the list if they are single connections */
1058static bool map_singles(struct hda_codec *codec, int outs, 1090static bool map_singles(struct hda_codec *codec, int outs,
1059 const hda_nid_t *pins, hda_nid_t *dacs) 1091 const hda_nid_t *pins, hda_nid_t *dacs, int *path_idx)
1060{ 1092{
1061 struct hda_gen_spec *spec = codec->spec; 1093 struct hda_gen_spec *spec = codec->spec;
1062 int i; 1094 int i;
@@ -1077,6 +1109,7 @@ static bool map_singles(struct hda_codec *codec, int outs,
1077 found = true; 1109 found = true;
1078 print_nid_path("output", path); 1110 print_nid_path("output", path);
1079 path->active = true; 1111 path->active = true;
1112 path_idx[i] = snd_hda_get_path_idx(codec, path);
1080 } 1113 }
1081 } 1114 }
1082 return found; 1115 return found;
@@ -1107,13 +1140,16 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1107 do { 1140 do {
1108 mapped = map_singles(codec, cfg->line_outs, 1141 mapped = map_singles(codec, cfg->line_outs,
1109 cfg->line_out_pins, 1142 cfg->line_out_pins,
1110 spec->private_dac_nids); 1143 spec->private_dac_nids,
1144 spec->out_paths);
1111 mapped |= map_singles(codec, cfg->hp_outs, 1145 mapped |= map_singles(codec, cfg->hp_outs,
1112 cfg->hp_pins, 1146 cfg->hp_pins,
1113 spec->multiout.hp_out_nid); 1147 spec->multiout.hp_out_nid,
1148 spec->hp_paths);
1114 mapped |= map_singles(codec, cfg->speaker_outs, 1149 mapped |= map_singles(codec, cfg->speaker_outs,
1115 cfg->speaker_pins, 1150 cfg->speaker_pins,
1116 spec->multiout.extra_out_nid); 1151 spec->multiout.extra_out_nid,
1152 spec->speaker_paths);
1117 if (fill_mio_first && cfg->line_outs == 1 && 1153 if (fill_mio_first && cfg->line_outs == 1 &&
1118 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1154 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1119 err = fill_multi_ios(codec, cfg->line_out_pins[0], true); 1155 err = fill_multi_ios(codec, cfg->line_out_pins[0], true);
@@ -1124,7 +1160,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1124 } 1160 }
1125 1161
1126 badness += try_assign_dacs(codec, cfg->line_outs, cfg->line_out_pins, 1162 badness += try_assign_dacs(codec, cfg->line_outs, cfg->line_out_pins,
1127 spec->private_dac_nids, 1163 spec->private_dac_nids, spec->out_paths,
1128 &main_out_badness); 1164 &main_out_badness);
1129 1165
1130 /* re-count num_dacs and squash invalid entries */ 1166 /* re-count num_dacs and squash invalid entries */
@@ -1152,6 +1188,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1152 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 1188 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
1153 err = try_assign_dacs(codec, cfg->hp_outs, cfg->hp_pins, 1189 err = try_assign_dacs(codec, cfg->hp_outs, cfg->hp_pins,
1154 spec->multiout.hp_out_nid, 1190 spec->multiout.hp_out_nid,
1191 spec->hp_paths,
1155 &extra_out_badness); 1192 &extra_out_badness);
1156 if (err < 0) 1193 if (err < 0)
1157 return err; 1194 return err;
@@ -1161,7 +1198,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1161 err = try_assign_dacs(codec, cfg->speaker_outs, 1198 err = try_assign_dacs(codec, cfg->speaker_outs,
1162 cfg->speaker_pins, 1199 cfg->speaker_pins,
1163 spec->multiout.extra_out_nid, 1200 spec->multiout.extra_out_nid,
1164 &extra_out_badness); 1201 spec->speaker_paths,
1202 &extra_out_badness);
1165 if (err < 0) 1203 if (err < 0)
1166 return err; 1204 return err;
1167 badness += err; 1205 badness += err;
@@ -1336,9 +1374,7 @@ static int parse_output_paths(struct hda_codec *codec)
1336 1374
1337 if (cfg->line_out_pins[0]) { 1375 if (cfg->line_out_pins[0]) {
1338 struct nid_path *path; 1376 struct nid_path *path;
1339 path = snd_hda_get_nid_path(codec, 1377 path = snd_hda_get_path_from_idx(codec, spec->out_paths[0]);
1340 spec->multiout.dac_nids[0],
1341 cfg->line_out_pins[0]);
1342 if (path) 1378 if (path)
1343 spec->vmaster_nid = look_for_out_vol_nid(codec, path); 1379 spec->vmaster_nid = look_for_out_vol_nid(codec, path);
1344 } 1380 }
@@ -1361,22 +1397,20 @@ static int create_multi_out_ctls(struct hda_codec *codec,
1361 for (i = 0; i < noutputs; i++) { 1397 for (i = 0; i < noutputs; i++) {
1362 const char *name; 1398 const char *name;
1363 int index; 1399 int index;
1364 hda_nid_t dac, pin; 1400 hda_nid_t dac;
1365 struct nid_path *path; 1401 struct nid_path *path;
1366 1402
1367 dac = spec->multiout.dac_nids[i]; 1403 dac = spec->multiout.dac_nids[i];
1368 if (!dac) 1404 if (!dac)
1369 continue; 1405 continue;
1370 if (i >= cfg->line_outs) { 1406 if (i >= cfg->line_outs) {
1371 pin = spec->multi_io[i - cfg->line_outs].pin;
1372 index = 0; 1407 index = 0;
1373 name = channel_name[i]; 1408 name = channel_name[i];
1374 } else { 1409 } else {
1375 pin = cfg->line_out_pins[i];
1376 name = get_line_out_pfx(spec, i, true, &index); 1410 name = get_line_out_pfx(spec, i, true, &index);
1377 } 1411 }
1378 1412
1379 path = snd_hda_get_nid_path(codec, dac, pin); 1413 path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]);
1380 if (!path) 1414 if (!path)
1381 continue; 1415 continue;
1382 if (!name || !strcmp(name, "CLFE")) { 1416 if (!name || !strcmp(name, "CLFE")) {
@@ -1406,12 +1440,13 @@ static int create_multi_out_ctls(struct hda_codec *codec,
1406} 1440}
1407 1441
1408static int create_extra_out(struct hda_codec *codec, hda_nid_t pin, 1442static int create_extra_out(struct hda_codec *codec, hda_nid_t pin,
1409 hda_nid_t dac, const char *pfx, int cidx) 1443 hda_nid_t dac, int path_idx,
1444 const char *pfx, int cidx)
1410{ 1445{
1411 struct nid_path *path; 1446 struct nid_path *path;
1412 int err; 1447 int err;
1413 1448
1414 path = snd_hda_get_nid_path(codec, dac, pin); 1449 path = snd_hda_get_path_from_idx(codec, path_idx);
1415 if (!path) 1450 if (!path)
1416 return 0; 1451 return 0;
1417 /* bind volume control will be created in the case of dac = 0 */ 1452 /* bind volume control will be created in the case of dac = 0 */
@@ -1429,7 +1464,7 @@ static int create_extra_out(struct hda_codec *codec, hda_nid_t pin,
1429/* add playback controls for speaker and HP outputs */ 1464/* add playback controls for speaker and HP outputs */
1430static int create_extra_outs(struct hda_codec *codec, int num_pins, 1465static int create_extra_outs(struct hda_codec *codec, int num_pins,
1431 const hda_nid_t *pins, const hda_nid_t *dacs, 1466 const hda_nid_t *pins, const hda_nid_t *dacs,
1432 const char *pfx) 1467 const int *paths, const char *pfx)
1433{ 1468{
1434 struct hda_gen_spec *spec = codec->spec; 1469 struct hda_gen_spec *spec = codec->spec;
1435 struct hda_bind_ctls *ctl; 1470 struct hda_bind_ctls *ctl;
@@ -1443,7 +1478,7 @@ static int create_extra_outs(struct hda_codec *codec, int num_pins,
1443 hda_nid_t dac = *dacs; 1478 hda_nid_t dac = *dacs;
1444 if (!dac) 1479 if (!dac)
1445 dac = spec->multiout.dac_nids[0]; 1480 dac = spec->multiout.dac_nids[0];
1446 return create_extra_out(codec, *pins, dac, pfx, 0); 1481 return create_extra_out(codec, *pins, dac, paths[0], pfx, 0);
1447 } 1482 }
1448 1483
1449 for (i = 0; i < num_pins; i++) { 1484 for (i = 0; i < num_pins; i++) {
@@ -1453,14 +1488,16 @@ static int create_extra_outs(struct hda_codec *codec, int num_pins,
1453 else 1488 else
1454 dac = 0; 1489 dac = 0;
1455 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) { 1490 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) {
1456 err = create_extra_out(codec, pins[i], dac, 1491 err = create_extra_out(codec, pins[i], dac, paths[i],
1457 "Bass Speaker", 0); 1492 "Bass Speaker", 0);
1458 } else if (num_pins >= 3) { 1493 } else if (num_pins >= 3) {
1459 snprintf(name, sizeof(name), "%s %s", 1494 snprintf(name, sizeof(name), "%s %s",
1460 pfx, channel_name[i]); 1495 pfx, channel_name[i]);
1461 err = create_extra_out(codec, pins[i], dac, name, 0); 1496 err = create_extra_out(codec, pins[i], dac, paths[i],
1497 name, 0);
1462 } else { 1498 } else {
1463 err = create_extra_out(codec, pins[i], dac, pfx, i); 1499 err = create_extra_out(codec, pins[i], dac, paths[i],
1500 pfx, i);
1464 } 1501 }
1465 if (err < 0) 1502 if (err < 0)
1466 return err; 1503 return err;
@@ -1478,7 +1515,7 @@ static int create_extra_outs(struct hda_codec *codec, int num_pins,
1478 struct nid_path *path; 1515 struct nid_path *path;
1479 if (!pins[i] || !dacs[i]) 1516 if (!pins[i] || !dacs[i])
1480 continue; 1517 continue;
1481 path = snd_hda_get_nid_path(codec, dacs[i], pins[i]); 1518 path = snd_hda_get_path_from_idx(codec, paths[i]);
1482 if (!path) 1519 if (!path)
1483 continue; 1520 continue;
1484 vol = look_for_out_vol_nid(codec, path); 1521 vol = look_for_out_vol_nid(codec, path);
@@ -1501,6 +1538,7 @@ static int create_hp_out_ctls(struct hda_codec *codec)
1501 return create_extra_outs(codec, spec->autocfg.hp_outs, 1538 return create_extra_outs(codec, spec->autocfg.hp_outs,
1502 spec->autocfg.hp_pins, 1539 spec->autocfg.hp_pins,
1503 spec->multiout.hp_out_nid, 1540 spec->multiout.hp_out_nid,
1541 spec->hp_paths,
1504 "Headphone"); 1542 "Headphone");
1505} 1543}
1506 1544
@@ -1510,6 +1548,7 @@ static int create_speaker_out_ctls(struct hda_codec *codec)
1510 return create_extra_outs(codec, spec->autocfg.speaker_outs, 1548 return create_extra_outs(codec, spec->autocfg.speaker_outs,
1511 spec->autocfg.speaker_pins, 1549 spec->autocfg.speaker_pins,
1512 spec->multiout.extra_out_nid, 1550 spec->multiout.extra_out_nid,
1551 spec->speaker_paths,
1513 "Speaker"); 1552 "Speaker");
1514} 1553}
1515 1554
@@ -1615,13 +1654,21 @@ static int ch_mode_get(struct snd_kcontrol *kcontrol,
1615 return 0; 1654 return 0;
1616} 1655}
1617 1656
1657static inline struct nid_path *
1658get_multiio_path(struct hda_codec *codec, int idx)
1659{
1660 struct hda_gen_spec *spec = codec->spec;
1661 return snd_hda_get_path_from_idx(codec,
1662 spec->out_paths[spec->autocfg.line_outs + idx]);
1663}
1664
1618static int set_multi_io(struct hda_codec *codec, int idx, bool output) 1665static int set_multi_io(struct hda_codec *codec, int idx, bool output)
1619{ 1666{
1620 struct hda_gen_spec *spec = codec->spec; 1667 struct hda_gen_spec *spec = codec->spec;
1621 hda_nid_t nid = spec->multi_io[idx].pin; 1668 hda_nid_t nid = spec->multi_io[idx].pin;
1622 struct nid_path *path; 1669 struct nid_path *path;
1623 1670
1624 path = snd_hda_get_nid_path(codec, spec->multi_io[idx].dac, nid); 1671 path = get_multiio_path(codec, idx);
1625 if (!path) 1672 if (!path)
1626 return -EINVAL; 1673 return -EINVAL;
1627 1674
@@ -1775,8 +1822,8 @@ static void add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx)
1775#endif 1822#endif
1776 1823
1777/* create input playback/capture controls for the given pin */ 1824/* create input playback/capture controls for the given pin */
1778static int new_analog_input(struct hda_codec *codec, hda_nid_t pin, 1825static int new_analog_input(struct hda_codec *codec, int input_idx,
1779 const char *ctlname, int ctlidx, 1826 hda_nid_t pin, const char *ctlname, int ctlidx,
1780 hda_nid_t mix_nid) 1827 hda_nid_t mix_nid)
1781{ 1828{
1782 struct hda_gen_spec *spec = codec->spec; 1829 struct hda_gen_spec *spec = codec->spec;
@@ -1792,6 +1839,7 @@ static int new_analog_input(struct hda_codec *codec, hda_nid_t pin,
1792 if (!path) 1839 if (!path)
1793 return -EINVAL; 1840 return -EINVAL;
1794 print_nid_path("loopback", path); 1841 print_nid_path("loopback", path);
1842 spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path);
1795 1843
1796 idx = path->idx[path->depth - 1]; 1844 idx = path->idx[path->depth - 1];
1797 if (nid_has_volume(codec, mix_nid, HDA_INPUT)) { 1845 if (nid_has_volume(codec, mix_nid, HDA_INPUT)) {
@@ -1944,7 +1992,7 @@ static int create_input_ctls(struct hda_codec *codec)
1944 1992
1945 if (mixer) { 1993 if (mixer) {
1946 if (is_reachable_path(codec, pin, mixer)) { 1994 if (is_reachable_path(codec, pin, mixer)) {
1947 err = new_analog_input(codec, pin, 1995 err = new_analog_input(codec, i, pin,
1948 label, type_idx, mixer); 1996 label, type_idx, mixer);
1949 if (err < 0) 1997 if (err < 0)
1950 return err; 1998 return err;
@@ -2445,6 +2493,7 @@ static void parse_digital(struct hda_codec *codec)
2445 continue; 2493 continue;
2446 print_nid_path("digout", path); 2494 print_nid_path("digout", path);
2447 path->active = true; 2495 path->active = true;
2496 spec->digout_paths[i] = snd_hda_get_path_idx(codec, path);
2448 if (!nums) { 2497 if (!nums) {
2449 spec->multiout.dig_out_nid = dig_nid; 2498 spec->multiout.dig_out_nid = dig_nid;
2450 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 2499 spec->dig_out_type = spec->autocfg.dig_out_type[0];
@@ -3575,12 +3624,12 @@ EXPORT_SYMBOL_HDA(snd_hda_gen_build_pcms);
3575 3624
3576/* configure the path from the given dac to the pin as the proper output */ 3625/* configure the path from the given dac to the pin as the proper output */
3577static void set_output_and_unmute(struct hda_codec *codec, hda_nid_t pin, 3626static void set_output_and_unmute(struct hda_codec *codec, hda_nid_t pin,
3578 int pin_type, hda_nid_t dac) 3627 int pin_type, int path_idx)
3579{ 3628{
3580 struct nid_path *path; 3629 struct nid_path *path;
3581 3630
3582 snd_hda_set_pin_ctl_cache(codec, pin, pin_type); 3631 snd_hda_set_pin_ctl_cache(codec, pin, pin_type);
3583 path = snd_hda_get_nid_path(codec, dac, pin); 3632 path = snd_hda_get_path_from_idx(codec, path_idx);
3584 if (!path) 3633 if (!path)
3585 return; 3634 return;
3586 snd_hda_activate_path(codec, path, path->active, true); 3635 snd_hda_activate_path(codec, path, path->active, true);
@@ -3591,7 +3640,7 @@ static void set_output_and_unmute(struct hda_codec *codec, hda_nid_t pin,
3591static void init_multi_out(struct hda_codec *codec) 3640static void init_multi_out(struct hda_codec *codec)
3592{ 3641{
3593 struct hda_gen_spec *spec = codec->spec; 3642 struct hda_gen_spec *spec = codec->spec;
3594 hda_nid_t nid, dac; 3643 hda_nid_t nid;
3595 int pin_type; 3644 int pin_type;
3596 int i; 3645 int i;
3597 3646
@@ -3602,35 +3651,24 @@ static void init_multi_out(struct hda_codec *codec)
3602 3651
3603 for (i = 0; i < spec->autocfg.line_outs; i++) { 3652 for (i = 0; i < spec->autocfg.line_outs; i++) {
3604 nid = spec->autocfg.line_out_pins[i]; 3653 nid = spec->autocfg.line_out_pins[i];
3605 if (nid) { 3654 if (nid)
3606 dac = spec->multiout.dac_nids[i]; 3655 set_output_and_unmute(codec, nid, pin_type,
3607 if (!dac) 3656 spec->out_paths[i]);
3608 dac = spec->multiout.dac_nids[0];
3609 set_output_and_unmute(codec, nid, pin_type, dac);
3610 }
3611 } 3657 }
3612} 3658}
3613 3659
3614 3660
3615static void __init_extra_out(struct hda_codec *codec, int num_outs, 3661static void __init_extra_out(struct hda_codec *codec, int num_outs,
3616 hda_nid_t *pins, hda_nid_t *dacs, int type) 3662 hda_nid_t *pins, int *paths, int type)
3617{ 3663{
3618 struct hda_gen_spec *spec = codec->spec;
3619 int i; 3664 int i;
3620 hda_nid_t pin, dac; 3665 hda_nid_t pin;
3621 3666
3622 for (i = 0; i < num_outs; i++) { 3667 for (i = 0; i < num_outs; i++) {
3623 pin = pins[i]; 3668 pin = pins[i];
3624 if (!pin) 3669 if (!pin)
3625 break; 3670 break;
3626 dac = dacs[i]; 3671 set_output_and_unmute(codec, pin, type, paths[i]);
3627 if (!dac) {
3628 if (i > 0 && dacs[0])
3629 dac = dacs[0];
3630 else
3631 dac = spec->multiout.dac_nids[0];
3632 }
3633 set_output_and_unmute(codec, pin, type, dac);
3634 } 3672 }
3635} 3673}
3636 3674
@@ -3642,11 +3680,11 @@ static void init_extra_out(struct hda_codec *codec)
3642 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) 3680 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT)
3643 __init_extra_out(codec, spec->autocfg.hp_outs, 3681 __init_extra_out(codec, spec->autocfg.hp_outs,
3644 spec->autocfg.hp_pins, 3682 spec->autocfg.hp_pins,
3645 spec->multiout.hp_out_nid, PIN_HP); 3683 spec->hp_paths, PIN_HP);
3646 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) 3684 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT)
3647 __init_extra_out(codec, spec->autocfg.speaker_outs, 3685 __init_extra_out(codec, spec->autocfg.speaker_outs,
3648 spec->autocfg.speaker_pins, 3686 spec->autocfg.speaker_pins,
3649 spec->multiout.extra_out_nid, PIN_OUT); 3687 spec->speaker_paths, PIN_OUT);
3650} 3688}
3651 3689
3652/* initialize multi-io paths */ 3690/* initialize multi-io paths */
@@ -3658,7 +3696,7 @@ static void init_multi_io(struct hda_codec *codec)
3658 for (i = 0; i < spec->multi_ios; i++) { 3696 for (i = 0; i < spec->multi_ios; i++) {
3659 hda_nid_t pin = spec->multi_io[i].pin; 3697 hda_nid_t pin = spec->multi_io[i].pin;
3660 struct nid_path *path; 3698 struct nid_path *path;
3661 path = snd_hda_get_nid_path(codec, spec->multi_io[i].dac, pin); 3699 path = get_multiio_path(codec, i);
3662 if (!path) 3700 if (!path)
3663 continue; 3701 continue;
3664 if (!spec->multi_io[i].ctl_in) 3702 if (!spec->multi_io[i].ctl_in)
@@ -3694,7 +3732,7 @@ static void init_analog_input(struct hda_codec *codec)
3694 /* init loopback inputs */ 3732 /* init loopback inputs */
3695 if (spec->mixer_nid) { 3733 if (spec->mixer_nid) {
3696 struct nid_path *path; 3734 struct nid_path *path;
3697 path = snd_hda_get_nid_path(codec, nid, spec->mixer_nid); 3735 path = snd_hda_get_path_from_idx(codec, spec->loopback_paths[i]);
3698 if (path) 3736 if (path)
3699 snd_hda_activate_path(codec, path, 3737 snd_hda_activate_path(codec, path,
3700 path->active, false); 3738 path->active, false);
@@ -3746,7 +3784,8 @@ static void init_digital(struct hda_codec *codec)
3746 pin = spec->autocfg.dig_out_pins[i]; 3784 pin = spec->autocfg.dig_out_pins[i];
3747 if (!pin) 3785 if (!pin)
3748 continue; 3786 continue;
3749 set_output_and_unmute(codec, pin, PIN_OUT, 0); 3787 set_output_and_unmute(codec, pin, PIN_OUT,
3788 spec->digout_paths[i]);
3750 } 3789 }
3751 pin = spec->autocfg.dig_in_pin; 3790 pin = spec->autocfg.dig_in_pin;
3752 if (pin) 3791 if (pin)
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index f1cae2e49377..71d409f5de87 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -130,6 +130,13 @@ struct hda_gen_spec {
130 /* path list */ 130 /* path list */
131 struct snd_array paths; 131 struct snd_array paths;
132 132
133 /* path indices */
134 int out_paths[AUTO_CFG_MAX_OUTS];
135 int hp_paths[AUTO_CFG_MAX_OUTS];
136 int speaker_paths[AUTO_CFG_MAX_OUTS];
137 int digout_paths[AUTO_CFG_MAX_OUTS];
138 int loopback_paths[HDA_MAX_NUM_INPUTS];
139
133 /* auto-mic stuff */ 140 /* auto-mic stuff */
134 int am_num_entries; 141 int am_num_entries;
135 struct automic_entry am_entry[MAX_AUTO_MIC_PINS]; 142 struct automic_entry am_entry[MAX_AUTO_MIC_PINS];
@@ -198,6 +205,8 @@ int snd_hda_gen_init(struct hda_codec *codec);
198 205
199struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, 206struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
200 hda_nid_t from_nid, hda_nid_t to_nid); 207 hda_nid_t from_nid, hda_nid_t to_nid);
208int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path);
209struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx);
201 210
202enum { 211enum {
203 HDA_PARSE_NO_AAMIX, 212 HDA_PARSE_NO_AAMIX,