aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_via.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-06-21 03:01:36 -0400
committerTakashi Iwai <tiwai@suse.de>2011-06-21 03:01:36 -0400
commit8e3679dca200a326426a92d998b63cab5a17c52d (patch)
treebde6e6f348f565d915cb3e78e872b6a338a29f6c /sound/pci/hda/patch_via.c
parent30f7c5d491ec2d515148882fa0b4080ab61d4bb0 (diff)
ALSA: hda - Revisit output_path parsing in patch_via.c
Change the order of the output-path list in a way from the DAC to the target pin. Also now the list include the target pin, too. Together with this format change, simplify the arguments of parse_output_path() function, and fix the initialization in via_auto_init_output(). 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.c87
1 files changed, 50 insertions, 37 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 51e7ce010543..e445a4d24778 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -81,10 +81,12 @@ enum VIA_HDA_CODEC {
81 (spec)->codec_type == VT1812 ||\ 81 (spec)->codec_type == VT1812 ||\
82 (spec)->codec_type == VT1802) 82 (spec)->codec_type == VT1802)
83 83
84#define MAX_NID_PATH_DEPTH 5
85
84struct nid_path { 86struct nid_path {
85 int depth; 87 int depth;
86 hda_nid_t path[5]; 88 hda_nid_t path[MAX_NID_PATH_DEPTH];
87 short idx[5]; 89 short idx[MAX_NID_PATH_DEPTH];
88}; 90};
89 91
90struct via_spec { 92struct via_spec {
@@ -415,15 +417,22 @@ static void unmute_and_select(struct hda_codec *codec, hda_nid_t nid,
415 return; 417 return;
416 418
417 /* select the route explicitly when multiple connections exist */ 419 /* select the route explicitly when multiple connections exist */
418 if (num_conns > 1) 420 if (num_conns > 1 &&
421 get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX)
419 snd_hda_codec_write(codec, nid, 0, 422 snd_hda_codec_write(codec, nid, 0,
420 AC_VERB_SET_CONNECT_SEL, idx); 423 AC_VERB_SET_CONNECT_SEL, idx);
424
421 /* unmute if the input amp is present */ 425 /* unmute if the input amp is present */
422 if (!(query_amp_caps(codec, nid, HDA_INPUT) & 426 if (query_amp_caps(codec, nid, HDA_INPUT) &
423 (AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE))) 427 (AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE))
424 return; 428 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
425 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 429 AMP_IN_UNMUTE(idx));
426 AMP_IN_UNMUTE(idx)); 430
431 /* unmute the src output */
432 if (query_amp_caps(codec, src, HDA_OUTPUT) &
433 (AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE))
434 snd_hda_codec_write(codec, src, 0, AC_VERB_SET_AMP_GAIN_MUTE,
435 AMP_OUT_UNMUTE);
427 436
428 /* unmute AA-path if present */ 437 /* unmute AA-path if present */
429 if (!mix) 438 if (!mix)
@@ -469,15 +478,9 @@ static void via_auto_init_output(struct hda_codec *codec, hda_nid_t pin,
469 } 478 }
470 479
471 /* initialize the output path */ 480 /* initialize the output path */
472 nid = pin; 481 for (i = path->depth - 1; i > 0; i--) {
473 for (i = 0; i < path->depth; i++) { 482 nid = path->path[i - 1];
474 unmute_and_select(codec, nid, path->idx[i], spec->aa_mix_nid); 483 unmute_and_select(codec, path->path[i], nid, spec->aa_mix_nid);
475 nid = path->path[i];
476 if (query_amp_caps(codec, nid, HDA_OUTPUT) &
477 (AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE))
478 snd_hda_codec_write(codec, nid, 0,
479 AC_VERB_SET_AMP_GAIN_MUTE,
480 AMP_OUT_UNMUTE);
481 } 484 }
482} 485}
483 486
@@ -1544,7 +1547,7 @@ static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
1544 return true; 1547 return true;
1545} 1548}
1546 1549
1547static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid, 1550static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1548 hda_nid_t target_dac, struct nid_path *path, 1551 hda_nid_t target_dac, struct nid_path *path,
1549 int depth, int wid_type) 1552 int depth, int wid_type)
1550{ 1553{
@@ -1556,13 +1559,13 @@ static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1556 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT) 1559 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
1557 continue; 1560 continue;
1558 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) { 1561 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
1559 path->path[depth] = conn[i]; 1562 path->path[0] = conn[i];
1560 path->idx[depth] = i; 1563 path->idx[0] = i;
1561 path->depth = ++depth; 1564 path->depth = 1;
1562 return true; 1565 return true;
1563 } 1566 }
1564 } 1567 }
1565 if (depth > 4) 1568 if (depth >= MAX_NID_PATH_DEPTH)
1566 return false; 1569 return false;
1567 for (i = 0; i < nums; i++) { 1570 for (i = 0; i < nums; i++) {
1568 unsigned int type; 1571 unsigned int type;
@@ -1570,16 +1573,28 @@ static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1570 if (type == AC_WID_AUD_OUT || 1573 if (type == AC_WID_AUD_OUT ||
1571 (wid_type != -1 && type != wid_type)) 1574 (wid_type != -1 && type != wid_type))
1572 continue; 1575 continue;
1573 if (parse_output_path(codec, conn[i], target_dac, 1576 if (__parse_output_path(codec, conn[i], target_dac,
1574 path, depth + 1, AC_WID_AUD_SEL)) { 1577 path, depth + 1, AC_WID_AUD_SEL)) {
1575 path->path[depth] = conn[i]; 1578 path->path[path->depth] = conn[i];
1576 path->idx[depth] = i; 1579 path->idx[path->depth] = i;
1580 path->depth++;
1577 return true; 1581 return true;
1578 } 1582 }
1579 } 1583 }
1580 return false; 1584 return false;
1581} 1585}
1582 1586
1587static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1588 hda_nid_t target_dac, struct nid_path *path)
1589{
1590 if (__parse_output_path(codec, nid, target_dac, path, 1, -1)) {
1591 path->path[path->depth] = nid;
1592 path->depth++;
1593 return true;
1594 }
1595 return false;
1596}
1597
1583static int via_auto_fill_dac_nids(struct hda_codec *codec) 1598static int via_auto_fill_dac_nids(struct hda_codec *codec)
1584{ 1599{
1585 struct via_spec *spec = codec->spec; 1600 struct via_spec *spec = codec->spec;
@@ -1593,9 +1608,8 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec)
1593 nid = cfg->line_out_pins[i]; 1608 nid = cfg->line_out_pins[i];
1594 if (!nid) 1609 if (!nid)
1595 continue; 1610 continue;
1596 if (parse_output_path(codec, nid, 0, &spec->out_path[i], 0, -1)) 1611 if (parse_output_path(codec, nid, 0, &spec->out_path[i]))
1597 spec->private_dac_nids[i] = 1612 spec->private_dac_nids[i] = spec->out_path[i].path[0];
1598 spec->out_path[i].path[spec->out_path[i].depth - 1];
1599 } 1613 }
1600 return 0; 1614 return 0;
1601} 1615}
@@ -1748,15 +1762,14 @@ static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
1748 if (!pin) 1762 if (!pin)
1749 return 0; 1763 return 0;
1750 1764
1751 if (parse_output_path(codec, pin, 0, &spec->hp_path, 0, -1)) { 1765 if (parse_output_path(codec, pin, 0, &spec->hp_path)) {
1752 spec->hp_dac_nid = spec->hp_path.path[spec->hp_path.depth - 1]; 1766 spec->hp_dac_nid = spec->hp_path.path[0];
1753 spec->hp_independent_mode_index = 1767 spec->hp_independent_mode_index = spec->hp_path.idx[0];
1754 spec->hp_path.idx[spec->hp_path.depth - 1];
1755 create_hp_imux(spec); 1768 create_hp_imux(spec);
1756 } 1769 }
1757 1770
1758 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT], 1771 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1759 &spec->hp_dep_path, 0, -1) && 1772 &spec->hp_dep_path) &&
1760 !spec->hp_dac_nid) 1773 !spec->hp_dac_nid)
1761 return 0; 1774 return 0;
1762 1775
@@ -1777,14 +1790,14 @@ static int via_auto_create_speaker_ctls(struct hda_codec *codec)
1777 if (!spec->autocfg.speaker_outs || !pin) 1790 if (!spec->autocfg.speaker_outs || !pin)
1778 return 0; 1791 return 0;
1779 1792
1780 if (parse_output_path(codec, pin, 0, &spec->speaker_path, 0, -1)) { 1793 if (parse_output_path(codec, pin, 0, &spec->speaker_path)) {
1781 dac = spec->speaker_path.path[spec->speaker_path.depth - 1]; 1794 dac = spec->speaker_path.path[0];
1782 spec->multiout.extra_out_nid[0] = dac; 1795 spec->multiout.extra_out_nid[0] = dac;
1783 return create_ch_ctls(codec, "Speaker", pin, dac, 3); 1796 return create_ch_ctls(codec, "Speaker", pin, dac, 3);
1784 } 1797 }
1785 if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT], 1798 if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1786 &spec->speaker_path, 0, -1)) 1799 &spec->speaker_path))
1787 return create_ch_ctls(codec, "Headphone", pin, 0, 3); 1800 return create_ch_ctls(codec, "Speaker", pin, 0, 3);
1788 1801
1789 return 0; 1802 return 0;
1790} 1803}