alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Lydia Wang <lydiawang@viatech.com.cn>
To: alsa-devel@alsa-project.org
Cc: tiwai@suse.de, HaraldWelte@viatech.com, lydiawang@viatech.com.cn
Subject: [PATCH] ALSA: VIA HDA: Add new power management function
Date: Wed, 23 Mar 2011 15:13:28 +0800	[thread overview]
Message-ID: <4D899D98.1040609@viatech.com.cn> (raw)

From: Lydia Wang <lydiawang@viatech.com.cn>
Subject: ALSA: VIA HDA: 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>
---
 sound/pci/hda/patch_via.c |  937 ++++++++++++++++++++++------------------------
 1 file changed, 452 insertions(+), 485 deletions(-)

--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -154,6 +154,9 @@
 	struct delayed_work vt1708_hp_work;
 	int vt1708_jack_detectect;
 	int vt1708_hp_present;
+
+	void (*set_widgets_power_state)(struct hda_codec *codec);
+
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 	struct hda_loopback_check loopback;
 #endif
@@ -245,7 +248,6 @@
 };
 
 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
-static void set_jack_power_state(struct hda_codec *codec);
 static int is_aa_path_mute(struct hda_codec *codec);
 
 static void vt1708_start_hp_work(struct via_spec *spec)
@@ -271,6 +273,12 @@
 	cancel_delayed_work_sync(&spec->vt1708_hp_work);
 }
 
+static void set_widgets_power_state(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	if (spec->set_widgets_power_state)
+		spec->set_widgets_power_state(codec);
+}
 
 static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
@@ -278,7 +286,7 @@
 	int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
-	set_jack_power_state(codec);
+	set_widgets_power_state(codec);
 	analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
 	if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
 		if (is_aa_path_mute(codec))
@@ -602,482 +610,6 @@
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
 }
 
-static void set_jack_power_state(struct hda_codec *codec)
-{
-	struct via_spec *spec = codec->spec;
-	int imux_is_smixer;
-	unsigned int parm;
-
-	if (spec->codec_type == VT1702) {
-		imux_is_smixer = snd_hda_codec_read(
-			codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
-		/* inputs */
-		/* PW 1/2/5 (14h/15h/18h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x14, &parm);
-		set_pin_power_state(codec, 0x15, &parm);
-		set_pin_power_state(codec, 0x18, &parm);
-		if (imux_is_smixer)
-			parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
-		/* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
-		snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* outputs */
-		/* PW 3/4 (16h/17h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x16, &parm);
-		set_pin_power_state(codec, 0x17, &parm);
-		/* MW0 (1ah), AOW 0/1 (10h/1dh) */
-		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
-				    imux_is_smixer ? AC_PWRST_D0 : parm);
-		snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-	} else if (spec->codec_type == VT1708B_8CH
-		   || spec->codec_type == VT1708B_4CH
-		   || spec->codec_type == VT1708S) {
-		/* SW0 (17h) = stereo mixer */
-		int is_8ch = spec->codec_type != VT1708B_4CH;
-		imux_is_smixer = snd_hda_codec_read(
-			codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
-			== ((spec->codec_type == VT1708S)  ? 5 : 0);
-		/* inputs */
-		/* PW 1/2/5 (1ah/1bh/1eh) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x1a, &parm);
-		set_pin_power_state(codec, 0x1b, &parm);
-		set_pin_power_state(codec, 0x1e, &parm);
-		if (imux_is_smixer)
-			parm = AC_PWRST_D0;
-		/* SW0 (17h), AIW 0/1 (13h/14h) */
-		snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* outputs */
-		/* PW0 (19h), SW1 (18h), AOW1 (11h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x19, &parm);
-		if (spec->smart51_enabled)
-			parm = AC_PWRST_D0;
-		snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* PW6 (22h), SW2 (26h), AOW2 (24h) */
-		if (is_8ch) {
-			parm = AC_PWRST_D3;
-			set_pin_power_state(codec, 0x22, &parm);
-			if (spec->smart51_enabled)
-				parm = AC_PWRST_D0;
-			snd_hda_codec_write(codec, 0x26, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-			snd_hda_codec_write(codec, 0x24, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-		}
-
-		/* PW 3/4/7 (1ch/1dh/23h) */
-		parm = AC_PWRST_D3;
-		/* force to D0 for internal Speaker */
-		set_pin_power_state(codec, 0x1c, &parm);
-		set_pin_power_state(codec, 0x1d, &parm);
-		if (is_8ch)
-			set_pin_power_state(codec, 0x23, &parm);
-		/* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
-		snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
-				    imux_is_smixer ? AC_PWRST_D0 : parm);
-		snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		if (is_8ch) {
-			snd_hda_codec_write(codec, 0x25, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-			snd_hda_codec_write(codec, 0x27, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-		}
-	}  else if (spec->codec_type == VT1718S) {
-		/* MUX6 (1eh) = stereo mixer */
-		imux_is_smixer = snd_hda_codec_read(
-			codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
-		/* inputs */
-		/* PW 5/6/7 (29h/2ah/2bh) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x29, &parm);
-		set_pin_power_state(codec, 0x2a, &parm);
-		set_pin_power_state(codec, 0x2b, &parm);
-		if (imux_is_smixer)
-			parm = AC_PWRST_D0;
-		/* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
-		snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* outputs */
-		/* PW3 (27h), MW2 (1ah), AOW3 (bh) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x27, &parm);
-		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* PW2 (26h), AOW2 (ah) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x26, &parm);
-		snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* PW0/1 (24h/25h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x24, &parm);
-		set_pin_power_state(codec, 0x25, &parm);
-		if (!spec->hp_independent_mode) /* check for redirected HP */
-			set_pin_power_state(codec, 0x28, &parm);
-		snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		/* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
-		snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
-				    imux_is_smixer ? AC_PWRST_D0 : parm);
-		if (spec->hp_independent_mode) {
-			/* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
-			parm = AC_PWRST_D3;
-			set_pin_power_state(codec, 0x28, &parm);
-			snd_hda_codec_write(codec, 0x1b, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-			snd_hda_codec_write(codec, 0x34, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-			snd_hda_codec_write(codec, 0xc, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-		}
-	} else if (spec->codec_type == VT1716S) {
-		unsigned int mono_out, present;
-		/* SW0 (17h) = stereo mixer */
-		imux_is_smixer = snd_hda_codec_read(
-			codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) ==  5;
-		/* inputs */
-		/* PW 1/2/5 (1ah/1bh/1eh) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x1a, &parm);
-		set_pin_power_state(codec, 0x1b, &parm);
-		set_pin_power_state(codec, 0x1e, &parm);
-		if (imux_is_smixer)
-			parm = AC_PWRST_D0;
-		/* SW0 (17h), AIW0(13h) */
-		snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x1e, &parm);
-		/* PW11 (22h) */
-		if (spec->dmic_enabled)
-			set_pin_power_state(codec, 0x22, &parm);
-		else
-			snd_hda_codec_write(
-				codec, 0x22, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-
-		/* SW2(26h), AIW1(14h) */
-		snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* outputs */
-		/* PW0 (19h), SW1 (18h), AOW1 (11h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x19, &parm);
-		/* Smart 5.1 PW2(1bh) */
-		if (spec->smart51_enabled)
-			set_pin_power_state(codec, 0x1b, &parm);
-		snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* PW7 (23h), SW3 (27h), AOW3 (25h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x23, &parm);
-		/* Smart 5.1 PW1(1ah) */
-		if (spec->smart51_enabled)
-			set_pin_power_state(codec, 0x1a, &parm);
-		snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* Smart 5.1 PW5(1eh) */
-		if (spec->smart51_enabled)
-			set_pin_power_state(codec, 0x1e, &parm);
-		snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* Mono out */
-		/* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
-		present = snd_hda_jack_detect(codec, 0x1c);
-		if (present)
-			mono_out = 0;
-		else {
-			present = snd_hda_jack_detect(codec, 0x1d);
-			if (!spec->hp_independent_mode && present)
-				mono_out = 0;
-			else
-				mono_out = 1;
-		}
-		parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
-		snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-		snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
-				    parm);
-
-		/* PW 3/4 (1ch/1dh) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x1c, &parm);
-		set_pin_power_state(codec, 0x1d, &parm);
-		/* HP Independent Mode, power on AOW3 */
-		if (spec->hp_independent_mode)
-			snd_hda_codec_write(codec, 0x25, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-
-		/* force to D0 for internal Speaker */
-		/* MW0 (16h), AOW0 (10h) */
-		snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
-				    imux_is_smixer ? AC_PWRST_D0 : parm);
-		snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
-				    mono_out ? AC_PWRST_D0 : parm);
-	} else if (spec->codec_type == VT2002P) {
-		unsigned int present;
-		/* MUX9 (1eh) = stereo mixer */
-		imux_is_smixer = snd_hda_codec_read(
-			codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
-		/* inputs */
-		/* PW 5/6/7 (29h/2ah/2bh) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x29, &parm);
-		set_pin_power_state(codec, 0x2a, &parm);
-		set_pin_power_state(codec, 0x2b, &parm);
-		if (imux_is_smixer)
-			parm = AC_PWRST_D0;
-		/* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
-		snd_hda_codec_write(codec, 0x1e, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x1f, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x10, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x11, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-
-		/* outputs */
-		/* AOW0 (8h)*/
-		snd_hda_codec_write(codec, 0x8, 0,
-				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-
-		/* PW4 (26h), MW4 (1ch), MUX4(37h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x26, &parm);
-		snd_hda_codec_write(codec, 0x1c, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x37,
-				    0, AC_VERB_SET_POWER_STATE, parm);
-
-		/* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x25, &parm);
-		snd_hda_codec_write(codec, 0x19, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x35, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		if (spec->hp_independent_mode)	{
-			snd_hda_codec_write(codec, 0x9, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-		}
-
-		/* Class-D */
-		/* PW0 (24h), MW0(18h), MUX0(34h) */
-		present = snd_hda_jack_detect(codec, 0x25);
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x24, &parm);
-		if (present) {
-			snd_hda_codec_write(
-				codec, 0x18, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-			snd_hda_codec_write(
-				codec, 0x34, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-		} else {
-			snd_hda_codec_write(
-				codec, 0x18, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-			snd_hda_codec_write(
-				codec, 0x34, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-		}
-
-		/* Mono Out */
-		/* PW15 (31h), MW8(17h), MUX8(3bh) */
-		present = snd_hda_jack_detect(codec, 0x26);
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x31, &parm);
-		if (present) {
-			snd_hda_codec_write(
-				codec, 0x17, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-			snd_hda_codec_write(
-				codec, 0x3b, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-		} else {
-			snd_hda_codec_write(
-				codec, 0x17, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-			snd_hda_codec_write(
-				codec, 0x3b, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-		}
-
-		/* MW9 (21h) */
-		if (imux_is_smixer || !is_aa_path_mute(codec))
-			snd_hda_codec_write(
-				codec, 0x21, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-		else
-			snd_hda_codec_write(
-				codec, 0x21, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-	} else if (spec->codec_type == VT1812) {
-		unsigned int present;
-		/* MUX10 (1eh) = stereo mixer */
-		imux_is_smixer = snd_hda_codec_read(
-			codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
-		/* inputs */
-		/* PW 5/6/7 (29h/2ah/2bh) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x29, &parm);
-		set_pin_power_state(codec, 0x2a, &parm);
-		set_pin_power_state(codec, 0x2b, &parm);
-		if (imux_is_smixer)
-			parm = AC_PWRST_D0;
-		/* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
-		snd_hda_codec_write(codec, 0x1e, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x1f, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x10, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x11, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-
-		/* outputs */
-		/* AOW0 (8h)*/
-		snd_hda_codec_write(codec, 0x8, 0,
-				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-
-		/* PW4 (28h), MW4 (18h), MUX4(38h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x28, &parm);
-		snd_hda_codec_write(codec, 0x18, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x38, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-
-		/* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x25, &parm);
-		snd_hda_codec_write(codec, 0x15, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x35, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		if (spec->hp_independent_mode)	{
-			snd_hda_codec_write(codec, 0x9, 0,
-					    AC_VERB_SET_POWER_STATE, parm);
-		}
-
-		/* Internal Speaker */
-		/* PW0 (24h), MW0(14h), MUX0(34h) */
-		present = snd_hda_jack_detect(codec, 0x25);
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x24, &parm);
-		if (present) {
-			snd_hda_codec_write(codec, 0x14, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D3);
-			snd_hda_codec_write(codec, 0x34, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D3);
-		} else {
-			snd_hda_codec_write(codec, 0x14, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D0);
-			snd_hda_codec_write(codec, 0x34, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D0);
-		}
-		/* Mono Out */
-		/* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
-		present = snd_hda_jack_detect(codec, 0x28);
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x31, &parm);
-		if (present) {
-			snd_hda_codec_write(codec, 0x1c, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D3);
-			snd_hda_codec_write(codec, 0x3c, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D3);
-			snd_hda_codec_write(codec, 0x3e, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D3);
-		} else {
-			snd_hda_codec_write(codec, 0x1c, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D0);
-			snd_hda_codec_write(codec, 0x3c, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D0);
-			snd_hda_codec_write(codec, 0x3e, 0,
-					    AC_VERB_SET_POWER_STATE,
-					    AC_PWRST_D0);
-		}
-
-		/* PW15 (33h), MW15 (1dh), MUX15(3dh) */
-		parm = AC_PWRST_D3;
-		set_pin_power_state(codec, 0x33, &parm);
-		snd_hda_codec_write(codec, 0x1d, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-		snd_hda_codec_write(codec, 0x3d, 0,
-				    AC_VERB_SET_POWER_STATE, parm);
-
-		/* MW9 (21h) */
-		if (imux_is_smixer || !is_aa_path_mute(codec))
-			snd_hda_codec_write(
-				codec, 0x21, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
-		else
-			snd_hda_codec_write(
-				codec, 0x21, 0,
-				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-	}
-}
-
 /*
  * input MUX handling
  */
@@ -1120,7 +652,7 @@
 				     spec->mux_nids[adc_idx],
 				     &spec->cur_mux[adc_idx]);
 	/* update jack power state */
-	set_jack_power_state(codec);
+	set_widgets_power_state(codec);
 
 	return ret;
 }
@@ -1225,7 +757,7 @@
 			     spec->hp_independent_mode);
 	}
 	/* update jack power state */
-	set_jack_power_state(codec);
+	set_widgets_power_state(codec);
 	return 0;
 }
 
@@ -1443,7 +975,7 @@
 		}
 	}
 	spec->smart51_enabled = *ucontrol->value.integer.value;
-	set_jack_power_state(codec);
+	set_widgets_power_state(codec);
 	return 1;
 }
 
@@ -1967,7 +1499,7 @@
 	}
 
 	/* init power states */
-	set_jack_power_state(codec);
+	set_widgets_power_state(codec);
 	analog_low_current_mode(codec, 1);
 
 	via_free_kctls(codec); /* no longer needed */
@@ -2195,7 +1727,7 @@
 	if (res & VIA_GPIO_EVENT)
 		via_gpio_control(codec);
 	if (res & VIA_JACK_EVENT)
-		set_jack_power_state(codec);
+		set_widgets_power_state(codec);
 	if (res & VIA_MONO_EVENT)
 		via_mono_automute(codec);
 	if (res & VIA_SPEAKER_EVENT)
@@ -3642,6 +3174,74 @@
 	{ } /* end */
 };
 #endif
+
+static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	int imux_is_smixer;
+	unsigned int parm;
+	int is_8ch = 0;
+	if (spec->codec_type != VT1708B_4CH)
+		is_8ch = 1;
+
+	/* SW0 (17h) = stereo mixer */
+	imux_is_smixer =
+	(snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
+	 == ((spec->codec_type == VT1708S) ? 5 : 0));
+	/* inputs */
+	/* PW 1/2/5 (1ah/1bh/1eh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x1a, &parm);
+	set_pin_power_state(codec, 0x1b, &parm);
+	set_pin_power_state(codec, 0x1e, &parm);
+	if (imux_is_smixer)
+		parm = AC_PWRST_D0;
+	/* SW0 (17h), AIW 0/1 (13h/14h) */
+	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* outputs */
+	/* PW0 (19h), SW1 (18h), AOW1 (11h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x19, &parm);
+	if (spec->smart51_enabled)
+		set_pin_power_state(codec, 0x1b, &parm);
+	snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* PW6 (22h), SW2 (26h), AOW2 (24h) */
+	if (is_8ch) {
+		parm = AC_PWRST_D3;
+		set_pin_power_state(codec, 0x22, &parm);
+		if (spec->smart51_enabled)
+			set_pin_power_state(codec, 0x1a, &parm);
+		snd_hda_codec_write(codec, 0x26, 0,
+				    AC_VERB_SET_POWER_STATE, parm);
+		snd_hda_codec_write(codec, 0x24, 0,
+				    AC_VERB_SET_POWER_STATE, parm);
+	}
+
+	/* PW 3/4/7 (1ch/1dh/23h) */
+	parm = AC_PWRST_D3;
+	/* force to D0 for internal Speaker */
+	set_pin_power_state(codec, 0x1c, &parm);
+	set_pin_power_state(codec, 0x1d, &parm);
+	if (is_8ch)
+		set_pin_power_state(codec, 0x23, &parm);
+
+	/* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
+	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
+			    imux_is_smixer ? AC_PWRST_D0 : parm);
+	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
+	if (is_8ch) {
+		snd_hda_codec_write(codec, 0x25, 0,
+				    AC_VERB_SET_POWER_STATE, parm);
+		snd_hda_codec_write(codec, 0x27, 0,
+				    AC_VERB_SET_POWER_STATE, parm);
+	}
+}
+
 static int patch_vt1708S(struct hda_codec *codec);
 static int patch_vt1708B_8ch(struct hda_codec *codec)
 {
@@ -3692,6 +3292,8 @@
 	spec->loopback.amplist = vt1708B_loopbacks;
 #endif
 
+	spec->set_widgets_power_state =  set_widgets_power_state_vt1708B;
+
 	return 0;
 }
 
@@ -3742,6 +3344,8 @@
 	spec->loopback.amplist = vt1708B_loopbacks;
 #endif
 
+	spec->set_widgets_power_state =  set_widgets_power_state_vt1708B;
+
 	return 0;
 }
 
@@ -4438,6 +4042,37 @@
 };
 #endif
 
+static void set_widgets_power_state_vt1702(struct hda_codec *codec)
+{
+	int imux_is_smixer =
+	snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
+	unsigned int parm;
+	/* inputs */
+	/* PW 1/2/5 (14h/15h/18h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x14, &parm);
+	set_pin_power_state(codec, 0x15, &parm);
+	set_pin_power_state(codec, 0x18, &parm);
+	if (imux_is_smixer)
+		parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
+	/* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
+	snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* outputs */
+	/* PW 3/4 (16h/17h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x17, &parm);
+	set_pin_power_state(codec, 0x16, &parm);
+	/* MW0 (1ah), AOW 0/1 (10h/1dh) */
+	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
+			    imux_is_smixer ? AC_PWRST_D0 : parm);
+	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
+}
+
 static int patch_vt1702(struct hda_codec *codec)
 {
 	struct via_spec *spec;
@@ -4484,6 +4119,7 @@
 	spec->loopback.amplist = vt1702_loopbacks;
 #endif
 
+	spec->set_widgets_power_state =  set_widgets_power_state_vt1702;
 	return 0;
 }
 
@@ -4825,6 +4461,72 @@
 };
 #endif
 
+static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	int imux_is_smixer;
+	unsigned int parm;
+	/* MUX6 (1eh) = stereo mixer */
+	imux_is_smixer =
+	snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
+	/* inputs */
+	/* PW 5/6/7 (29h/2ah/2bh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x29, &parm);
+	set_pin_power_state(codec, 0x2a, &parm);
+	set_pin_power_state(codec, 0x2b, &parm);
+	if (imux_is_smixer)
+		parm = AC_PWRST_D0;
+	/* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
+	snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* outputs */
+	/* PW3 (27h), MW2 (1ah), AOW3 (bh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x27, &parm);
+	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* PW2 (26h), AOW2 (ah) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x26, &parm);
+	if (spec->smart51_enabled)
+		set_pin_power_state(codec, 0x2b, &parm);
+	snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* PW0 (24h), AOW0 (8h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x24, &parm);
+	if (!spec->hp_independent_mode) /* check for redirected HP */
+		set_pin_power_state(codec, 0x28, &parm);
+	snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
+	/* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
+	snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
+			    imux_is_smixer ? AC_PWRST_D0 : parm);
+
+	/* PW1 (25h), AOW1 (9h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x25, &parm);
+	if (spec->smart51_enabled)
+		set_pin_power_state(codec, 0x2a, &parm);
+	snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	if (spec->hp_independent_mode) {
+		/* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
+		parm = AC_PWRST_D3;
+		set_pin_power_state(codec, 0x28, &parm);
+		snd_hda_codec_write(codec, 0x1b, 0,
+				    AC_VERB_SET_POWER_STATE, parm);
+		snd_hda_codec_write(codec, 0x34, 0,
+				    AC_VERB_SET_POWER_STATE, parm);
+		snd_hda_codec_write(codec, 0xc, 0,
+				    AC_VERB_SET_POWER_STATE, parm);
+	}
+}
+
 static int patch_vt1718S(struct hda_codec *codec)
 {
 	struct via_spec *spec;
@@ -4886,6 +4588,8 @@
 	spec->loopback.amplist = vt1718S_loopbacks;
 #endif
 
+	spec->set_widgets_power_state =  set_widgets_power_state_vt1718S;
+
 	return 0;
 }
 
@@ -4925,8 +4629,7 @@
 	snd_hda_codec_write(codec, 0x26, 0,
 					       AC_VERB_SET_CONNECT_SEL, index);
 	spec->dmic_enabled = index;
-	set_jack_power_state(codec);
-
+	set_widgets_power_state(codec);
 	return 1;
 }
 
@@ -5285,6 +4988,99 @@
 };
 #endif
 
+static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	int imux_is_smixer;
+	unsigned int parm;
+	unsigned int mono_out, present;
+	/* SW0 (17h) = stereo mixer */
+	imux_is_smixer =
+	(snd_hda_codec_read(codec, 0x17, 0,
+			    AC_VERB_GET_CONNECT_SEL, 0x00) ==  5);
+	/* inputs */
+	/* PW 1/2/5 (1ah/1bh/1eh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x1a, &parm);
+	set_pin_power_state(codec, 0x1b, &parm);
+	set_pin_power_state(codec, 0x1e, &parm);
+	if (imux_is_smixer)
+		parm = AC_PWRST_D0;
+	/* SW0 (17h), AIW0(13h) */
+	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x1e, &parm);
+	/* PW11 (22h) */
+	if (spec->dmic_enabled)
+		set_pin_power_state(codec, 0x22, &parm);
+	else
+		snd_hda_codec_write(codec, 0x22, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+
+	/* SW2(26h), AIW1(14h) */
+	snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* outputs */
+	/* PW0 (19h), SW1 (18h), AOW1 (11h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x19, &parm);
+	/* Smart 5.1 PW2(1bh) */
+	if (spec->smart51_enabled)
+		set_pin_power_state(codec, 0x1b, &parm);
+	snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* PW7 (23h), SW3 (27h), AOW3 (25h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x23, &parm);
+	/* Smart 5.1 PW1(1ah) */
+	if (spec->smart51_enabled)
+		set_pin_power_state(codec, 0x1a, &parm);
+	snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* Smart 5.1 PW5(1eh) */
+	if (spec->smart51_enabled)
+		set_pin_power_state(codec, 0x1e, &parm);
+	snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* Mono out */
+	/* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
+	present = snd_hda_jack_detect(codec, 0x1c);
+
+	if (present)
+		mono_out = 0;
+	else {
+		present = snd_hda_jack_detect(codec, 0x1d);
+		if (!spec->hp_independent_mode && present)
+			mono_out = 0;
+		else
+			mono_out = 1;
+	}
+	parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
+	snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* PW 3/4 (1ch/1dh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x1c, &parm);
+	set_pin_power_state(codec, 0x1d, &parm);
+	/* HP Independent Mode, power on AOW3 */
+	if (spec->hp_independent_mode)
+		snd_hda_codec_write(codec, 0x25, 0,
+				    AC_VERB_SET_POWER_STATE, parm);
+
+	/* force to D0 for internal Speaker */
+	/* MW0 (16h), AOW0 (10h) */
+	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
+			    imux_is_smixer ? AC_PWRST_D0 : parm);
+	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
+			    mono_out ? AC_PWRST_D0 : parm);
+}
+
 static int patch_vt1716S(struct hda_codec *codec)
 {
 	struct via_spec *spec;
@@ -5339,6 +5135,7 @@
 	spec->loopback.amplist = vt1716S_loopbacks;
 #endif
 
+	spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
 	return 0;
 }
 
@@ -5609,6 +5406,83 @@
 };
 #endif
 
+static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	int imux_is_smixer;
+	unsigned int parm;
+	unsigned int present;
+	/* MUX9 (1eh) = stereo mixer */
+	imux_is_smixer =
+	snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
+	/* inputs */
+	/* PW 5/6/7 (29h/2ah/2bh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x29, &parm);
+	set_pin_power_state(codec, 0x2a, &parm);
+	set_pin_power_state(codec, 0x2b, &parm);
+	parm = AC_PWRST_D0;
+	/* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
+	snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* outputs */
+	/* AOW0 (8h)*/
+	snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* PW4 (26h), MW4 (1ch), MUX4(37h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x26, &parm);
+	snd_hda_codec_write(codec, 0x1c, 0,
+			    AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x37, 0,
+			    AC_VERB_SET_POWER_STATE, parm);
+
+	/* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x25, &parm);
+	snd_hda_codec_write(codec, 0x19, 0,
+			    AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x35, 0,
+			    AC_VERB_SET_POWER_STATE, parm);
+
+	if (spec->hp_independent_mode)
+		snd_hda_codec_write(codec, 0x9, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+
+	/* Class-D */
+	/* PW0 (24h), MW0(18h/14h), MUX0(34h) */
+	present = snd_hda_jack_detect(codec, 0x25);
+
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x24, &parm);
+	parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
+	snd_hda_codec_write(codec, 0x18, 0,
+			    AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* Mono Out */
+	present = snd_hda_jack_detect(codec, 0x26);
+
+	parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
+	/* PW15 (31h), MW8(17h), MUX8(3bh) */
+	snd_hda_codec_write(codec, 0x31, 0,
+			    AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x17, 0,
+			    AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x3b, 0,
+			    AC_VERB_SET_POWER_STATE, parm);
+
+	/* MW9 (21h) */
+	if (imux_is_smixer || !is_aa_path_mute(codec))
+		snd_hda_codec_write(codec, 0x21, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+	else
+		snd_hda_codec_write(codec, 0x21, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+}
 
 /* patch for vt2002P */
 static int patch_vt2002P(struct hda_codec *codec)
@@ -5660,6 +5534,7 @@
 	spec->loopback.amplist = vt2002P_loopbacks;
 #endif
 
+	spec->set_widgets_power_state =  set_widgets_power_state_vt2002P;
 	return 0;
 }
 
@@ -5931,6 +5806,97 @@
 };
 #endif
 
+static void set_widgets_power_state_vt1812(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	int imux_is_smixer =
+	snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
+	unsigned int parm;
+	unsigned int present;
+	/* MUX10 (1eh) = stereo mixer */
+	imux_is_smixer =
+	snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
+	/* inputs */
+	/* PW 5/6/7 (29h/2ah/2bh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x29, &parm);
+	set_pin_power_state(codec, 0x2a, &parm);
+	set_pin_power_state(codec, 0x2b, &parm);
+	parm = AC_PWRST_D0;
+	/* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
+	snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* outputs */
+	/* AOW0 (8h)*/
+	snd_hda_codec_write(codec, 0x8, 0,
+			    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+
+	/* PW4 (28h), MW4 (18h), MUX4(38h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x28, &parm);
+	snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm);
+
+	/* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x25, &parm);
+	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm);
+	if (spec->hp_independent_mode)
+		snd_hda_codec_write(codec, 0x9, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+
+	/* Internal Speaker */
+	/* PW0 (24h), MW0(14h), MUX0(34h) */
+	present = snd_hda_jack_detect(codec, 0x25);
+
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x24, &parm);
+	if (present) {
+		snd_hda_codec_write(codec, 0x14, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+		snd_hda_codec_write(codec, 0x34, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+	} else {
+		snd_hda_codec_write(codec, 0x14, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+		snd_hda_codec_write(codec, 0x34, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+	}
+
+
+	/* Mono Out */
+	/* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
+	present = snd_hda_jack_detect(codec, 0x28);
+
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x31, &parm);
+	if (present) {
+		snd_hda_codec_write(codec, 0x1c, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+		snd_hda_codec_write(codec, 0x3c, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+		snd_hda_codec_write(codec, 0x3e, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+	} else {
+		snd_hda_codec_write(codec, 0x1c, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+		snd_hda_codec_write(codec, 0x3c, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+		snd_hda_codec_write(codec, 0x3e, 0,
+				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+	}
+
+	/* PW15 (33h), MW15 (1dh), MUX15(3dh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x33, &parm);
+	snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
+	snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm);
+
+}
 
 /* patch for vt1812 */
 static int patch_vt1812(struct hda_codec *codec)
@@ -5984,6 +5950,7 @@
 	spec->loopback.amplist = vt1812_loopbacks;
 #endif
 
+	spec->set_widgets_power_state =  set_widgets_power_state_vt1812;
 	return 0;
 }

             reply	other threads:[~2011-03-23  7:13 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-23  7:13 Lydia Wang [this message]
2011-03-23  7:48 ` [PATCH] ALSA: VIA HDA: Add new power management function Takashi Iwai
     [not found]   ` <5B2BE0DB92BC8F4694F815C2F34E0D5F660ABA@exchbj03.viatech.com.bj>
2011-03-23  7:57     ` 答复: " Takashi Iwai
     [not found]       ` <5B2BE0DB92BC8F4694F815C2F34E0D5F660ACB@exchbj03.viatech.com.bj>
2011-03-23  8:55         ` 答复: " Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D899D98.1040609@viatech.com.cn \
    --to=lydiawang@viatech.com.cn \
    --cc=HaraldWelte@viatech.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).