aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_via.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-18 06:49:25 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-18 10:47:33 -0400
commit3214b9665c06f684011f169428963b20f8ac554b (patch)
treeae0a11d150f1fb7f65fb1aaf404a034f0f3acf1e /sound/pci/hda/patch_via.c
parent7b1655f5f21a9bd1eb8b478c5dab9b83de809edc (diff)
ALSA: hda - Implement dynamic loopback control for VIA codecs
This patch adds the dynamic control of analog-loopback for VIA codecs. When the loopback is enabled, the inputs from line-ins and mics are mixed with the front DAC, and sent to the front outputs. The very same input is routed to the headhpones and speakers in loopback mode. However, since the loopback mix can't take other than the front DAC, there is no longer individual volume controls for headphones and speakers. Once when the loopback control is off, these volumes take effect. Since the individual volumes are more desired in general use caess, the loopback mode is set to off as default for now. 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.c400
1 files changed, 260 insertions, 140 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 5232abc341f..76c688409cd 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -130,13 +130,28 @@ struct via_spec {
130 struct hda_multi_out multiout; 130 struct hda_multi_out multiout;
131 hda_nid_t slave_dig_outs[2]; 131 hda_nid_t slave_dig_outs[2];
132 hda_nid_t hp_dac_nid; 132 hda_nid_t hp_dac_nid;
133 bool hp_indep_shared; /* indep HP-DAC is shared with side ch */ 133 hda_nid_t speaker_dac_nid;
134 int hp_indep_shared; /* indep HP-DAC is shared with side ch */
134 int num_active_streams; 135 int num_active_streams;
135 136 int aamix_mode; /* loopback is enabled for output-path? */
137
138 /* Output-paths:
139 * There are different output-paths depending on the setup.
140 * out_path, hp_path and speaker_path are primary paths. If both
141 * direct DAC and aa-loopback routes are available, these contain
142 * the former paths. Meanwhile *_mix_path contain the paths with
143 * loopback mixer. (Since the loopback is only for front channel,
144 * no out_mix_path for surround channels.)
145 * The HP output has another path, hp_indep_path, which is used in
146 * the independent-HP mode.
147 */
136 struct nid_path out_path[HDA_SIDE + 1]; 148 struct nid_path out_path[HDA_SIDE + 1];
149 struct nid_path out_mix_path;
137 struct nid_path hp_path; 150 struct nid_path hp_path;
138 struct nid_path hp_dep_path; 151 struct nid_path hp_mix_path;
152 struct nid_path hp_indep_path;
139 struct nid_path speaker_path; 153 struct nid_path speaker_path;
154 struct nid_path speaker_mix_path;
140 155
141 /* capture */ 156 /* capture */
142 unsigned int num_adc_nids; 157 unsigned int num_adc_nids;
@@ -437,50 +452,20 @@ static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
437#define have_mute(codec, nid, dir) \ 452#define have_mute(codec, nid, dir) \
438 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE) 453 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
439 454
440static bool is_node_in_path(struct nid_path *path, hda_nid_t nid)
441{
442 int i;
443 if (!nid)
444 return false;
445 for (i = 0; i < path->depth; i++) {
446 if (path->path[i] == nid)
447 return true;
448 }
449 return false;
450}
451
452/* enable/disable the output-route mixers */ 455/* enable/disable the output-route mixers */
453static void activate_output_mix(struct hda_codec *codec, struct nid_path *path, 456static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
454 hda_nid_t mix_nid, int aa_mix_idx, bool enable) 457 hda_nid_t mix_nid, int idx, bool enable)
455{ 458{
456 int i, num, val; 459 int i, num, val;
457 bool hp_path, front_path;
458 struct via_spec *spec = codec->spec;
459 460
460 if (!path) 461 if (!path)
461 return; 462 return;
462 num = snd_hda_get_conn_list(codec, mix_nid, NULL); 463 num = snd_hda_get_conn_list(codec, mix_nid, NULL);
463 hp_path = is_node_in_path(path, spec->hp_dac_nid);
464 front_path = is_node_in_path(path, spec->multiout.dac_nids[0]);
465
466 for (i = 0; i < num; i++) { 464 for (i = 0; i < num; i++) {
467 if (i == aa_mix_idx) { 465 if (i == idx)
468 if (hp_path) 466 val = AMP_IN_UNMUTE(i);
469 val = enable ? AMP_IN_MUTE(i) : 467 else
470 AMP_IN_UNMUTE(i); 468 val = AMP_IN_MUTE(i);
471 else if (front_path)
472 val = AMP_IN_UNMUTE(i);
473 else
474 val = AMP_IN_MUTE(i);
475 } else {
476 if (hp_path)
477 val = enable ? AMP_IN_UNMUTE(i) :
478 AMP_IN_MUTE(i);
479 else if (front_path)
480 val = AMP_IN_MUTE(i);
481 else
482 val = AMP_IN_UNMUTE(i);
483 }
484 snd_hda_codec_write(codec, mix_nid, 0, 469 snd_hda_codec_write(codec, mix_nid, 0,
485 AC_VERB_SET_AMP_GAIN_MUTE, val); 470 AC_VERB_SET_AMP_GAIN_MUTE, val);
486 } 471 }
@@ -490,9 +475,8 @@ static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
490static void activate_output_path(struct hda_codec *codec, struct nid_path *path, 475static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
491 bool enable, bool force) 476 bool enable, bool force)
492{ 477{
493 int i, val;
494 struct via_spec *spec = codec->spec; 478 struct via_spec *spec = codec->spec;
495 hda_nid_t aa_mix_nid = spec->aa_mix_nid; 479 int i;
496 for (i = 0; i < path->depth; i++) { 480 for (i = 0; i < path->depth; i++) {
497 hda_nid_t src, dst; 481 hda_nid_t src, dst;
498 int idx = path->idx[i]; 482 int idx = path->idx[i];
@@ -504,25 +488,10 @@ static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
504 if (enable && path->multi[i]) 488 if (enable && path->multi[i])
505 snd_hda_codec_write(codec, dst, 0, 489 snd_hda_codec_write(codec, dst, 0,
506 AC_VERB_SET_CONNECT_SEL, idx); 490 AC_VERB_SET_CONNECT_SEL, idx);
507 if (!force 491 if (!force && (dst == spec->aa_mix_nid))
508 && get_wcaps_type(get_wcaps(codec, src)) == AC_WID_AUD_OUT
509 && get_wcaps_type(get_wcaps(codec, dst)) == AC_WID_AUD_MIX)
510 continue; 492 continue;
511 if (have_mute(codec, dst, HDA_INPUT)) { 493 if (have_mute(codec, dst, HDA_INPUT))
512 if (dst == aa_mix_nid) { 494 activate_output_mix(codec, path, dst, idx, enable);
513 val = enable ? AMP_IN_UNMUTE(idx) :
514 AMP_IN_MUTE(idx);
515 snd_hda_codec_write(codec, dst, 0,
516 AC_VERB_SET_AMP_GAIN_MUTE, val);
517 } else {
518 idx = get_connection_index(codec, dst,
519 aa_mix_nid);
520 if (idx >= 0) {
521 activate_output_mix(codec, path,
522 dst, idx, enable);
523 }
524 }
525 }
526 if (!force && (src == path->vol_ctl || src == path->mute_ctl)) 495 if (!force && (src == path->vol_ctl || src == path->mute_ctl))
527 continue; 496 continue;
528 if (have_mute(codec, src, HDA_OUTPUT)) { 497 if (have_mute(codec, src, HDA_OUTPUT)) {
@@ -548,9 +517,8 @@ static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
548 517
549static void via_auto_init_output(struct hda_codec *codec, 518static void via_auto_init_output(struct hda_codec *codec,
550 struct nid_path *path, int pin_type, 519 struct nid_path *path, int pin_type,
551 bool with_aa_mix, bool force) 520 bool force)
552{ 521{
553 struct via_spec *spec = codec->spec;
554 unsigned int caps; 522 unsigned int caps;
555 hda_nid_t pin; 523 hda_nid_t pin;
556 524
@@ -566,41 +534,45 @@ static void via_auto_init_output(struct hda_codec *codec,
566 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, 534 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
567 AMP_OUT_MUTE | val); 535 AMP_OUT_MUTE | val);
568 } 536 }
569
570 /* initialize the AA-path */
571 if (!spec->aa_mix_nid)
572 return;
573 activate_output_path(codec, path, true, force); 537 activate_output_path(codec, path, true, force);
574} 538}
575 539
576static void via_auto_init_multi_out(struct hda_codec *codec) 540static void via_auto_init_multi_out(struct hda_codec *codec)
577{ 541{
578 struct via_spec *spec = codec->spec; 542 struct via_spec *spec = codec->spec;
543 struct nid_path *path;
579 int i; 544 int i;
580 545
581 for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) 546 for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) {
582 /* enable aa-mute only for the front channel */ 547 path = &spec->out_path[i];
583 via_auto_init_output(codec, &spec->out_path[i], PIN_OUT, 548 if (!i && spec->aamix_mode && spec->out_mix_path.depth)
584 i == 0, true); 549 path = &spec->out_mix_path;
550 via_auto_init_output(codec, path, PIN_OUT, true);
551 }
585} 552}
586 553
587static void via_auto_init_hp_out(struct hda_codec *codec) 554static void via_auto_init_hp_out(struct hda_codec *codec)
588{ 555{
589 struct via_spec *spec = codec->spec; 556 struct via_spec *spec = codec->spec;
557 int shared = spec->hp_indep_shared;
590 558
591 if (!spec->hp_dac_nid) { 559 if (!spec->hp_path.depth) {
592 via_auto_init_output(codec, &spec->hp_dep_path, PIN_HP, 560 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP, true);
593 true, true);
594 return; 561 return;
595 } 562 }
596 if (spec->hp_independent_mode) { 563 if (spec->hp_independent_mode) {
597 activate_output_path(codec, &spec->hp_dep_path, false, false);
598 via_auto_init_output(codec, &spec->hp_path, PIN_HP,
599 true, true);
600 } else {
601 activate_output_path(codec, &spec->hp_path, false, false); 564 activate_output_path(codec, &spec->hp_path, false, false);
602 via_auto_init_output(codec, &spec->hp_dep_path, PIN_HP, 565 activate_output_path(codec, &spec->hp_mix_path, false, false);
603 true, true); 566 if (shared)
567 activate_output_path(codec, &spec->out_path[shared],
568 false, false);
569 via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP, true);
570 } else if (spec->aamix_mode) {
571 activate_output_path(codec, &spec->hp_path, false, false);
572 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP, true);
573 } else {
574 activate_output_path(codec, &spec->hp_mix_path, false, false);
575 via_auto_init_output(codec, &spec->hp_path, PIN_HP, true);
604 } 576 }
605} 577}
606 578
@@ -608,9 +580,23 @@ static void via_auto_init_speaker_out(struct hda_codec *codec)
608{ 580{
609 struct via_spec *spec = codec->spec; 581 struct via_spec *spec = codec->spec;
610 582
611 if (spec->autocfg.speaker_outs) 583 if (!spec->autocfg.speaker_outs)
584 return;
585 if (!spec->speaker_path.depth) {
586 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT,
587 true);
588 return;
589 }
590 if (!spec->aamix_mode) {
591 activate_output_path(codec, &spec->speaker_mix_path,
592 false, false);
612 via_auto_init_output(codec, &spec->speaker_path, PIN_OUT, 593 via_auto_init_output(codec, &spec->speaker_path, PIN_OUT,
613 true, true); 594 true);
595 } else {
596 activate_output_path(codec, &spec->speaker_path, false, false);
597 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT,
598 true);
599 }
614} 600}
615 601
616static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin); 602static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin);
@@ -775,7 +761,7 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
775{ 761{
776 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 762 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
777 struct via_spec *spec = codec->spec; 763 struct via_spec *spec = codec->spec;
778 int cur; 764 int cur, shared;
779 765
780 /* no independent-hp status change during PCM playback is running */ 766 /* no independent-hp status change during PCM playback is running */
781 if (spec->num_active_streams) 767 if (spec->num_active_streams)
@@ -785,18 +771,19 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
785 if (spec->hp_independent_mode == cur) 771 if (spec->hp_independent_mode == cur)
786 return 0; 772 return 0;
787 spec->hp_independent_mode = cur; 773 spec->hp_independent_mode = cur;
774 shared = spec->hp_indep_shared;
788 if (cur) { 775 if (cur) {
789 activate_output_path(codec, &spec->hp_dep_path, false, false); 776 activate_output_path(codec, &spec->hp_mix_path, false, false);
790 activate_output_path(codec, &spec->hp_path, true, false); 777 if (shared)
791 if (spec->hp_indep_shared) 778 activate_output_path(codec, &spec->out_path[shared],
792 activate_output_path(codec, &spec->out_path[HDA_SIDE],
793 false, false); 779 false, false);
780 activate_output_path(codec, &spec->hp_path, true, false);
794 } else { 781 } else {
795 activate_output_path(codec, &spec->hp_path, false, false); 782 activate_output_path(codec, &spec->hp_path, false, false);
796 activate_output_path(codec, &spec->hp_dep_path, true, false); 783 if (shared)
797 if (spec->hp_indep_shared) 784 activate_output_path(codec, &spec->out_path[shared],
798 activate_output_path(codec, &spec->out_path[HDA_SIDE],
799 true, false); 785 true, false);
786 activate_output_path(codec, &spec->hp_mix_path, true, false);
800 } 787 }
801 788
802 /* update jack power state */ 789 /* update jack power state */
@@ -1671,29 +1658,38 @@ static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
1671} 1658}
1672 1659
1673static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid, 1660static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1674 hda_nid_t target_dac, struct nid_path *path, 1661 hda_nid_t target_dac, int with_aa_mix,
1675 int depth, int wid_type) 1662 struct nid_path *path, int depth)
1676{ 1663{
1664 struct via_spec *spec = codec->spec;
1677 hda_nid_t conn[8]; 1665 hda_nid_t conn[8];
1678 int i, nums; 1666 int i, nums;
1679 1667
1668 if (nid == spec->aa_mix_nid) {
1669 if (!with_aa_mix)
1670 return false;
1671 with_aa_mix = 2; /* mark aa-mix is included */
1672 }
1673
1680 nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn)); 1674 nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
1681 for (i = 0; i < nums; i++) { 1675 for (i = 0; i < nums; i++) {
1682 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT) 1676 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
1683 continue; 1677 continue;
1684 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) 1678 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
1685 goto found; 1679 /* aa-mix is requested but not included? */
1680 if (!(spec->aa_mix_nid && with_aa_mix == 1))
1681 goto found;
1682 }
1686 } 1683 }
1687 if (depth >= MAX_NID_PATH_DEPTH) 1684 if (depth >= MAX_NID_PATH_DEPTH)
1688 return false; 1685 return false;
1689 for (i = 0; i < nums; i++) { 1686 for (i = 0; i < nums; i++) {
1690 unsigned int type; 1687 unsigned int type;
1691 type = get_wcaps_type(get_wcaps(codec, conn[i])); 1688 type = get_wcaps_type(get_wcaps(codec, conn[i]));
1692 if (type == AC_WID_AUD_OUT || 1689 if (type == AC_WID_AUD_OUT)
1693 (wid_type != -1 && type != wid_type))
1694 continue; 1690 continue;
1695 if (__parse_output_path(codec, conn[i], target_dac, 1691 if (__parse_output_path(codec, conn[i], target_dac,
1696 path, depth + 1, AC_WID_AUD_SEL)) 1692 with_aa_mix, path, depth + 1))
1697 goto found; 1693 goto found;
1698 } 1694 }
1699 return false; 1695 return false;
@@ -1708,11 +1704,15 @@ static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1708} 1704}
1709 1705
1710static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid, 1706static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1711 hda_nid_t target_dac, struct nid_path *path) 1707 hda_nid_t target_dac, int with_aa_mix,
1708 struct nid_path *path)
1712{ 1709{
1713 if (__parse_output_path(codec, nid, target_dac, path, 1, -1)) { 1710 if (__parse_output_path(codec, nid, target_dac, with_aa_mix, path, 1)) {
1714 path->path[path->depth] = nid; 1711 path->path[path->depth] = nid;
1715 path->depth++; 1712 path->depth++;
1713 snd_printdd("output-path: depth=%d, %02x/%02x/%02x/%02x/%02x\n",
1714 path->depth, path->path[0], path->path[1],
1715 path->path[2], path->path[3], path->path[4]);
1716 return true; 1716 return true;
1717 } 1717 }
1718 return false; 1718 return false;
@@ -1728,14 +1728,24 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec)
1728 spec->multiout.dac_nids = spec->private_dac_nids; 1728 spec->multiout.dac_nids = spec->private_dac_nids;
1729 dac_num = 0; 1729 dac_num = 0;
1730 for (i = 0; i < cfg->line_outs; i++) { 1730 for (i = 0; i < cfg->line_outs; i++) {
1731 hda_nid_t dac = 0;
1731 nid = cfg->line_out_pins[i]; 1732 nid = cfg->line_out_pins[i];
1732 if (!nid) 1733 if (!nid)
1733 continue; 1734 continue;
1734 if (parse_output_path(codec, nid, 0, &spec->out_path[i])) { 1735 if (parse_output_path(codec, nid, 0, 0, &spec->out_path[i]))
1735 spec->private_dac_nids[i] = spec->out_path[i].path[0]; 1736 dac = spec->out_path[i].path[0];
1737 if (!i && parse_output_path(codec, nid, dac, 1,
1738 &spec->out_mix_path))
1739 dac = spec->out_mix_path.path[0];
1740 if (dac) {
1741 spec->private_dac_nids[i] = dac;
1736 dac_num++; 1742 dac_num++;
1737 } 1743 }
1738 } 1744 }
1745 if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
1746 spec->out_path[0] = spec->out_mix_path;
1747 spec->out_mix_path.depth = 0;
1748 }
1739 spec->multiout.num_dacs = dac_num; 1749 spec->multiout.num_dacs = dac_num;
1740 return 0; 1750 return 0;
1741} 1751}
@@ -1832,6 +1842,7 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
1832{ 1842{
1833 struct via_spec *spec = codec->spec; 1843 struct via_spec *spec = codec->spec;
1834 struct auto_pin_cfg *cfg = &spec->autocfg; 1844 struct auto_pin_cfg *cfg = &spec->autocfg;
1845 struct nid_path *path;
1835 static const char * const chname[4] = { 1846 static const char * const chname[4] = {
1836 "Front", "Surround", "C/LFE", "Side" 1847 "Front", "Surround", "C/LFE", "Side"
1837 }; 1848 };
@@ -1857,13 +1868,12 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
1857 dac = spec->multiout.dac_nids[i]; 1868 dac = spec->multiout.dac_nids[i];
1858 if (!pin || !dac) 1869 if (!pin || !dac)
1859 continue; 1870 continue;
1871 path = spec->out_path + i;
1860 if (i == HDA_CLFE) { 1872 if (i == HDA_CLFE) {
1861 err = create_ch_ctls(codec, "Center", 1, true, 1873 err = create_ch_ctls(codec, "Center", 1, true, path);
1862 &spec->out_path[i]);
1863 if (err < 0) 1874 if (err < 0)
1864 return err; 1875 return err;
1865 err = create_ch_ctls(codec, "LFE", 2, true, 1876 err = create_ch_ctls(codec, "LFE", 2, true, path);
1866 &spec->out_path[i]);
1867 if (err < 0) 1877 if (err < 0)
1868 return err; 1878 return err;
1869 } else { 1879 } else {
@@ -1871,25 +1881,35 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
1871 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && 1881 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
1872 cfg->line_outs == 1) 1882 cfg->line_outs == 1)
1873 pfx = "Speaker"; 1883 pfx = "Speaker";
1874 err = create_ch_ctls(codec, pfx, 3, true, 1884 err = create_ch_ctls(codec, pfx, 3, true, path);
1875 &spec->out_path[i]);
1876 if (err < 0) 1885 if (err < 0)
1877 return err; 1886 return err;
1878 } 1887 }
1888 if (path != spec->out_path + i) {
1889 spec->out_path[i].vol_ctl = path->vol_ctl;
1890 spec->out_path[i].mute_ctl = path->mute_ctl;
1891 }
1892 if (path == spec->out_path && spec->out_mix_path.depth) {
1893 spec->out_mix_path.vol_ctl = path->vol_ctl;
1894 spec->out_mix_path.mute_ctl = path->mute_ctl;
1895 }
1879 } 1896 }
1880 1897
1881 idx = get_connection_index(codec, spec->aa_mix_nid, 1898 idx = get_connection_index(codec, spec->aa_mix_nid,
1882 spec->multiout.dac_nids[0]); 1899 spec->multiout.dac_nids[0]);
1883 if (idx >= 0) { 1900 if (idx >= 0) {
1884 /* add control to mixer */ 1901 /* add control to mixer */
1885 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1902 const char *name;
1886 "PCM Playback Volume", 1903 name = spec->out_mix_path.depth ?
1904 "PCM Loopback Playback Volume" : "PCM Playback Volume";
1905 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1887 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3, 1906 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
1888 idx, HDA_INPUT)); 1907 idx, HDA_INPUT));
1889 if (err < 0) 1908 if (err < 0)
1890 return err; 1909 return err;
1891 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1910 name = spec->out_mix_path.depth ?
1892 "PCM Playback Switch", 1911 "PCM Loopback Playback Switch" : "PCM Playback Switch";
1912 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1893 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3, 1913 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
1894 idx, HDA_INPUT)); 1914 idx, HDA_INPUT));
1895 if (err < 0) 1915 if (err < 0)
@@ -1906,70 +1926,167 @@ static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
1906 struct via_spec *spec = codec->spec; 1926 struct via_spec *spec = codec->spec;
1907 struct nid_path *path; 1927 struct nid_path *path;
1908 bool check_dac; 1928 bool check_dac;
1909 int err; 1929 int i, err;
1910 1930
1911 if (!pin) 1931 if (!pin)
1912 return 0; 1932 return 0;
1913 1933
1914 if (parse_output_path(codec, pin, 0, &spec->hp_path)) 1934 if (!parse_output_path(codec, pin, 0, 0, &spec->hp_indep_path)) {
1915 spec->hp_dac_nid = spec->hp_path.path[0]; 1935 for (i = HDA_SIDE; i >= HDA_CLFE; i--) {
1916 else if (spec->multiout.dac_nids[HDA_SIDE] && 1936 if (i < spec->multiout.num_dacs &&
1917 parse_output_path(codec, pin, 1937 parse_output_path(codec, pin,
1918 spec->multiout.dac_nids[HDA_SIDE], 1938 spec->multiout.dac_nids[i], 0,
1919 &spec->hp_path)) { 1939 &spec->hp_indep_path)) {
1920 spec->hp_dac_nid = spec->hp_path.path[0]; 1940 spec->hp_indep_shared = i;
1921 spec->hp_indep_shared = true; 1941 break;
1922 } else if (spec->multiout.dac_nids[HDA_CLFE] && 1942 }
1923 parse_output_path(codec, pin, 1943 }
1924 spec->multiout.dac_nids[HDA_CLFE],
1925 &spec->hp_path)) {
1926 spec->hp_dac_nid = spec->hp_path.path[0];
1927 spec->hp_indep_shared = true;
1928 } 1944 }
1945 if (spec->hp_indep_path.depth) {
1946 spec->hp_dac_nid = spec->hp_indep_path.path[0];
1947 if (!spec->hp_indep_shared)
1948 spec->hp_path = spec->hp_indep_path;
1949 }
1950 /* optionally check front-path w/o AA-mix */
1951 if (!spec->hp_path.depth)
1952 parse_output_path(codec, pin,
1953 spec->multiout.dac_nids[HDA_FRONT], 0,
1954 &spec->hp_path);
1929 1955
1930 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT], 1956 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1931 &spec->hp_dep_path) && 1957 1, &spec->hp_mix_path) && !spec->hp_path.depth)
1932 !spec->hp_dac_nid)
1933 return 0; 1958 return 0;
1934 1959
1935 if (spec->hp_dac_nid && !spec->hp_indep_shared) { 1960 if (spec->hp_path.depth) {
1936 path = &spec->hp_path; 1961 path = &spec->hp_path;
1937 check_dac = true; 1962 check_dac = true;
1938 } else { 1963 } else {
1939 path = &spec->hp_dep_path; 1964 path = &spec->hp_mix_path;
1940 check_dac = false; 1965 check_dac = false;
1941 } 1966 }
1942 err = create_ch_ctls(codec, "Headphone", 3, check_dac, path); 1967 err = create_ch_ctls(codec, "Headphone", 3, check_dac, path);
1943 if (err < 0) 1968 if (err < 0)
1944 return err; 1969 return err;
1945 if (spec->hp_dac_nid) { 1970 if (check_dac) {
1946 spec->hp_dep_path.vol_ctl = spec->hp_path.vol_ctl; 1971 spec->hp_mix_path.vol_ctl = path->vol_ctl;
1947 spec->hp_dep_path.mute_ctl = spec->hp_path.mute_ctl; 1972 spec->hp_mix_path.mute_ctl = path->mute_ctl;
1973 } else {
1974 spec->hp_path.vol_ctl = path->vol_ctl;
1975 spec->hp_path.mute_ctl = path->mute_ctl;
1948 } 1976 }
1949
1950 return 0; 1977 return 0;
1951} 1978}
1952 1979
1953static int via_auto_create_speaker_ctls(struct hda_codec *codec) 1980static int via_auto_create_speaker_ctls(struct hda_codec *codec)
1954{ 1981{
1955 struct via_spec *spec = codec->spec; 1982 struct via_spec *spec = codec->spec;
1983 struct nid_path *path;
1984 bool check_dac;
1956 hda_nid_t pin, dac; 1985 hda_nid_t pin, dac;
1986 int err;
1957 1987
1958 pin = spec->autocfg.speaker_pins[0]; 1988 pin = spec->autocfg.speaker_pins[0];
1959 if (!spec->autocfg.speaker_outs || !pin) 1989 if (!spec->autocfg.speaker_outs || !pin)
1960 return 0; 1990 return 0;
1961 1991
1962 if (parse_output_path(codec, pin, 0, &spec->speaker_path)) { 1992 if (parse_output_path(codec, pin, 0, 0, &spec->speaker_path))
1963 dac = spec->speaker_path.path[0]; 1993 dac = spec->speaker_path.path[0];
1964 spec->multiout.extra_out_nid[0] = dac; 1994 if (!dac)
1965 return create_ch_ctls(codec, "Speaker", 3, true, 1995 parse_output_path(codec, pin,
1966 &spec->speaker_path); 1996 spec->multiout.dac_nids[HDA_FRONT], 0,
1997 &spec->speaker_path);
1998 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1999 1, &spec->speaker_mix_path) && !dac)
2000 return 0;
2001
2002 /* no AA-path for front? */
2003 if (!spec->out_mix_path.depth && spec->speaker_mix_path.depth)
2004 dac = 0;
2005
2006 spec->speaker_dac_nid = dac;
2007 spec->multiout.extra_out_nid[0] = dac;
2008 if (dac) {
2009 path = &spec->speaker_path;
2010 check_dac = true;
2011 } else {
2012 path = &spec->speaker_mix_path;
2013 check_dac = false;
2014 }
2015 err = create_ch_ctls(codec, "Speaker", 3, check_dac, path);
2016 if (err < 0)
2017 return err;
2018 if (check_dac) {
2019 spec->speaker_mix_path.vol_ctl = path->vol_ctl;
2020 spec->speaker_mix_path.mute_ctl = path->mute_ctl;
2021 } else {
2022 spec->speaker_path.vol_ctl = path->vol_ctl;
2023 spec->speaker_path.mute_ctl = path->mute_ctl;
1967 } 2024 }
1968 if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT], 2025 return 0;
1969 &spec->speaker_path)) 2026}
1970 return create_ch_ctls(codec, "Speaker", 3, false, 2027
1971 &spec->speaker_path); 2028#define via_aamix_ctl_info via_pin_power_ctl_info
1972 2029
2030static int via_aamix_ctl_get(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_value *ucontrol)
2032{
2033 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2034 struct via_spec *spec = codec->spec;
2035 ucontrol->value.enumerated.item[0] = spec->aamix_mode;
2036 return 0;
2037}
2038
2039static void update_aamix_paths(struct hda_codec *codec, int do_mix,
2040 struct nid_path *nomix, struct nid_path *mix)
2041{
2042 if (do_mix) {
2043 activate_output_path(codec, nomix, false, false);
2044 activate_output_path(codec, mix, true, false);
2045 } else {
2046 activate_output_path(codec, mix, false, false);
2047 activate_output_path(codec, nomix, true, false);
2048 }
2049}
2050
2051static int via_aamix_ctl_put(struct snd_kcontrol *kcontrol,
2052 struct snd_ctl_elem_value *ucontrol)
2053{
2054 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2055 struct via_spec *spec = codec->spec;
2056 unsigned int val = ucontrol->value.enumerated.item[0];
2057
2058 if (val == spec->aamix_mode)
2059 return 0;
2060 spec->aamix_mode = val;
2061 /* update front path */
2062 update_aamix_paths(codec, val, &spec->out_path[0], &spec->out_mix_path);
2063 /* update HP path */
2064 if (!spec->hp_independent_mode) {
2065 update_aamix_paths(codec, val, &spec->hp_path,
2066 &spec->hp_mix_path);
2067 }
2068 /* update speaker path */
2069 update_aamix_paths(codec, val, &spec->speaker_path,
2070 &spec->speaker_mix_path);
2071 return 1;
2072}
2073
2074static const struct snd_kcontrol_new via_aamix_ctl_enum = {
2075 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2076 .name = "Loopback Mixing",
2077 .info = via_aamix_ctl_info,
2078 .get = via_aamix_ctl_get,
2079 .put = via_aamix_ctl_put,
2080};
2081
2082static int via_auto_create_loopback_switch(struct hda_codec *codec)
2083{
2084 struct via_spec *spec = codec->spec;
2085
2086 if (!spec->aa_mix_nid || !spec->out_mix_path.depth)
2087 return 0; /* no loopback switching available */
2088 if (!via_clone_control(spec, &via_aamix_ctl_enum))
2089 return -ENOMEM;
1973 return 0; 2090 return 0;
1974} 2091}
1975 2092
@@ -2440,6 +2557,9 @@ static int via_parse_auto_config(struct hda_codec *codec)
2440 err = via_auto_create_speaker_ctls(codec); 2557 err = via_auto_create_speaker_ctls(codec);
2441 if (err < 0) 2558 if (err < 0)
2442 return err; 2559 return err;
2560 err = via_auto_create_loopback_switch(codec);
2561 if (err < 0)
2562 return err;
2443 err = via_auto_create_analog_input_ctls(codec); 2563 err = via_auto_create_analog_input_ctls(codec);
2444 if (err < 0) 2564 if (err < 0)
2445 return err; 2565 return err;
@@ -2453,7 +2573,7 @@ static int via_parse_auto_config(struct hda_codec *codec)
2453 spec->mixers[spec->num_mixers++] = spec->kctls.list; 2573 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2454 2574
2455 2575
2456 if (spec->hp_dac_nid && spec->hp_dep_path.depth) { 2576 if (spec->hp_dac_nid && spec->hp_mix_path.depth) {
2457 err = via_hp_build(codec); 2577 err = via_hp_build(codec);
2458 if (err < 0) 2578 if (err < 0)
2459 return err; 2579 return err;