aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLydia Wang <lydiawang@viatech.com.cn>2011-03-23 03:13:28 -0400
committerTakashi Iwai <tiwai@suse.de>2011-03-23 04:53:23 -0400
commit3e95b9aba50deeee69afce87d2bcd94c4cd1d95e (patch)
tree615908e1d78316e5c32bf836eb3e0ae76f9bec2d /sound
parentee3c35c0827de02de414d08b2ddcbb910c2263ab (diff)
ALSA: hda - VIA: Add new power management function.
Use set_widgets_power_state() function to seperately control different codecs' power management actions and to replace the original large function. Also fix some wrong widgets power up sequence which caused no sound issue under Smart5.1 mode and Independent HP mode. Signed-off-by: Lydia Wang <lydiawang@viatech.com.cn> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_via.c938
1 files changed, 453 insertions, 485 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 1371b57c11e8..23cb44086b27 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -154,6 +154,9 @@ struct via_spec {
154 struct delayed_work vt1708_hp_work; 154 struct delayed_work vt1708_hp_work;
155 int vt1708_jack_detectect; 155 int vt1708_jack_detectect;
156 int vt1708_hp_present; 156 int vt1708_hp_present;
157
158 void (*set_widgets_power_state)(struct hda_codec *codec);
159
157#ifdef CONFIG_SND_HDA_POWER_SAVE 160#ifdef CONFIG_SND_HDA_POWER_SAVE
158 struct hda_loopback_check loopback; 161 struct hda_loopback_check loopback;
159#endif 162#endif
@@ -245,7 +248,6 @@ enum {
245}; 248};
246 249
247static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); 250static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
248static void set_jack_power_state(struct hda_codec *codec);
249static int is_aa_path_mute(struct hda_codec *codec); 251static int is_aa_path_mute(struct hda_codec *codec);
250 252
251static void vt1708_start_hp_work(struct via_spec *spec) 253static void vt1708_start_hp_work(struct via_spec *spec)
@@ -271,6 +273,12 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
271 cancel_delayed_work_sync(&spec->vt1708_hp_work); 273 cancel_delayed_work_sync(&spec->vt1708_hp_work);
272} 274}
273 275
276static void set_widgets_power_state(struct hda_codec *codec)
277{
278 struct via_spec *spec = codec->spec;
279 if (spec->set_widgets_power_state)
280 spec->set_widgets_power_state(codec);
281}
274 282
275static int analog_input_switch_put(struct snd_kcontrol *kcontrol, 283static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
276 struct snd_ctl_elem_value *ucontrol) 284 struct snd_ctl_elem_value *ucontrol)
@@ -278,7 +286,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
278 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 286 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
279 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 287 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
280 288
281 set_jack_power_state(codec); 289 set_widgets_power_state(codec);
282 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); 290 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
283 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { 291 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
284 if (is_aa_path_mute(codec)) 292 if (is_aa_path_mute(codec))
@@ -602,482 +610,6 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
602 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); 610 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
603} 611}
604 612
605static void set_jack_power_state(struct hda_codec *codec)
606{
607 struct via_spec *spec = codec->spec;
608 int imux_is_smixer;
609 unsigned int parm;
610
611 if (spec->codec_type == VT1702) {
612 imux_is_smixer = snd_hda_codec_read(
613 codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
614 /* inputs */
615 /* PW 1/2/5 (14h/15h/18h) */
616 parm = AC_PWRST_D3;
617 set_pin_power_state(codec, 0x14, &parm);
618 set_pin_power_state(codec, 0x15, &parm);
619 set_pin_power_state(codec, 0x18, &parm);
620 if (imux_is_smixer)
621 parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
622 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
623 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
624 parm);
625 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
626 parm);
627 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
628 parm);
629 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
630 parm);
631
632 /* outputs */
633 /* PW 3/4 (16h/17h) */
634 parm = AC_PWRST_D3;
635 set_pin_power_state(codec, 0x16, &parm);
636 set_pin_power_state(codec, 0x17, &parm);
637 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
638 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
639 imux_is_smixer ? AC_PWRST_D0 : parm);
640 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
641 parm);
642 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
643 parm);
644 } else if (spec->codec_type == VT1708B_8CH
645 || spec->codec_type == VT1708B_4CH
646 || spec->codec_type == VT1708S) {
647 /* SW0 (17h) = stereo mixer */
648 int is_8ch = spec->codec_type != VT1708B_4CH;
649 imux_is_smixer = snd_hda_codec_read(
650 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
651 == ((spec->codec_type == VT1708S) ? 5 : 0);
652 /* inputs */
653 /* PW 1/2/5 (1ah/1bh/1eh) */
654 parm = AC_PWRST_D3;
655 set_pin_power_state(codec, 0x1a, &parm);
656 set_pin_power_state(codec, 0x1b, &parm);
657 set_pin_power_state(codec, 0x1e, &parm);
658 if (imux_is_smixer)
659 parm = AC_PWRST_D0;
660 /* SW0 (17h), AIW 0/1 (13h/14h) */
661 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
662 parm);
663 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
664 parm);
665 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
666 parm);
667
668 /* outputs */
669 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
670 parm = AC_PWRST_D3;
671 set_pin_power_state(codec, 0x19, &parm);
672 if (spec->smart51_enabled)
673 parm = AC_PWRST_D0;
674 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
675 parm);
676 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
677 parm);
678
679 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
680 if (is_8ch) {
681 parm = AC_PWRST_D3;
682 set_pin_power_state(codec, 0x22, &parm);
683 if (spec->smart51_enabled)
684 parm = AC_PWRST_D0;
685 snd_hda_codec_write(codec, 0x26, 0,
686 AC_VERB_SET_POWER_STATE, parm);
687 snd_hda_codec_write(codec, 0x24, 0,
688 AC_VERB_SET_POWER_STATE, parm);
689 }
690
691 /* PW 3/4/7 (1ch/1dh/23h) */
692 parm = AC_PWRST_D3;
693 /* force to D0 for internal Speaker */
694 set_pin_power_state(codec, 0x1c, &parm);
695 set_pin_power_state(codec, 0x1d, &parm);
696 if (is_8ch)
697 set_pin_power_state(codec, 0x23, &parm);
698 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
699 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
700 imux_is_smixer ? AC_PWRST_D0 : parm);
701 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
702 parm);
703 if (is_8ch) {
704 snd_hda_codec_write(codec, 0x25, 0,
705 AC_VERB_SET_POWER_STATE, parm);
706 snd_hda_codec_write(codec, 0x27, 0,
707 AC_VERB_SET_POWER_STATE, parm);
708 }
709 } else if (spec->codec_type == VT1718S) {
710 /* MUX6 (1eh) = stereo mixer */
711 imux_is_smixer = snd_hda_codec_read(
712 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
713 /* inputs */
714 /* PW 5/6/7 (29h/2ah/2bh) */
715 parm = AC_PWRST_D3;
716 set_pin_power_state(codec, 0x29, &parm);
717 set_pin_power_state(codec, 0x2a, &parm);
718 set_pin_power_state(codec, 0x2b, &parm);
719 if (imux_is_smixer)
720 parm = AC_PWRST_D0;
721 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
722 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
723 parm);
724 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
725 parm);
726 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
727 parm);
728 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
729 parm);
730
731 /* outputs */
732 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
733 parm = AC_PWRST_D3;
734 set_pin_power_state(codec, 0x27, &parm);
735 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
736 parm);
737 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
738 parm);
739
740 /* PW2 (26h), AOW2 (ah) */
741 parm = AC_PWRST_D3;
742 set_pin_power_state(codec, 0x26, &parm);
743 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
744 parm);
745
746 /* PW0/1 (24h/25h) */
747 parm = AC_PWRST_D3;
748 set_pin_power_state(codec, 0x24, &parm);
749 set_pin_power_state(codec, 0x25, &parm);
750 if (!spec->hp_independent_mode) /* check for redirected HP */
751 set_pin_power_state(codec, 0x28, &parm);
752 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
753 parm);
754 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
755 parm);
756 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
757 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
758 imux_is_smixer ? AC_PWRST_D0 : parm);
759 if (spec->hp_independent_mode) {
760 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
761 parm = AC_PWRST_D3;
762 set_pin_power_state(codec, 0x28, &parm);
763 snd_hda_codec_write(codec, 0x1b, 0,
764 AC_VERB_SET_POWER_STATE, parm);
765 snd_hda_codec_write(codec, 0x34, 0,
766 AC_VERB_SET_POWER_STATE, parm);
767 snd_hda_codec_write(codec, 0xc, 0,
768 AC_VERB_SET_POWER_STATE, parm);
769 }
770 } else if (spec->codec_type == VT1716S) {
771 unsigned int mono_out, present;
772 /* SW0 (17h) = stereo mixer */
773 imux_is_smixer = snd_hda_codec_read(
774 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
775 /* inputs */
776 /* PW 1/2/5 (1ah/1bh/1eh) */
777 parm = AC_PWRST_D3;
778 set_pin_power_state(codec, 0x1a, &parm);
779 set_pin_power_state(codec, 0x1b, &parm);
780 set_pin_power_state(codec, 0x1e, &parm);
781 if (imux_is_smixer)
782 parm = AC_PWRST_D0;
783 /* SW0 (17h), AIW0(13h) */
784 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
785 parm);
786 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
787 parm);
788
789 parm = AC_PWRST_D3;
790 set_pin_power_state(codec, 0x1e, &parm);
791 /* PW11 (22h) */
792 if (spec->dmic_enabled)
793 set_pin_power_state(codec, 0x22, &parm);
794 else
795 snd_hda_codec_write(
796 codec, 0x22, 0,
797 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
798
799 /* SW2(26h), AIW1(14h) */
800 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
801 parm);
802 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
803 parm);
804
805 /* outputs */
806 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
807 parm = AC_PWRST_D3;
808 set_pin_power_state(codec, 0x19, &parm);
809 /* Smart 5.1 PW2(1bh) */
810 if (spec->smart51_enabled)
811 set_pin_power_state(codec, 0x1b, &parm);
812 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
813 parm);
814 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
815 parm);
816
817 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
818 parm = AC_PWRST_D3;
819 set_pin_power_state(codec, 0x23, &parm);
820 /* Smart 5.1 PW1(1ah) */
821 if (spec->smart51_enabled)
822 set_pin_power_state(codec, 0x1a, &parm);
823 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
824 parm);
825
826 /* Smart 5.1 PW5(1eh) */
827 if (spec->smart51_enabled)
828 set_pin_power_state(codec, 0x1e, &parm);
829 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
830 parm);
831
832 /* Mono out */
833 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
834 present = snd_hda_jack_detect(codec, 0x1c);
835 if (present)
836 mono_out = 0;
837 else {
838 present = snd_hda_jack_detect(codec, 0x1d);
839 if (!spec->hp_independent_mode && present)
840 mono_out = 0;
841 else
842 mono_out = 1;
843 }
844 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
845 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
846 parm);
847 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
848 parm);
849 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
850 parm);
851
852 /* PW 3/4 (1ch/1dh) */
853 parm = AC_PWRST_D3;
854 set_pin_power_state(codec, 0x1c, &parm);
855 set_pin_power_state(codec, 0x1d, &parm);
856 /* HP Independent Mode, power on AOW3 */
857 if (spec->hp_independent_mode)
858 snd_hda_codec_write(codec, 0x25, 0,
859 AC_VERB_SET_POWER_STATE, parm);
860
861 /* force to D0 for internal Speaker */
862 /* MW0 (16h), AOW0 (10h) */
863 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
864 imux_is_smixer ? AC_PWRST_D0 : parm);
865 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
866 mono_out ? AC_PWRST_D0 : parm);
867 } else if (spec->codec_type == VT2002P) {
868 unsigned int present;
869 /* MUX9 (1eh) = stereo mixer */
870 imux_is_smixer = snd_hda_codec_read(
871 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
872 /* inputs */
873 /* PW 5/6/7 (29h/2ah/2bh) */
874 parm = AC_PWRST_D3;
875 set_pin_power_state(codec, 0x29, &parm);
876 set_pin_power_state(codec, 0x2a, &parm);
877 set_pin_power_state(codec, 0x2b, &parm);
878 if (imux_is_smixer)
879 parm = AC_PWRST_D0;
880 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
881 snd_hda_codec_write(codec, 0x1e, 0,
882 AC_VERB_SET_POWER_STATE, parm);
883 snd_hda_codec_write(codec, 0x1f, 0,
884 AC_VERB_SET_POWER_STATE, parm);
885 snd_hda_codec_write(codec, 0x10, 0,
886 AC_VERB_SET_POWER_STATE, parm);
887 snd_hda_codec_write(codec, 0x11, 0,
888 AC_VERB_SET_POWER_STATE, parm);
889
890 /* outputs */
891 /* AOW0 (8h)*/
892 snd_hda_codec_write(codec, 0x8, 0,
893 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
894
895 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
896 parm = AC_PWRST_D3;
897 set_pin_power_state(codec, 0x26, &parm);
898 snd_hda_codec_write(codec, 0x1c, 0,
899 AC_VERB_SET_POWER_STATE, parm);
900 snd_hda_codec_write(codec, 0x37,
901 0, AC_VERB_SET_POWER_STATE, parm);
902
903 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
904 parm = AC_PWRST_D3;
905 set_pin_power_state(codec, 0x25, &parm);
906 snd_hda_codec_write(codec, 0x19, 0,
907 AC_VERB_SET_POWER_STATE, parm);
908 snd_hda_codec_write(codec, 0x35, 0,
909 AC_VERB_SET_POWER_STATE, parm);
910 if (spec->hp_independent_mode) {
911 snd_hda_codec_write(codec, 0x9, 0,
912 AC_VERB_SET_POWER_STATE, parm);
913 }
914
915 /* Class-D */
916 /* PW0 (24h), MW0(18h), MUX0(34h) */
917 present = snd_hda_jack_detect(codec, 0x25);
918 parm = AC_PWRST_D3;
919 set_pin_power_state(codec, 0x24, &parm);
920 if (present) {
921 snd_hda_codec_write(
922 codec, 0x18, 0,
923 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
924 snd_hda_codec_write(
925 codec, 0x34, 0,
926 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
927 } else {
928 snd_hda_codec_write(
929 codec, 0x18, 0,
930 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
931 snd_hda_codec_write(
932 codec, 0x34, 0,
933 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
934 }
935
936 /* Mono Out */
937 /* PW15 (31h), MW8(17h), MUX8(3bh) */
938 present = snd_hda_jack_detect(codec, 0x26);
939 parm = AC_PWRST_D3;
940 set_pin_power_state(codec, 0x31, &parm);
941 if (present) {
942 snd_hda_codec_write(
943 codec, 0x17, 0,
944 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
945 snd_hda_codec_write(
946 codec, 0x3b, 0,
947 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
948 } else {
949 snd_hda_codec_write(
950 codec, 0x17, 0,
951 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
952 snd_hda_codec_write(
953 codec, 0x3b, 0,
954 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
955 }
956
957 /* MW9 (21h) */
958 if (imux_is_smixer || !is_aa_path_mute(codec))
959 snd_hda_codec_write(
960 codec, 0x21, 0,
961 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
962 else
963 snd_hda_codec_write(
964 codec, 0x21, 0,
965 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
966 } else if (spec->codec_type == VT1812) {
967 unsigned int present;
968 /* MUX10 (1eh) = stereo mixer */
969 imux_is_smixer = snd_hda_codec_read(
970 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
971 /* inputs */
972 /* PW 5/6/7 (29h/2ah/2bh) */
973 parm = AC_PWRST_D3;
974 set_pin_power_state(codec, 0x29, &parm);
975 set_pin_power_state(codec, 0x2a, &parm);
976 set_pin_power_state(codec, 0x2b, &parm);
977 if (imux_is_smixer)
978 parm = AC_PWRST_D0;
979 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
980 snd_hda_codec_write(codec, 0x1e, 0,
981 AC_VERB_SET_POWER_STATE, parm);
982 snd_hda_codec_write(codec, 0x1f, 0,
983 AC_VERB_SET_POWER_STATE, parm);
984 snd_hda_codec_write(codec, 0x10, 0,
985 AC_VERB_SET_POWER_STATE, parm);
986 snd_hda_codec_write(codec, 0x11, 0,
987 AC_VERB_SET_POWER_STATE, parm);
988
989 /* outputs */
990 /* AOW0 (8h)*/
991 snd_hda_codec_write(codec, 0x8, 0,
992 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
993
994 /* PW4 (28h), MW4 (18h), MUX4(38h) */
995 parm = AC_PWRST_D3;
996 set_pin_power_state(codec, 0x28, &parm);
997 snd_hda_codec_write(codec, 0x18, 0,
998 AC_VERB_SET_POWER_STATE, parm);
999 snd_hda_codec_write(codec, 0x38, 0,
1000 AC_VERB_SET_POWER_STATE, parm);
1001
1002 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
1003 parm = AC_PWRST_D3;
1004 set_pin_power_state(codec, 0x25, &parm);
1005 snd_hda_codec_write(codec, 0x15, 0,
1006 AC_VERB_SET_POWER_STATE, parm);
1007 snd_hda_codec_write(codec, 0x35, 0,
1008 AC_VERB_SET_POWER_STATE, parm);
1009 if (spec->hp_independent_mode) {
1010 snd_hda_codec_write(codec, 0x9, 0,
1011 AC_VERB_SET_POWER_STATE, parm);
1012 }
1013
1014 /* Internal Speaker */
1015 /* PW0 (24h), MW0(14h), MUX0(34h) */
1016 present = snd_hda_jack_detect(codec, 0x25);
1017 parm = AC_PWRST_D3;
1018 set_pin_power_state(codec, 0x24, &parm);
1019 if (present) {
1020 snd_hda_codec_write(codec, 0x14, 0,
1021 AC_VERB_SET_POWER_STATE,
1022 AC_PWRST_D3);
1023 snd_hda_codec_write(codec, 0x34, 0,
1024 AC_VERB_SET_POWER_STATE,
1025 AC_PWRST_D3);
1026 } else {
1027 snd_hda_codec_write(codec, 0x14, 0,
1028 AC_VERB_SET_POWER_STATE,
1029 AC_PWRST_D0);
1030 snd_hda_codec_write(codec, 0x34, 0,
1031 AC_VERB_SET_POWER_STATE,
1032 AC_PWRST_D0);
1033 }
1034 /* Mono Out */
1035 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1036 present = snd_hda_jack_detect(codec, 0x28);
1037 parm = AC_PWRST_D3;
1038 set_pin_power_state(codec, 0x31, &parm);
1039 if (present) {
1040 snd_hda_codec_write(codec, 0x1c, 0,
1041 AC_VERB_SET_POWER_STATE,
1042 AC_PWRST_D3);
1043 snd_hda_codec_write(codec, 0x3c, 0,
1044 AC_VERB_SET_POWER_STATE,
1045 AC_PWRST_D3);
1046 snd_hda_codec_write(codec, 0x3e, 0,
1047 AC_VERB_SET_POWER_STATE,
1048 AC_PWRST_D3);
1049 } else {
1050 snd_hda_codec_write(codec, 0x1c, 0,
1051 AC_VERB_SET_POWER_STATE,
1052 AC_PWRST_D0);
1053 snd_hda_codec_write(codec, 0x3c, 0,
1054 AC_VERB_SET_POWER_STATE,
1055 AC_PWRST_D0);
1056 snd_hda_codec_write(codec, 0x3e, 0,
1057 AC_VERB_SET_POWER_STATE,
1058 AC_PWRST_D0);
1059 }
1060
1061 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1062 parm = AC_PWRST_D3;
1063 set_pin_power_state(codec, 0x33, &parm);
1064 snd_hda_codec_write(codec, 0x1d, 0,
1065 AC_VERB_SET_POWER_STATE, parm);
1066 snd_hda_codec_write(codec, 0x3d, 0,
1067 AC_VERB_SET_POWER_STATE, parm);
1068
1069 /* MW9 (21h) */
1070 if (imux_is_smixer || !is_aa_path_mute(codec))
1071 snd_hda_codec_write(
1072 codec, 0x21, 0,
1073 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1074 else
1075 snd_hda_codec_write(
1076 codec, 0x21, 0,
1077 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1078 }
1079}
1080
1081/* 613/*
1082 * input MUX handling 614 * input MUX handling
1083 */ 615 */
@@ -1120,7 +652,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1120 spec->mux_nids[adc_idx], 652 spec->mux_nids[adc_idx],
1121 &spec->cur_mux[adc_idx]); 653 &spec->cur_mux[adc_idx]);
1122 /* update jack power state */ 654 /* update jack power state */
1123 set_jack_power_state(codec); 655 set_widgets_power_state(codec);
1124 656
1125 return ret; 657 return ret;
1126} 658}
@@ -1225,7 +757,7 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1225 spec->hp_independent_mode); 757 spec->hp_independent_mode);
1226 } 758 }
1227 /* update jack power state */ 759 /* update jack power state */
1228 set_jack_power_state(codec); 760 set_widgets_power_state(codec);
1229 return 0; 761 return 0;
1230} 762}
1231 763
@@ -1443,7 +975,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1443 } 975 }
1444 } 976 }
1445 spec->smart51_enabled = *ucontrol->value.integer.value; 977 spec->smart51_enabled = *ucontrol->value.integer.value;
1446 set_jack_power_state(codec); 978 set_widgets_power_state(codec);
1447 return 1; 979 return 1;
1448} 980}
1449 981
@@ -1967,7 +1499,7 @@ static int via_build_controls(struct hda_codec *codec)
1967 } 1499 }
1968 1500
1969 /* init power states */ 1501 /* init power states */
1970 set_jack_power_state(codec); 1502 set_widgets_power_state(codec);
1971 analog_low_current_mode(codec, 1); 1503 analog_low_current_mode(codec, 1);
1972 1504
1973 via_free_kctls(codec); /* no longer needed */ 1505 via_free_kctls(codec); /* no longer needed */
@@ -2195,7 +1727,7 @@ static void via_unsol_event(struct hda_codec *codec,
2195 if (res & VIA_GPIO_EVENT) 1727 if (res & VIA_GPIO_EVENT)
2196 via_gpio_control(codec); 1728 via_gpio_control(codec);
2197 if (res & VIA_JACK_EVENT) 1729 if (res & VIA_JACK_EVENT)
2198 set_jack_power_state(codec); 1730 set_widgets_power_state(codec);
2199 if (res & VIA_MONO_EVENT) 1731 if (res & VIA_MONO_EVENT)
2200 via_mono_automute(codec); 1732 via_mono_automute(codec);
2201 if (res & VIA_SPEAKER_EVENT) 1733 if (res & VIA_SPEAKER_EVENT)
@@ -3642,6 +3174,74 @@ static struct hda_amp_list vt1708B_loopbacks[] = {
3642 { } /* end */ 3174 { } /* end */
3643}; 3175};
3644#endif 3176#endif
3177
3178static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3179{
3180 struct via_spec *spec = codec->spec;
3181 int imux_is_smixer;
3182 unsigned int parm;
3183 int is_8ch = 0;
3184 if (spec->codec_type != VT1708B_4CH)
3185 is_8ch = 1;
3186
3187 /* SW0 (17h) = stereo mixer */
3188 imux_is_smixer =
3189 (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
3190 == ((spec->codec_type == VT1708S) ? 5 : 0));
3191 /* inputs */
3192 /* PW 1/2/5 (1ah/1bh/1eh) */
3193 parm = AC_PWRST_D3;
3194 set_pin_power_state(codec, 0x1a, &parm);
3195 set_pin_power_state(codec, 0x1b, &parm);
3196 set_pin_power_state(codec, 0x1e, &parm);
3197 if (imux_is_smixer)
3198 parm = AC_PWRST_D0;
3199 /* SW0 (17h), AIW 0/1 (13h/14h) */
3200 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
3201 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
3202 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
3203
3204 /* outputs */
3205 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
3206 parm = AC_PWRST_D3;
3207 set_pin_power_state(codec, 0x19, &parm);
3208 if (spec->smart51_enabled)
3209 set_pin_power_state(codec, 0x1b, &parm);
3210 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3211 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3212
3213 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
3214 if (is_8ch) {
3215 parm = AC_PWRST_D3;
3216 set_pin_power_state(codec, 0x22, &parm);
3217 if (spec->smart51_enabled)
3218 set_pin_power_state(codec, 0x1a, &parm);
3219 snd_hda_codec_write(codec, 0x26, 0,
3220 AC_VERB_SET_POWER_STATE, parm);
3221 snd_hda_codec_write(codec, 0x24, 0,
3222 AC_VERB_SET_POWER_STATE, parm);
3223 }
3224
3225 /* PW 3/4/7 (1ch/1dh/23h) */
3226 parm = AC_PWRST_D3;
3227 /* force to D0 for internal Speaker */
3228 set_pin_power_state(codec, 0x1c, &parm);
3229 set_pin_power_state(codec, 0x1d, &parm);
3230 if (is_8ch)
3231 set_pin_power_state(codec, 0x23, &parm);
3232
3233 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
3234 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
3235 imux_is_smixer ? AC_PWRST_D0 : parm);
3236 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3237 if (is_8ch) {
3238 snd_hda_codec_write(codec, 0x25, 0,
3239 AC_VERB_SET_POWER_STATE, parm);
3240 snd_hda_codec_write(codec, 0x27, 0,
3241 AC_VERB_SET_POWER_STATE, parm);
3242 }
3243}
3244
3645static int patch_vt1708S(struct hda_codec *codec); 3245static int patch_vt1708S(struct hda_codec *codec);
3646static int patch_vt1708B_8ch(struct hda_codec *codec) 3246static int patch_vt1708B_8ch(struct hda_codec *codec)
3647{ 3247{
@@ -3692,6 +3292,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
3692 spec->loopback.amplist = vt1708B_loopbacks; 3292 spec->loopback.amplist = vt1708B_loopbacks;
3693#endif 3293#endif
3694 3294
3295 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3296
3695 return 0; 3297 return 0;
3696} 3298}
3697 3299
@@ -3742,6 +3344,8 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
3742 spec->loopback.amplist = vt1708B_loopbacks; 3344 spec->loopback.amplist = vt1708B_loopbacks;
3743#endif 3345#endif
3744 3346
3347 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3348
3745 return 0; 3349 return 0;
3746} 3350}
3747 3351
@@ -4181,6 +3785,7 @@ static int patch_vt1708S(struct hda_codec *codec)
4181 spec->stream_name_analog = "VT1818S Analog"; 3785 spec->stream_name_analog = "VT1818S Analog";
4182 spec->stream_name_digital = "VT1818S Digital"; 3786 spec->stream_name_digital = "VT1818S Digital";
4183 } 3787 }
3788 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
4184 return 0; 3789 return 0;
4185} 3790}
4186 3791
@@ -4438,6 +4043,37 @@ static struct hda_amp_list vt1702_loopbacks[] = {
4438}; 4043};
4439#endif 4044#endif
4440 4045
4046static void set_widgets_power_state_vt1702(struct hda_codec *codec)
4047{
4048 int imux_is_smixer =
4049 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
4050 unsigned int parm;
4051 /* inputs */
4052 /* PW 1/2/5 (14h/15h/18h) */
4053 parm = AC_PWRST_D3;
4054 set_pin_power_state(codec, 0x14, &parm);
4055 set_pin_power_state(codec, 0x15, &parm);
4056 set_pin_power_state(codec, 0x18, &parm);
4057 if (imux_is_smixer)
4058 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
4059 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
4060 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
4061 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm);
4062 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
4063 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm);
4064
4065 /* outputs */
4066 /* PW 3/4 (16h/17h) */
4067 parm = AC_PWRST_D3;
4068 set_pin_power_state(codec, 0x17, &parm);
4069 set_pin_power_state(codec, 0x16, &parm);
4070 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
4071 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
4072 imux_is_smixer ? AC_PWRST_D0 : parm);
4073 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
4074 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
4075}
4076
4441static int patch_vt1702(struct hda_codec *codec) 4077static int patch_vt1702(struct hda_codec *codec)
4442{ 4078{
4443 struct via_spec *spec; 4079 struct via_spec *spec;
@@ -4484,6 +4120,7 @@ static int patch_vt1702(struct hda_codec *codec)
4484 spec->loopback.amplist = vt1702_loopbacks; 4120 spec->loopback.amplist = vt1702_loopbacks;
4485#endif 4121#endif
4486 4122
4123 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
4487 return 0; 4124 return 0;
4488} 4125}
4489 4126
@@ -4825,6 +4462,72 @@ static struct hda_amp_list vt1718S_loopbacks[] = {
4825}; 4462};
4826#endif 4463#endif
4827 4464
4465static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4466{
4467 struct via_spec *spec = codec->spec;
4468 int imux_is_smixer;
4469 unsigned int parm;
4470 /* MUX6 (1eh) = stereo mixer */
4471 imux_is_smixer =
4472 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
4473 /* inputs */
4474 /* PW 5/6/7 (29h/2ah/2bh) */
4475 parm = AC_PWRST_D3;
4476 set_pin_power_state(codec, 0x29, &parm);
4477 set_pin_power_state(codec, 0x2a, &parm);
4478 set_pin_power_state(codec, 0x2b, &parm);
4479 if (imux_is_smixer)
4480 parm = AC_PWRST_D0;
4481 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
4482 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
4483 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
4484 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
4485 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
4486
4487 /* outputs */
4488 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
4489 parm = AC_PWRST_D3;
4490 set_pin_power_state(codec, 0x27, &parm);
4491 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
4492 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
4493
4494 /* PW2 (26h), AOW2 (ah) */
4495 parm = AC_PWRST_D3;
4496 set_pin_power_state(codec, 0x26, &parm);
4497 if (spec->smart51_enabled)
4498 set_pin_power_state(codec, 0x2b, &parm);
4499 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm);
4500
4501 /* PW0 (24h), AOW0 (8h) */
4502 parm = AC_PWRST_D3;
4503 set_pin_power_state(codec, 0x24, &parm);
4504 if (!spec->hp_independent_mode) /* check for redirected HP */
4505 set_pin_power_state(codec, 0x28, &parm);
4506 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
4507 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
4508 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
4509 imux_is_smixer ? AC_PWRST_D0 : parm);
4510
4511 /* PW1 (25h), AOW1 (9h) */
4512 parm = AC_PWRST_D3;
4513 set_pin_power_state(codec, 0x25, &parm);
4514 if (spec->smart51_enabled)
4515 set_pin_power_state(codec, 0x2a, &parm);
4516 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
4517
4518 if (spec->hp_independent_mode) {
4519 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
4520 parm = AC_PWRST_D3;
4521 set_pin_power_state(codec, 0x28, &parm);
4522 snd_hda_codec_write(codec, 0x1b, 0,
4523 AC_VERB_SET_POWER_STATE, parm);
4524 snd_hda_codec_write(codec, 0x34, 0,
4525 AC_VERB_SET_POWER_STATE, parm);
4526 snd_hda_codec_write(codec, 0xc, 0,
4527 AC_VERB_SET_POWER_STATE, parm);
4528 }
4529}
4530
4828static int patch_vt1718S(struct hda_codec *codec) 4531static int patch_vt1718S(struct hda_codec *codec)
4829{ 4532{
4830 struct via_spec *spec; 4533 struct via_spec *spec;
@@ -4886,6 +4589,8 @@ static int patch_vt1718S(struct hda_codec *codec)
4886 spec->loopback.amplist = vt1718S_loopbacks; 4589 spec->loopback.amplist = vt1718S_loopbacks;
4887#endif 4590#endif
4888 4591
4592 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
4593
4889 return 0; 4594 return 0;
4890} 4595}
4891 4596
@@ -4925,8 +4630,7 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4925 snd_hda_codec_write(codec, 0x26, 0, 4630 snd_hda_codec_write(codec, 0x26, 0,
4926 AC_VERB_SET_CONNECT_SEL, index); 4631 AC_VERB_SET_CONNECT_SEL, index);
4927 spec->dmic_enabled = index; 4632 spec->dmic_enabled = index;
4928 set_jack_power_state(codec); 4633 set_widgets_power_state(codec);
4929
4930 return 1; 4634 return 1;
4931} 4635}
4932 4636
@@ -5285,6 +4989,99 @@ static struct hda_amp_list vt1716S_loopbacks[] = {
5285}; 4989};
5286#endif 4990#endif
5287 4991
4992static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
4993{
4994 struct via_spec *spec = codec->spec;
4995 int imux_is_smixer;
4996 unsigned int parm;
4997 unsigned int mono_out, present;
4998 /* SW0 (17h) = stereo mixer */
4999 imux_is_smixer =
5000 (snd_hda_codec_read(codec, 0x17, 0,
5001 AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
5002 /* inputs */
5003 /* PW 1/2/5 (1ah/1bh/1eh) */
5004 parm = AC_PWRST_D3;
5005 set_pin_power_state(codec, 0x1a, &parm);
5006 set_pin_power_state(codec, 0x1b, &parm);
5007 set_pin_power_state(codec, 0x1e, &parm);
5008 if (imux_is_smixer)
5009 parm = AC_PWRST_D0;
5010 /* SW0 (17h), AIW0(13h) */
5011 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
5012 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
5013
5014 parm = AC_PWRST_D3;
5015 set_pin_power_state(codec, 0x1e, &parm);
5016 /* PW11 (22h) */
5017 if (spec->dmic_enabled)
5018 set_pin_power_state(codec, 0x22, &parm);
5019 else
5020 snd_hda_codec_write(codec, 0x22, 0,
5021 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5022
5023 /* SW2(26h), AIW1(14h) */
5024 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm);
5025 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
5026
5027 /* outputs */
5028 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
5029 parm = AC_PWRST_D3;
5030 set_pin_power_state(codec, 0x19, &parm);
5031 /* Smart 5.1 PW2(1bh) */
5032 if (spec->smart51_enabled)
5033 set_pin_power_state(codec, 0x1b, &parm);
5034 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
5035 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
5036
5037 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
5038 parm = AC_PWRST_D3;
5039 set_pin_power_state(codec, 0x23, &parm);
5040 /* Smart 5.1 PW1(1ah) */
5041 if (spec->smart51_enabled)
5042 set_pin_power_state(codec, 0x1a, &parm);
5043 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm);
5044
5045 /* Smart 5.1 PW5(1eh) */
5046 if (spec->smart51_enabled)
5047 set_pin_power_state(codec, 0x1e, &parm);
5048 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm);
5049
5050 /* Mono out */
5051 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
5052 present = snd_hda_jack_detect(codec, 0x1c);
5053
5054 if (present)
5055 mono_out = 0;
5056 else {
5057 present = snd_hda_jack_detect(codec, 0x1d);
5058 if (!spec->hp_independent_mode && present)
5059 mono_out = 0;
5060 else
5061 mono_out = 1;
5062 }
5063 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
5064 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm);
5065 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm);
5066 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm);
5067
5068 /* PW 3/4 (1ch/1dh) */
5069 parm = AC_PWRST_D3;
5070 set_pin_power_state(codec, 0x1c, &parm);
5071 set_pin_power_state(codec, 0x1d, &parm);
5072 /* HP Independent Mode, power on AOW3 */
5073 if (spec->hp_independent_mode)
5074 snd_hda_codec_write(codec, 0x25, 0,
5075 AC_VERB_SET_POWER_STATE, parm);
5076
5077 /* force to D0 for internal Speaker */
5078 /* MW0 (16h), AOW0 (10h) */
5079 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
5080 imux_is_smixer ? AC_PWRST_D0 : parm);
5081 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
5082 mono_out ? AC_PWRST_D0 : parm);
5083}
5084
5288static int patch_vt1716S(struct hda_codec *codec) 5085static int patch_vt1716S(struct hda_codec *codec)
5289{ 5086{
5290 struct via_spec *spec; 5087 struct via_spec *spec;
@@ -5339,6 +5136,7 @@ static int patch_vt1716S(struct hda_codec *codec)
5339 spec->loopback.amplist = vt1716S_loopbacks; 5136 spec->loopback.amplist = vt1716S_loopbacks;
5340#endif 5137#endif
5341 5138
5139 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
5342 return 0; 5140 return 0;
5343} 5141}
5344 5142
@@ -5609,6 +5407,83 @@ static struct hda_amp_list vt2002P_loopbacks[] = {
5609}; 5407};
5610#endif 5408#endif
5611 5409
5410static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
5411{
5412 struct via_spec *spec = codec->spec;
5413 int imux_is_smixer;
5414 unsigned int parm;
5415 unsigned int present;
5416 /* MUX9 (1eh) = stereo mixer */
5417 imux_is_smixer =
5418 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
5419 /* inputs */
5420 /* PW 5/6/7 (29h/2ah/2bh) */
5421 parm = AC_PWRST_D3;
5422 set_pin_power_state(codec, 0x29, &parm);
5423 set_pin_power_state(codec, 0x2a, &parm);
5424 set_pin_power_state(codec, 0x2b, &parm);
5425 parm = AC_PWRST_D0;
5426 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
5427 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
5428 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
5429 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
5430 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
5431
5432 /* outputs */
5433 /* AOW0 (8h)*/
5434 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
5435
5436 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
5437 parm = AC_PWRST_D3;
5438 set_pin_power_state(codec, 0x26, &parm);
5439 snd_hda_codec_write(codec, 0x1c, 0,
5440 AC_VERB_SET_POWER_STATE, parm);
5441 snd_hda_codec_write(codec, 0x37, 0,
5442 AC_VERB_SET_POWER_STATE, parm);
5443
5444 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
5445 parm = AC_PWRST_D3;
5446 set_pin_power_state(codec, 0x25, &parm);
5447 snd_hda_codec_write(codec, 0x19, 0,
5448 AC_VERB_SET_POWER_STATE, parm);
5449 snd_hda_codec_write(codec, 0x35, 0,
5450 AC_VERB_SET_POWER_STATE, parm);
5451
5452 if (spec->hp_independent_mode)
5453 snd_hda_codec_write(codec, 0x9, 0,
5454 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5455
5456 /* Class-D */
5457 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
5458 present = snd_hda_jack_detect(codec, 0x25);
5459
5460 parm = AC_PWRST_D3;
5461 set_pin_power_state(codec, 0x24, &parm);
5462 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
5463 snd_hda_codec_write(codec, 0x18, 0,
5464 AC_VERB_SET_POWER_STATE, parm);
5465 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
5466
5467 /* Mono Out */
5468 present = snd_hda_jack_detect(codec, 0x26);
5469
5470 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
5471 /* PW15 (31h), MW8(17h), MUX8(3bh) */
5472 snd_hda_codec_write(codec, 0x31, 0,
5473 AC_VERB_SET_POWER_STATE, parm);
5474 snd_hda_codec_write(codec, 0x17, 0,
5475 AC_VERB_SET_POWER_STATE, parm);
5476 snd_hda_codec_write(codec, 0x3b, 0,
5477 AC_VERB_SET_POWER_STATE, parm);
5478
5479 /* MW9 (21h) */
5480 if (imux_is_smixer || !is_aa_path_mute(codec))
5481 snd_hda_codec_write(codec, 0x21, 0,
5482 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5483 else
5484 snd_hda_codec_write(codec, 0x21, 0,
5485 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5486}
5612 5487
5613/* patch for vt2002P */ 5488/* patch for vt2002P */
5614static int patch_vt2002P(struct hda_codec *codec) 5489static int patch_vt2002P(struct hda_codec *codec)
@@ -5660,6 +5535,7 @@ static int patch_vt2002P(struct hda_codec *codec)
5660 spec->loopback.amplist = vt2002P_loopbacks; 5535 spec->loopback.amplist = vt2002P_loopbacks;
5661#endif 5536#endif
5662 5537
5538 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
5663 return 0; 5539 return 0;
5664} 5540}
5665 5541
@@ -5931,6 +5807,97 @@ static struct hda_amp_list vt1812_loopbacks[] = {
5931}; 5807};
5932#endif 5808#endif
5933 5809
5810static void set_widgets_power_state_vt1812(struct hda_codec *codec)
5811{
5812 struct via_spec *spec = codec->spec;
5813 int imux_is_smixer =
5814 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
5815 unsigned int parm;
5816 unsigned int present;
5817 /* MUX10 (1eh) = stereo mixer */
5818 imux_is_smixer =
5819 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
5820 /* inputs */
5821 /* PW 5/6/7 (29h/2ah/2bh) */
5822 parm = AC_PWRST_D3;
5823 set_pin_power_state(codec, 0x29, &parm);
5824 set_pin_power_state(codec, 0x2a, &parm);
5825 set_pin_power_state(codec, 0x2b, &parm);
5826 parm = AC_PWRST_D0;
5827 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
5828 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
5829 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
5830 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
5831 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
5832
5833 /* outputs */
5834 /* AOW0 (8h)*/
5835 snd_hda_codec_write(codec, 0x8, 0,
5836 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5837
5838 /* PW4 (28h), MW4 (18h), MUX4(38h) */
5839 parm = AC_PWRST_D3;
5840 set_pin_power_state(codec, 0x28, &parm);
5841 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
5842 snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm);
5843
5844 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
5845 parm = AC_PWRST_D3;
5846 set_pin_power_state(codec, 0x25, &parm);
5847 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm);
5848 snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm);
5849 if (spec->hp_independent_mode)
5850 snd_hda_codec_write(codec, 0x9, 0,
5851 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5852
5853 /* Internal Speaker */
5854 /* PW0 (24h), MW0(14h), MUX0(34h) */
5855 present = snd_hda_jack_detect(codec, 0x25);
5856
5857 parm = AC_PWRST_D3;
5858 set_pin_power_state(codec, 0x24, &parm);
5859 if (present) {
5860 snd_hda_codec_write(codec, 0x14, 0,
5861 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5862 snd_hda_codec_write(codec, 0x34, 0,
5863 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5864 } else {
5865 snd_hda_codec_write(codec, 0x14, 0,
5866 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5867 snd_hda_codec_write(codec, 0x34, 0,
5868 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5869 }
5870
5871
5872 /* Mono Out */
5873 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
5874 present = snd_hda_jack_detect(codec, 0x28);
5875
5876 parm = AC_PWRST_D3;
5877 set_pin_power_state(codec, 0x31, &parm);
5878 if (present) {
5879 snd_hda_codec_write(codec, 0x1c, 0,
5880 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5881 snd_hda_codec_write(codec, 0x3c, 0,
5882 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5883 snd_hda_codec_write(codec, 0x3e, 0,
5884 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5885 } else {
5886 snd_hda_codec_write(codec, 0x1c, 0,
5887 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5888 snd_hda_codec_write(codec, 0x3c, 0,
5889 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5890 snd_hda_codec_write(codec, 0x3e, 0,
5891 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
5892 }
5893
5894 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
5895 parm = AC_PWRST_D3;
5896 set_pin_power_state(codec, 0x33, &parm);
5897 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
5898 snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm);
5899
5900}
5934 5901
5935/* patch for vt1812 */ 5902/* patch for vt1812 */
5936static int patch_vt1812(struct hda_codec *codec) 5903static int patch_vt1812(struct hda_codec *codec)
@@ -5984,6 +5951,7 @@ static int patch_vt1812(struct hda_codec *codec)
5984 spec->loopback.amplist = vt1812_loopbacks; 5951 spec->loopback.amplist = vt1812_loopbacks;
5985#endif 5952#endif
5986 5953
5954 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
5987 return 0; 5955 return 0;
5988} 5956}
5989 5957