diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-06-21 03:01:36 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-06-21 03:01:36 -0400 |
commit | 8e3679dca200a326426a92d998b63cab5a17c52d (patch) | |
tree | bde6e6f348f565d915cb3e78e872b6a338a29f6c /sound/pci/hda/patch_via.c | |
parent | 30f7c5d491ec2d515148882fa0b4080ab61d4bb0 (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.c | 87 |
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 | |||
84 | struct nid_path { | 86 | struct 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 | ||
90 | struct via_spec { | 92 | struct 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 | ||
1547 | static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid, | 1550 | static 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 | ||
1587 | static 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 | |||
1583 | static int via_auto_fill_dac_nids(struct hda_codec *codec) | 1598 | static 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 | } |