aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-03-17 10:56:05 -0400
committerTakashi Iwai <tiwai@suse.de>2015-03-18 04:22:35 -0400
commit688b12cc3ca8a5155b95ce8d01e0e43006813b27 (patch)
tree53ef7a3bbcac6f43a3426bdfdf9566ed46e73136 /sound/pci
parente6feb5d08509be1af2ebc894dae35f32f7b92ab6 (diff)
ALSA: hda - Use the new power control for VIA codecs
VIA codecs used to have the own power controls but they were disabled at transition to the generic parser due to the coding assuming the fixed routes. Now we get the proper support of equivalently fine power management in the generic parser, and the old kludges can be replaced with it. This results in the reduction of lots of dead codes. The advanced PM feature is disabled as default like before for keeping the compatible behavior. It's enabled via "Dynamic Power-Control" mixer element. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_via.c662
1 files changed, 12 insertions, 650 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 2112fbe9e577..d5d1dca4f11b 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -99,7 +99,6 @@ struct via_spec {
99 99
100 /* HP mode source */ 100 /* HP mode source */
101 unsigned int dmic_enabled; 101 unsigned int dmic_enabled;
102 unsigned int no_pin_power_ctl;
103 enum VIA_HDA_CODEC codec_type; 102 enum VIA_HDA_CODEC codec_type;
104 103
105 /* analog low-power control */ 104 /* analog low-power control */
@@ -108,9 +107,6 @@ struct via_spec {
108 /* work to check hp jack state */ 107 /* work to check hp jack state */
109 int hp_work_active; 108 int hp_work_active;
110 int vt1708_jack_detect; 109 int vt1708_jack_detect;
111
112 void (*set_widgets_power_state)(struct hda_codec *codec);
113 unsigned int dac_stream_tag[4];
114}; 110};
115 111
116static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); 112static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
@@ -133,11 +129,12 @@ static struct via_spec *via_new_spec(struct hda_codec *codec)
133 /* VT1708BCE & VT1708S are almost same */ 129 /* VT1708BCE & VT1708S are almost same */
134 if (spec->codec_type == VT1708BCE) 130 if (spec->codec_type == VT1708BCE)
135 spec->codec_type = VT1708S; 131 spec->codec_type = VT1708S;
136 spec->no_pin_power_ctl = 1;
137 spec->gen.indep_hp = 1; 132 spec->gen.indep_hp = 1;
138 spec->gen.keep_eapd_on = 1; 133 spec->gen.keep_eapd_on = 1;
139 spec->gen.pcm_playback_hook = via_playback_pcm_hook; 134 spec->gen.pcm_playback_hook = via_playback_pcm_hook;
140 spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO; 135 spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO;
136 codec->power_mgmt = 1;
137 spec->gen.power_down_unused = 1;
141 return spec; 138 return spec;
142} 139}
143 140
@@ -229,90 +226,6 @@ static void vt1708_update_hp_work(struct hda_codec *codec)
229 vt1708_stop_hp_work(codec); 226 vt1708_stop_hp_work(codec);
230} 227}
231 228
232static void set_widgets_power_state(struct hda_codec *codec)
233{
234#if 0 /* FIXME: the assumed connections don't match always with the
235 * actual routes by the generic parser, so better to disable
236 * the control for safety.
237 */
238 struct via_spec *spec = codec->spec;
239 if (spec->set_widgets_power_state)
240 spec->set_widgets_power_state(codec);
241#endif
242}
243
244static void update_power_state(struct hda_codec *codec, hda_nid_t nid,
245 unsigned int parm)
246{
247 if (snd_hda_check_power_state(codec, nid, parm))
248 return;
249 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
250}
251
252static void update_conv_power_state(struct hda_codec *codec, hda_nid_t nid,
253 unsigned int parm, unsigned int index)
254{
255 struct via_spec *spec = codec->spec;
256 unsigned int format;
257
258 if (snd_hda_check_power_state(codec, nid, parm))
259 return;
260 format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
261 if (format && (spec->dac_stream_tag[index] != format))
262 spec->dac_stream_tag[index] = format;
263
264 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
265 if (parm == AC_PWRST_D0) {
266 format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
267 if (!format && (spec->dac_stream_tag[index] != format))
268 snd_hda_codec_write(codec, nid, 0,
269 AC_VERB_SET_CHANNEL_STREAMID,
270 spec->dac_stream_tag[index]);
271 }
272}
273
274static bool smart51_enabled(struct hda_codec *codec)
275{
276 struct via_spec *spec = codec->spec;
277 return spec->gen.ext_channel_count > 2;
278}
279
280static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
281{
282 struct via_spec *spec = codec->spec;
283 int i;
284
285 for (i = 0; i < spec->gen.multi_ios; i++)
286 if (spec->gen.multi_io[i].pin == pin)
287 return true;
288 return false;
289}
290
291static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
292 unsigned int *affected_parm)
293{
294 unsigned parm;
295 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
296 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
297 >> AC_DEFCFG_MISC_SHIFT
298 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
299 struct via_spec *spec = codec->spec;
300 unsigned present = 0;
301
302 no_presence |= spec->no_pin_power_ctl;
303 if (!no_presence)
304 present = snd_hda_jack_detect(codec, nid);
305 if ((smart51_enabled(codec) && is_smart51_pins(codec, nid))
306 || ((no_presence || present)
307 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
308 *affected_parm = AC_PWRST_D0; /* if it's connected */
309 parm = AC_PWRST_D0;
310 } else
311 parm = AC_PWRST_D3;
312
313 update_power_state(codec, nid, parm);
314}
315
316static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol, 229static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
317 struct snd_ctl_elem_info *uinfo) 230 struct snd_ctl_elem_info *uinfo)
318{ 231{
@@ -323,8 +236,7 @@ static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
323 struct snd_ctl_elem_value *ucontrol) 236 struct snd_ctl_elem_value *ucontrol)
324{ 237{
325 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 238 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
326 struct via_spec *spec = codec->spec; 239 ucontrol->value.enumerated.item[0] = codec->power_mgmt;
327 ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
328 return 0; 240 return 0;
329} 241}
330 242
@@ -333,12 +245,12 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
333{ 245{
334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335 struct via_spec *spec = codec->spec; 247 struct via_spec *spec = codec->spec;
336 unsigned int val = !ucontrol->value.enumerated.item[0]; 248 bool val = !!ucontrol->value.enumerated.item[0];
337 249
338 if (val == spec->no_pin_power_ctl) 250 if (val == codec->power_mgmt)
339 return 0; 251 return 0;
340 spec->no_pin_power_ctl = val; 252 codec->power_mgmt = val;
341 set_widgets_power_state(codec); 253 spec->gen.power_down_unused = val;
342 analog_low_current_mode(codec); 254 analog_low_current_mode(codec);
343 return 1; 255 return 1;
344} 256}
@@ -383,7 +295,7 @@ static void __analog_low_current_mode(struct hda_codec *codec, bool force)
383 bool enable; 295 bool enable;
384 unsigned int verb, parm; 296 unsigned int verb, parm;
385 297
386 if (spec->no_pin_power_ctl) 298 if (!codec->power_mgmt)
387 enable = false; 299 enable = false;
388 else 300 else
389 enable = is_aa_path_mute(codec) && !spec->gen.active_streams; 301 enable = is_aa_path_mute(codec) && !spec->gen.active_streams;
@@ -440,8 +352,7 @@ static int via_build_controls(struct hda_codec *codec)
440 if (err < 0) 352 if (err < 0)
441 return err; 353 return err;
442 354
443 if (spec->set_widgets_power_state) 355 spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
444 spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
445 356
446 for (i = 0; i < spec->num_mixers; i++) { 357 for (i = 0; i < spec->num_mixers; i++) {
447 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 358 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -485,7 +396,6 @@ static int via_suspend(struct hda_codec *codec)
485static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) 396static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
486{ 397{
487 struct via_spec *spec = codec->spec; 398 struct via_spec *spec = codec->spec;
488 set_widgets_power_state(codec);
489 analog_low_current_mode(codec); 399 analog_low_current_mode(codec);
490 vt1708_update_hp_work(codec); 400 vt1708_update_hp_work(codec);
491 return snd_hda_check_amp_list_power(codec, &spec->gen.loopback, nid); 401 return snd_hda_check_amp_list_power(codec, &spec->gen.loopback, nid);
@@ -573,34 +483,6 @@ static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = {
573 {} /* terminator */ 483 {} /* terminator */
574}; 484};
575 485
576static void via_jack_powerstate_event(struct hda_codec *codec,
577 struct hda_jack_callback *tbl)
578{
579 set_widgets_power_state(codec);
580}
581
582static void via_set_jack_unsol_events(struct hda_codec *codec)
583{
584 struct via_spec *spec = codec->spec;
585 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
586 hda_nid_t pin;
587 int i;
588
589 for (i = 0; i < cfg->line_outs; i++) {
590 pin = cfg->line_out_pins[i];
591 if (pin && is_jack_detectable(codec, pin))
592 snd_hda_jack_detect_enable_callback(codec, pin,
593 via_jack_powerstate_event);
594 }
595
596 for (i = 0; i < cfg->num_inputs; i++) {
597 pin = cfg->line_out_pins[i];
598 if (pin && is_jack_detectable(codec, pin))
599 snd_hda_jack_detect_enable_callback(codec, pin,
600 via_jack_powerstate_event);
601 }
602}
603
604static const struct badness_table via_main_out_badness = { 486static const struct badness_table via_main_out_badness = {
605 .no_primary_dac = 0x10000, 487 .no_primary_dac = 0x10000,
606 .no_dac = 0x4000, 488 .no_dac = 0x4000,
@@ -634,7 +516,9 @@ static int via_parse_auto_config(struct hda_codec *codec)
634 if (err < 0) 516 if (err < 0)
635 return err; 517 return err;
636 518
637 via_set_jack_unsol_events(codec); 519 /* disable widget PM at start for compatibility */
520 codec->power_mgmt = 0;
521 spec->gen.power_down_unused = 0;
638 return 0; 522 return 0;
639} 523}
640 524
@@ -647,7 +531,6 @@ static int via_init(struct hda_codec *codec)
647 snd_hda_sequence_write(codec, spec->init_verbs[i]); 531 snd_hda_sequence_write(codec, spec->init_verbs[i]);
648 532
649 /* init power states */ 533 /* init power states */
650 set_widgets_power_state(codec);
651 __analog_low_current_mode(codec, true); 534 __analog_low_current_mode(codec, true);
652 535
653 snd_hda_gen_init(codec); 536 snd_hda_gen_init(codec);
@@ -767,78 +650,6 @@ static int patch_vt1709(struct hda_codec *codec)
767 return 0; 650 return 0;
768} 651}
769 652
770static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
771{
772 struct via_spec *spec = codec->spec;
773 int imux_is_smixer;
774 unsigned int parm;
775 int is_8ch = 0;
776 if ((spec->codec_type != VT1708B_4CH) &&
777 (codec->vendor_id != 0x11064397))
778 is_8ch = 1;
779
780 /* SW0 (17h) = stereo mixer */
781 imux_is_smixer =
782 (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
783 == ((spec->codec_type == VT1708S) ? 5 : 0));
784 /* inputs */
785 /* PW 1/2/5 (1ah/1bh/1eh) */
786 parm = AC_PWRST_D3;
787 set_pin_power_state(codec, 0x1a, &parm);
788 set_pin_power_state(codec, 0x1b, &parm);
789 set_pin_power_state(codec, 0x1e, &parm);
790 if (imux_is_smixer)
791 parm = AC_PWRST_D0;
792 /* SW0 (17h), AIW 0/1 (13h/14h) */
793 update_power_state(codec, 0x17, parm);
794 update_power_state(codec, 0x13, parm);
795 update_power_state(codec, 0x14, parm);
796
797 /* outputs */
798 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
799 parm = AC_PWRST_D3;
800 set_pin_power_state(codec, 0x19, &parm);
801 if (smart51_enabled(codec))
802 set_pin_power_state(codec, 0x1b, &parm);
803 update_power_state(codec, 0x18, parm);
804 update_power_state(codec, 0x11, parm);
805
806 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
807 if (is_8ch) {
808 parm = AC_PWRST_D3;
809 set_pin_power_state(codec, 0x22, &parm);
810 if (smart51_enabled(codec))
811 set_pin_power_state(codec, 0x1a, &parm);
812 update_power_state(codec, 0x26, parm);
813 update_power_state(codec, 0x24, parm);
814 } else if (codec->vendor_id == 0x11064397) {
815 /* PW7(23h), SW2(27h), AOW2(25h) */
816 parm = AC_PWRST_D3;
817 set_pin_power_state(codec, 0x23, &parm);
818 if (smart51_enabled(codec))
819 set_pin_power_state(codec, 0x1a, &parm);
820 update_power_state(codec, 0x27, parm);
821 update_power_state(codec, 0x25, parm);
822 }
823
824 /* PW 3/4/7 (1ch/1dh/23h) */
825 parm = AC_PWRST_D3;
826 /* force to D0 for internal Speaker */
827 set_pin_power_state(codec, 0x1c, &parm);
828 set_pin_power_state(codec, 0x1d, &parm);
829 if (is_8ch)
830 set_pin_power_state(codec, 0x23, &parm);
831
832 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
833 update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
834 update_power_state(codec, 0x10, parm);
835 if (is_8ch) {
836 update_power_state(codec, 0x25, parm);
837 update_power_state(codec, 0x27, parm);
838 } else if (codec->vendor_id == 0x11064397 && spec->gen.indep_hp_enabled)
839 update_power_state(codec, 0x25, parm);
840}
841
842static int patch_vt1708S(struct hda_codec *codec); 653static int patch_vt1708S(struct hda_codec *codec);
843static int patch_vt1708B(struct hda_codec *codec) 654static int patch_vt1708B(struct hda_codec *codec)
844{ 655{
@@ -863,9 +674,6 @@ static int patch_vt1708B(struct hda_codec *codec)
863 } 674 }
864 675
865 codec->patch_ops = via_patch_ops; 676 codec->patch_ops = via_patch_ops;
866
867 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
868
869 return 0; 677 return 0;
870} 678}
871 679
@@ -931,8 +739,6 @@ static int patch_vt1708S(struct hda_codec *codec)
931 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs; 739 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
932 740
933 codec->patch_ops = via_patch_ops; 741 codec->patch_ops = via_patch_ops;
934
935 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
936 return 0; 742 return 0;
937} 743}
938 744
@@ -946,36 +752,6 @@ static const struct hda_verb vt1702_init_verbs[] = {
946 { } 752 { }
947}; 753};
948 754
949static void set_widgets_power_state_vt1702(struct hda_codec *codec)
950{
951 int imux_is_smixer =
952 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
953 unsigned int parm;
954 /* inputs */
955 /* PW 1/2/5 (14h/15h/18h) */
956 parm = AC_PWRST_D3;
957 set_pin_power_state(codec, 0x14, &parm);
958 set_pin_power_state(codec, 0x15, &parm);
959 set_pin_power_state(codec, 0x18, &parm);
960 if (imux_is_smixer)
961 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
962 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
963 update_power_state(codec, 0x13, parm);
964 update_power_state(codec, 0x12, parm);
965 update_power_state(codec, 0x1f, parm);
966 update_power_state(codec, 0x20, parm);
967
968 /* outputs */
969 /* PW 3/4 (16h/17h) */
970 parm = AC_PWRST_D3;
971 set_pin_power_state(codec, 0x17, &parm);
972 set_pin_power_state(codec, 0x16, &parm);
973 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
974 update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm);
975 update_power_state(codec, 0x10, parm);
976 update_power_state(codec, 0x1d, parm);
977}
978
979static int patch_vt1702(struct hda_codec *codec) 755static int patch_vt1702(struct hda_codec *codec)
980{ 756{
981 struct via_spec *spec; 757 struct via_spec *spec;
@@ -1005,8 +781,6 @@ static int patch_vt1702(struct hda_codec *codec)
1005 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs; 781 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
1006 782
1007 codec->patch_ops = via_patch_ops; 783 codec->patch_ops = via_patch_ops;
1008
1009 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
1010 return 0; 784 return 0;
1011} 785}
1012 786
@@ -1021,71 +795,6 @@ static const struct hda_verb vt1718S_init_verbs[] = {
1021 { } 795 { }
1022}; 796};
1023 797
1024static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
1025{
1026 struct via_spec *spec = codec->spec;
1027 int imux_is_smixer;
1028 unsigned int parm, parm2;
1029 /* MUX6 (1eh) = stereo mixer */
1030 imux_is_smixer =
1031 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
1032 /* inputs */
1033 /* PW 5/6/7 (29h/2ah/2bh) */
1034 parm = AC_PWRST_D3;
1035 set_pin_power_state(codec, 0x29, &parm);
1036 set_pin_power_state(codec, 0x2a, &parm);
1037 set_pin_power_state(codec, 0x2b, &parm);
1038 if (imux_is_smixer)
1039 parm = AC_PWRST_D0;
1040 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
1041 update_power_state(codec, 0x1e, parm);
1042 update_power_state(codec, 0x1f, parm);
1043 update_power_state(codec, 0x10, parm);
1044 update_power_state(codec, 0x11, parm);
1045
1046 /* outputs */
1047 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
1048 parm = AC_PWRST_D3;
1049 set_pin_power_state(codec, 0x27, &parm);
1050 update_power_state(codec, 0x1a, parm);
1051 parm2 = parm; /* for pin 0x0b */
1052
1053 /* PW2 (26h), AOW2 (ah) */
1054 parm = AC_PWRST_D3;
1055 set_pin_power_state(codec, 0x26, &parm);
1056 if (smart51_enabled(codec))
1057 set_pin_power_state(codec, 0x2b, &parm);
1058 update_power_state(codec, 0xa, parm);
1059
1060 /* PW0 (24h), AOW0 (8h) */
1061 parm = AC_PWRST_D3;
1062 set_pin_power_state(codec, 0x24, &parm);
1063 if (!spec->gen.indep_hp_enabled) /* check for redirected HP */
1064 set_pin_power_state(codec, 0x28, &parm);
1065 update_power_state(codec, 0x8, parm);
1066 if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3)
1067 parm = parm2;
1068 update_power_state(codec, 0xb, parm);
1069 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
1070 update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm);
1071
1072 /* PW1 (25h), AOW1 (9h) */
1073 parm = AC_PWRST_D3;
1074 set_pin_power_state(codec, 0x25, &parm);
1075 if (smart51_enabled(codec))
1076 set_pin_power_state(codec, 0x2a, &parm);
1077 update_power_state(codec, 0x9, parm);
1078
1079 if (spec->gen.indep_hp_enabled) {
1080 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
1081 parm = AC_PWRST_D3;
1082 set_pin_power_state(codec, 0x28, &parm);
1083 update_power_state(codec, 0x1b, parm);
1084 update_power_state(codec, 0x34, parm);
1085 update_power_state(codec, 0xc, parm);
1086 }
1087}
1088
1089/* Add a connection to the primary DAC from AA-mixer for some codecs 798/* Add a connection to the primary DAC from AA-mixer for some codecs
1090 * This isn't listed from the raw info, but the chip has a secret connection. 799 * This isn't listed from the raw info, but the chip has a secret connection.
1091 */ 800 */
@@ -1146,9 +855,6 @@ static int patch_vt1718S(struct hda_codec *codec)
1146 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs; 855 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
1147 856
1148 codec->patch_ops = via_patch_ops; 857 codec->patch_ops = via_patch_ops;
1149
1150 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
1151
1152 return 0; 858 return 0;
1153} 859}
1154 860
@@ -1188,7 +894,6 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
1188 snd_hda_codec_write(codec, 0x26, 0, 894 snd_hda_codec_write(codec, 0x26, 0,
1189 AC_VERB_SET_CONNECT_SEL, index); 895 AC_VERB_SET_CONNECT_SEL, index);
1190 spec->dmic_enabled = index; 896 spec->dmic_enabled = index;
1191 set_widgets_power_state(codec);
1192 return 1; 897 return 1;
1193} 898}
1194 899
@@ -1223,95 +928,6 @@ static const struct hda_verb vt1716S_init_verbs[] = {
1223 { } 928 { }
1224}; 929};
1225 930
1226static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
1227{
1228 struct via_spec *spec = codec->spec;
1229 int imux_is_smixer;
1230 unsigned int parm;
1231 unsigned int mono_out, present;
1232 /* SW0 (17h) = stereo mixer */
1233 imux_is_smixer =
1234 (snd_hda_codec_read(codec, 0x17, 0,
1235 AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
1236 /* inputs */
1237 /* PW 1/2/5 (1ah/1bh/1eh) */
1238 parm = AC_PWRST_D3;
1239 set_pin_power_state(codec, 0x1a, &parm);
1240 set_pin_power_state(codec, 0x1b, &parm);
1241 set_pin_power_state(codec, 0x1e, &parm);
1242 if (imux_is_smixer)
1243 parm = AC_PWRST_D0;
1244 /* SW0 (17h), AIW0(13h) */
1245 update_power_state(codec, 0x17, parm);
1246 update_power_state(codec, 0x13, parm);
1247
1248 parm = AC_PWRST_D3;
1249 set_pin_power_state(codec, 0x1e, &parm);
1250 /* PW11 (22h) */
1251 if (spec->dmic_enabled)
1252 set_pin_power_state(codec, 0x22, &parm);
1253 else
1254 update_power_state(codec, 0x22, AC_PWRST_D3);
1255
1256 /* SW2(26h), AIW1(14h) */
1257 update_power_state(codec, 0x26, parm);
1258 update_power_state(codec, 0x14, parm);
1259
1260 /* outputs */
1261 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
1262 parm = AC_PWRST_D3;
1263 set_pin_power_state(codec, 0x19, &parm);
1264 /* Smart 5.1 PW2(1bh) */
1265 if (smart51_enabled(codec))
1266 set_pin_power_state(codec, 0x1b, &parm);
1267 update_power_state(codec, 0x18, parm);
1268 update_power_state(codec, 0x11, parm);
1269
1270 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
1271 parm = AC_PWRST_D3;
1272 set_pin_power_state(codec, 0x23, &parm);
1273 /* Smart 5.1 PW1(1ah) */
1274 if (smart51_enabled(codec))
1275 set_pin_power_state(codec, 0x1a, &parm);
1276 update_power_state(codec, 0x27, parm);
1277
1278 /* Smart 5.1 PW5(1eh) */
1279 if (smart51_enabled(codec))
1280 set_pin_power_state(codec, 0x1e, &parm);
1281 update_power_state(codec, 0x25, parm);
1282
1283 /* Mono out */
1284 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
1285 present = snd_hda_jack_detect(codec, 0x1c);
1286
1287 if (present)
1288 mono_out = 0;
1289 else {
1290 present = snd_hda_jack_detect(codec, 0x1d);
1291 if (!spec->gen.indep_hp_enabled && present)
1292 mono_out = 0;
1293 else
1294 mono_out = 1;
1295 }
1296 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
1297 update_power_state(codec, 0x28, parm);
1298 update_power_state(codec, 0x29, parm);
1299 update_power_state(codec, 0x2a, parm);
1300
1301 /* PW 3/4 (1ch/1dh) */
1302 parm = AC_PWRST_D3;
1303 set_pin_power_state(codec, 0x1c, &parm);
1304 set_pin_power_state(codec, 0x1d, &parm);
1305 /* HP Independent Mode, power on AOW3 */
1306 if (spec->gen.indep_hp_enabled)
1307 update_power_state(codec, 0x25, parm);
1308
1309 /* force to D0 for internal Speaker */
1310 /* MW0 (16h), AOW0 (10h) */
1311 update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
1312 update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm);
1313}
1314
1315static int patch_vt1716S(struct hda_codec *codec) 931static int patch_vt1716S(struct hda_codec *codec)
1316{ 932{
1317 struct via_spec *spec; 933 struct via_spec *spec;
@@ -1339,8 +955,6 @@ static int patch_vt1716S(struct hda_codec *codec)
1339 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer; 955 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
1340 956
1341 codec->patch_ops = via_patch_ops; 957 codec->patch_ops = via_patch_ops;
1342
1343 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
1344 return 0; 958 return 0;
1345} 959}
1346 960
@@ -1366,98 +980,6 @@ static const struct hda_verb vt1802_init_verbs[] = {
1366 { } 980 { }
1367}; 981};
1368 982
1369static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
1370{
1371 struct via_spec *spec = codec->spec;
1372 int imux_is_smixer;
1373 unsigned int parm;
1374 unsigned int present;
1375 /* MUX9 (1eh) = stereo mixer */
1376 imux_is_smixer =
1377 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
1378 /* inputs */
1379 /* PW 5/6/7 (29h/2ah/2bh) */
1380 parm = AC_PWRST_D3;
1381 set_pin_power_state(codec, 0x29, &parm);
1382 set_pin_power_state(codec, 0x2a, &parm);
1383 set_pin_power_state(codec, 0x2b, &parm);
1384 parm = AC_PWRST_D0;
1385 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
1386 update_power_state(codec, 0x1e, parm);
1387 update_power_state(codec, 0x1f, parm);
1388 update_power_state(codec, 0x10, parm);
1389 update_power_state(codec, 0x11, parm);
1390
1391 /* outputs */
1392 /* AOW0 (8h)*/
1393 update_power_state(codec, 0x8, parm);
1394
1395 if (spec->codec_type == VT1802) {
1396 /* PW4 (28h), MW4 (18h), MUX4(38h) */
1397 parm = AC_PWRST_D3;
1398 set_pin_power_state(codec, 0x28, &parm);
1399 update_power_state(codec, 0x18, parm);
1400 update_power_state(codec, 0x38, parm);
1401 } else {
1402 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
1403 parm = AC_PWRST_D3;
1404 set_pin_power_state(codec, 0x26, &parm);
1405 update_power_state(codec, 0x1c, parm);
1406 update_power_state(codec, 0x37, parm);
1407 }
1408
1409 if (spec->codec_type == VT1802) {
1410 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
1411 parm = AC_PWRST_D3;
1412 set_pin_power_state(codec, 0x25, &parm);
1413 update_power_state(codec, 0x15, parm);
1414 update_power_state(codec, 0x35, parm);
1415 } else {
1416 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
1417 parm = AC_PWRST_D3;
1418 set_pin_power_state(codec, 0x25, &parm);
1419 update_power_state(codec, 0x19, parm);
1420 update_power_state(codec, 0x35, parm);
1421 }
1422
1423 if (spec->gen.indep_hp_enabled)
1424 update_power_state(codec, 0x9, AC_PWRST_D0);
1425
1426 /* Class-D */
1427 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
1428 present = snd_hda_jack_detect(codec, 0x25);
1429
1430 parm = AC_PWRST_D3;
1431 set_pin_power_state(codec, 0x24, &parm);
1432 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
1433 if (spec->codec_type == VT1802)
1434 update_power_state(codec, 0x14, parm);
1435 else
1436 update_power_state(codec, 0x18, parm);
1437 update_power_state(codec, 0x34, parm);
1438
1439 /* Mono Out */
1440 present = snd_hda_jack_detect(codec, 0x26);
1441
1442 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
1443 if (spec->codec_type == VT1802) {
1444 /* PW15 (33h), MW8(1ch), MUX8(3ch) */
1445 update_power_state(codec, 0x33, parm);
1446 update_power_state(codec, 0x1c, parm);
1447 update_power_state(codec, 0x3c, parm);
1448 } else {
1449 /* PW15 (31h), MW8(17h), MUX8(3bh) */
1450 update_power_state(codec, 0x31, parm);
1451 update_power_state(codec, 0x17, parm);
1452 update_power_state(codec, 0x3b, parm);
1453 }
1454 /* MW9 (21h) */
1455 if (imux_is_smixer || !is_aa_path_mute(codec))
1456 update_power_state(codec, 0x21, AC_PWRST_D0);
1457 else
1458 update_power_state(codec, 0x21, AC_PWRST_D3);
1459}
1460
1461/* 983/*
1462 * pin fix-up 984 * pin fix-up
1463 */ 985 */
@@ -1541,8 +1063,6 @@ static int patch_vt2002P(struct hda_codec *codec)
1541 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs; 1063 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
1542 1064
1543 codec->patch_ops = via_patch_ops; 1065 codec->patch_ops = via_patch_ops;
1544
1545 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
1546 return 0; 1066 return 0;
1547} 1067}
1548 1068
@@ -1556,81 +1076,6 @@ static const struct hda_verb vt1812_init_verbs[] = {
1556 { } 1076 { }
1557}; 1077};
1558 1078
1559static void set_widgets_power_state_vt1812(struct hda_codec *codec)
1560{
1561 struct via_spec *spec = codec->spec;
1562 unsigned int parm;
1563 unsigned int present;
1564 /* inputs */
1565 /* PW 5/6/7 (29h/2ah/2bh) */
1566 parm = AC_PWRST_D3;
1567 set_pin_power_state(codec, 0x29, &parm);
1568 set_pin_power_state(codec, 0x2a, &parm);
1569 set_pin_power_state(codec, 0x2b, &parm);
1570 parm = AC_PWRST_D0;
1571 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
1572 update_power_state(codec, 0x1e, parm);
1573 update_power_state(codec, 0x1f, parm);
1574 update_power_state(codec, 0x10, parm);
1575 update_power_state(codec, 0x11, parm);
1576
1577 /* outputs */
1578 /* AOW0 (8h)*/
1579 update_power_state(codec, 0x8, AC_PWRST_D0);
1580
1581 /* PW4 (28h), MW4 (18h), MUX4(38h) */
1582 parm = AC_PWRST_D3;
1583 set_pin_power_state(codec, 0x28, &parm);
1584 update_power_state(codec, 0x18, parm);
1585 update_power_state(codec, 0x38, parm);
1586
1587 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
1588 parm = AC_PWRST_D3;
1589 set_pin_power_state(codec, 0x25, &parm);
1590 update_power_state(codec, 0x15, parm);
1591 update_power_state(codec, 0x35, parm);
1592 if (spec->gen.indep_hp_enabled)
1593 update_power_state(codec, 0x9, AC_PWRST_D0);
1594
1595 /* Internal Speaker */
1596 /* PW0 (24h), MW0(14h), MUX0(34h) */
1597 present = snd_hda_jack_detect(codec, 0x25);
1598
1599 parm = AC_PWRST_D3;
1600 set_pin_power_state(codec, 0x24, &parm);
1601 if (present) {
1602 update_power_state(codec, 0x14, AC_PWRST_D3);
1603 update_power_state(codec, 0x34, AC_PWRST_D3);
1604 } else {
1605 update_power_state(codec, 0x14, AC_PWRST_D0);
1606 update_power_state(codec, 0x34, AC_PWRST_D0);
1607 }
1608
1609
1610 /* Mono Out */
1611 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1612 present = snd_hda_jack_detect(codec, 0x28);
1613
1614 parm = AC_PWRST_D3;
1615 set_pin_power_state(codec, 0x31, &parm);
1616 if (present) {
1617 update_power_state(codec, 0x1c, AC_PWRST_D3);
1618 update_power_state(codec, 0x3c, AC_PWRST_D3);
1619 update_power_state(codec, 0x3e, AC_PWRST_D3);
1620 } else {
1621 update_power_state(codec, 0x1c, AC_PWRST_D0);
1622 update_power_state(codec, 0x3c, AC_PWRST_D0);
1623 update_power_state(codec, 0x3e, AC_PWRST_D0);
1624 }
1625
1626 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1627 parm = AC_PWRST_D3;
1628 set_pin_power_state(codec, 0x33, &parm);
1629 update_power_state(codec, 0x1d, parm);
1630 update_power_state(codec, 0x3d, parm);
1631
1632}
1633
1634/* patch for vt1812 */ 1079/* patch for vt1812 */
1635static int patch_vt1812(struct hda_codec *codec) 1080static int patch_vt1812(struct hda_codec *codec)
1636{ 1081{
@@ -1657,8 +1102,6 @@ static int patch_vt1812(struct hda_codec *codec)
1657 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs; 1102 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
1658 1103
1659 codec->patch_ops = via_patch_ops; 1104 codec->patch_ops = via_patch_ops;
1660
1661 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
1662 return 0; 1105 return 0;
1663} 1106}
1664 1107
@@ -1674,84 +1117,6 @@ static const struct hda_verb vt3476_init_verbs[] = {
1674 { } 1117 { }
1675}; 1118};
1676 1119
1677static void set_widgets_power_state_vt3476(struct hda_codec *codec)
1678{
1679 struct via_spec *spec = codec->spec;
1680 int imux_is_smixer;
1681 unsigned int parm, parm2;
1682 /* MUX10 (1eh) = stereo mixer */
1683 imux_is_smixer =
1684 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 4;
1685 /* inputs */
1686 /* PW 5/6/7 (29h/2ah/2bh) */
1687 parm = AC_PWRST_D3;
1688 set_pin_power_state(codec, 0x29, &parm);
1689 set_pin_power_state(codec, 0x2a, &parm);
1690 set_pin_power_state(codec, 0x2b, &parm);
1691 if (imux_is_smixer)
1692 parm = AC_PWRST_D0;
1693 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
1694 update_power_state(codec, 0x1e, parm);
1695 update_power_state(codec, 0x1f, parm);
1696 update_power_state(codec, 0x10, parm);
1697 update_power_state(codec, 0x11, parm);
1698
1699 /* outputs */
1700 /* PW3 (27h), MW3(37h), AOW3 (bh) */
1701 if (spec->codec_type == VT1705CF) {
1702 parm = AC_PWRST_D3;
1703 update_power_state(codec, 0x27, parm);
1704 update_power_state(codec, 0x37, parm);
1705 } else {
1706 parm = AC_PWRST_D3;
1707 set_pin_power_state(codec, 0x27, &parm);
1708 update_power_state(codec, 0x37, parm);
1709 }
1710
1711 /* PW2 (26h), MW2(36h), AOW2 (ah) */
1712 parm = AC_PWRST_D3;
1713 set_pin_power_state(codec, 0x26, &parm);
1714 update_power_state(codec, 0x36, parm);
1715 if (smart51_enabled(codec)) {
1716 /* PW7(2bh), MW7(3bh), MUX7(1Bh) */
1717 set_pin_power_state(codec, 0x2b, &parm);
1718 update_power_state(codec, 0x3b, parm);
1719 update_power_state(codec, 0x1b, parm);
1720 }
1721 update_conv_power_state(codec, 0xa, parm, 2);
1722
1723 /* PW1 (25h), MW1(35h), AOW1 (9h) */
1724 parm = AC_PWRST_D3;
1725 set_pin_power_state(codec, 0x25, &parm);
1726 update_power_state(codec, 0x35, parm);
1727 if (smart51_enabled(codec)) {
1728 /* PW6(2ah), MW6(3ah), MUX6(1ah) */
1729 set_pin_power_state(codec, 0x2a, &parm);
1730 update_power_state(codec, 0x3a, parm);
1731 update_power_state(codec, 0x1a, parm);
1732 }
1733 update_conv_power_state(codec, 0x9, parm, 1);
1734
1735 /* PW4 (28h), MW4 (38h), MUX4(18h), AOW3(bh)/AOW0(8h) */
1736 parm = AC_PWRST_D3;
1737 set_pin_power_state(codec, 0x28, &parm);
1738 update_power_state(codec, 0x38, parm);
1739 update_power_state(codec, 0x18, parm);
1740 if (spec->gen.indep_hp_enabled)
1741 update_conv_power_state(codec, 0xb, parm, 3);
1742 parm2 = parm; /* for pin 0x0b */
1743
1744 /* PW0 (24h), MW0(34h), MW9(3fh), AOW0 (8h) */
1745 parm = AC_PWRST_D3;
1746 set_pin_power_state(codec, 0x24, &parm);
1747 update_power_state(codec, 0x34, parm);
1748 if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3)
1749 parm = parm2;
1750 update_conv_power_state(codec, 0x8, parm, 0);
1751 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
1752 update_power_state(codec, 0x3f, imux_is_smixer ? AC_PWRST_D0 : parm);
1753}
1754
1755static int patch_vt3476(struct hda_codec *codec) 1120static int patch_vt3476(struct hda_codec *codec)
1756{ 1121{
1757 struct via_spec *spec; 1122 struct via_spec *spec;
@@ -1775,9 +1140,6 @@ static int patch_vt3476(struct hda_codec *codec)
1775 spec->init_verbs[spec->num_iverbs++] = vt3476_init_verbs; 1140 spec->init_verbs[spec->num_iverbs++] = vt3476_init_verbs;
1776 1141
1777 codec->patch_ops = via_patch_ops; 1142 codec->patch_ops = via_patch_ops;
1778
1779 spec->set_widgets_power_state = set_widgets_power_state_vt3476;
1780
1781 return 0; 1143 return 0;
1782} 1144}
1783 1145