summaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_via.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r--sound/pci/hda/patch_via.c1526
1 files changed, 864 insertions, 662 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 0997031c48d..605c99e1e52 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -98,24 +98,30 @@ enum VIA_HDA_CODEC {
VT1716S,
VT2002P,
VT1812,
+ VT1802,
CODEC_TYPES,
};
+#define VT2002P_COMPATIBLE(spec) \
+ ((spec)->codec_type == VT2002P ||\
+ (spec)->codec_type == VT1812 ||\
+ (spec)->codec_type == VT1802)
+
struct via_spec {
/* codec parameterization */
- struct snd_kcontrol_new *mixers[6];
+ const struct snd_kcontrol_new *mixers[6];
unsigned int num_mixers;
- struct hda_verb *init_verbs[5];
+ const struct hda_verb *init_verbs[5];
unsigned int num_iverbs;
char *stream_name_analog;
- struct hda_pcm_stream *stream_analog_playback;
- struct hda_pcm_stream *stream_analog_capture;
+ const struct hda_pcm_stream *stream_analog_playback;
+ const struct hda_pcm_stream *stream_analog_capture;
char *stream_name_digital;
- struct hda_pcm_stream *stream_digital_playback;
- struct hda_pcm_stream *stream_digital_capture;
+ const struct hda_pcm_stream *stream_digital_playback;
+ const struct hda_pcm_stream *stream_digital_capture;
/* playback */
struct hda_multi_out multiout;
@@ -123,7 +129,7 @@ struct via_spec {
/* capture */
unsigned int num_adc_nids;
- hda_nid_t *adc_nids;
+ const hda_nid_t *adc_nids;
hda_nid_t mux_nids[3];
hda_nid_t dig_in_nid;
hda_nid_t dig_in_pin;
@@ -154,6 +160,9 @@ struct via_spec {
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
@@ -218,17 +227,19 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
codec_type = VT1812;
else if (dev_id == 0x0440)
codec_type = VT1708S;
+ else if ((dev_id & 0xfff) == 0x446)
+ codec_type = VT1802;
else
codec_type = UNKNOWN;
return codec_type;
};
+#define VIA_JACK_EVENT 0x20
#define VIA_HP_EVENT 0x01
#define VIA_GPIO_EVENT 0x02
-#define VIA_JACK_EVENT 0x04
-#define VIA_MONO_EVENT 0x08
-#define VIA_SPEAKER_EVENT 0x10
-#define VIA_BIND_HP_EVENT 0x20
+#define VIA_MONO_EVENT 0x03
+#define VIA_SPEAKER_EVENT 0x04
+#define VIA_BIND_HP_EVENT 0x05
enum {
VIA_CTL_WIDGET_VOL,
@@ -245,7 +256,6 @@ enum {
};
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 +281,12 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
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 +294,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
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))
@@ -394,54 +410,54 @@ static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
.put = bind_pin_switch_put, \
.private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
-static struct snd_kcontrol_new via_control_templates[] = {
+static const struct snd_kcontrol_new via_control_templates[] = {
HDA_CODEC_VOLUME(NULL, 0, 0, 0),
HDA_CODEC_MUTE(NULL, 0, 0, 0),
ANALOG_INPUT_MUTE,
BIND_PIN_MUTE,
};
-static hda_nid_t vt1708_adc_nids[2] = {
+static const hda_nid_t vt1708_adc_nids[2] = {
/* ADC1-2 */
0x15, 0x27
};
-static hda_nid_t vt1709_adc_nids[3] = {
+static const hda_nid_t vt1709_adc_nids[3] = {
/* ADC1-2 */
0x14, 0x15, 0x16
};
-static hda_nid_t vt1708B_adc_nids[2] = {
+static const hda_nid_t vt1708B_adc_nids[2] = {
/* ADC1-2 */
0x13, 0x14
};
-static hda_nid_t vt1708S_adc_nids[2] = {
+static const hda_nid_t vt1708S_adc_nids[2] = {
/* ADC1-2 */
0x13, 0x14
};
-static hda_nid_t vt1702_adc_nids[3] = {
+static const hda_nid_t vt1702_adc_nids[3] = {
/* ADC1-2 */
0x12, 0x20, 0x1F
};
-static hda_nid_t vt1718S_adc_nids[2] = {
+static const hda_nid_t vt1718S_adc_nids[2] = {
/* ADC1-2 */
0x10, 0x11
};
-static hda_nid_t vt1716S_adc_nids[2] = {
+static const hda_nid_t vt1716S_adc_nids[2] = {
/* ADC1-2 */
0x13, 0x14
};
-static hda_nid_t vt2002P_adc_nids[2] = {
+static const hda_nid_t vt2002P_adc_nids[2] = {
/* ADC1-2 */
0x10, 0x11
};
-static hda_nid_t vt1812_adc_nids[2] = {
+static const hda_nid_t vt1812_adc_nids[2] = {
/* ADC1-2 */
0x10, 0x11
};
@@ -471,7 +487,7 @@ static int __via_add_control(struct via_spec *spec, int type, const char *name,
__via_add_control(spec, type, name, 0, val)
static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
- struct snd_kcontrol_new *tmpl)
+ const struct snd_kcontrol_new *tmpl)
{
struct snd_kcontrol_new *knew;
@@ -602,482 +618,6 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
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 +660,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
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;
}
@@ -1168,6 +708,9 @@ static hda_nid_t side_mute_channel(struct via_spec *spec)
case VT1709_10CH: return 0x29;
case VT1708B_8CH: /* fall thru */
case VT1708S: return 0x27;
+ case VT2002P: return 0x19;
+ case VT1802: return 0x15;
+ case VT1812: return 0x15;
default: return 0;
}
}
@@ -1176,13 +719,22 @@ static int update_side_mute_status(struct hda_codec *codec)
{
/* mute side channel */
struct via_spec *spec = codec->spec;
- unsigned int parm = spec->hp_independent_mode
- ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
+ unsigned int parm;
hda_nid_t sw3 = side_mute_channel(spec);
- if (sw3)
- snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- parm);
+ if (sw3) {
+ if (VT2002P_COMPATIBLE(spec))
+ parm = spec->hp_independent_mode ?
+ AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1);
+ else
+ parm = spec->hp_independent_mode ?
+ AMP_OUT_MUTE : AMP_OUT_UNMUTE;
+ snd_hda_codec_write(codec, sw3, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, parm);
+ if (spec->codec_type == VT1812)
+ snd_hda_codec_write(codec, 0x1d, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, parm);
+ }
return 0;
}
@@ -1217,19 +769,18 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
|| spec->codec_type == VT1702
|| spec->codec_type == VT1718S
|| spec->codec_type == VT1716S
- || spec->codec_type == VT2002P
- || spec->codec_type == VT1812) {
+ || VT2002P_COMPATIBLE(spec)) {
activate_ctl(codec, "Headphone Playback Volume",
spec->hp_independent_mode);
activate_ctl(codec, "Headphone Playback Switch",
spec->hp_independent_mode);
}
/* update jack power state */
- set_jack_power_state(codec);
+ set_widgets_power_state(codec);
return 0;
}
-static struct snd_kcontrol_new via_hp_mixer[2] = {
+static const struct snd_kcontrol_new via_hp_mixer[2] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Independent HP",
@@ -1256,6 +807,7 @@ static int via_hp_build(struct hda_codec *codec)
nid = 0x34;
break;
case VT2002P:
+ case VT1802:
nid = 0x35;
break;
case VT1812:
@@ -1447,11 +999,11 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
}
}
spec->smart51_enabled = *ucontrol->value.integer.value;
- set_jack_power_state(codec);
+ set_widgets_power_state(codec);
return 1;
}
-static struct snd_kcontrol_new via_smart51_mixer[2] = {
+static const struct snd_kcontrol_new via_smart51_mixer[2] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Smart 5.1",
@@ -1473,6 +1025,11 @@ static int via_smart51_build(struct via_spec *spec)
hda_nid_t nid;
int i;
+ if (!cfg)
+ return 0;
+ if (cfg->line_outs > 2)
+ return 0;
+
knew = via_clone_control(spec, &via_smart51_mixer[0]);
if (knew == NULL)
return -ENOMEM;
@@ -1492,7 +1049,7 @@ static int via_smart51_build(struct via_spec *spec)
}
/* capture mixer elements */
-static struct snd_kcontrol_new vt1708_capture_mixer[] = {
+static const struct snd_kcontrol_new vt1708_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
@@ -1543,6 +1100,7 @@ static int is_aa_path_mute(struct hda_codec *codec)
break;
case VT2002P:
case VT1812:
+ case VT1802:
nid_mixer = 0x21;
start_idx = 0;
end_idx = 2;
@@ -1607,6 +1165,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
break;
case VT2002P:
case VT1812:
+ case VT1802:
verb = 0xf93;
parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
break;
@@ -1620,7 +1179,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
/*
* generic initialization of ADC, input mixers and output mixers
*/
-static struct hda_verb vt1708_volume_init_verbs[] = {
+static const struct hda_verb vt1708_volume_init_verbs[] = {
/*
* Unmute ADC0-1 and set the default input to mic-in
*/
@@ -1650,6 +1209,8 @@ static struct hda_verb vt1708_volume_init_verbs[] = {
{0x20, AC_VERB_SET_CONNECT_SEL, 0},
/* PW9 Output enable */
{0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+ /* power down jack detect function */
+ {0x1, 0xf81, 0x1},
{ }
};
@@ -1672,7 +1233,7 @@ static void playback_multi_pcm_prep_0(struct hda_codec *codec,
{
struct via_spec *spec = codec->spec;
struct hda_multi_out *mout = &spec->multiout;
- hda_nid_t *nids = mout->dac_nids;
+ const hda_nid_t *nids = mout->dac_nids;
int chs = substream->runtime->channels;
int i;
@@ -1741,7 +1302,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
{
struct via_spec *spec = codec->spec;
struct hda_multi_out *mout = &spec->multiout;
- hda_nid_t *nids = mout->dac_nids;
+ const hda_nid_t *nids = mout->dac_nids;
if (substream->number == 0)
playback_multi_pcm_prep_0(codec, stream_tag, format,
@@ -1762,7 +1323,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
{
struct via_spec *spec = codec->spec;
struct hda_multi_out *mout = &spec->multiout;
- hda_nid_t *nids = mout->dac_nids;
+ const hda_nid_t *nids = mout->dac_nids;
int i;
if (substream->number == 0) {
@@ -1860,7 +1421,7 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
return 0;
}
-static struct hda_pcm_stream vt1708_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1708_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 8,
@@ -1872,7 +1433,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
+static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 8,
@@ -1889,7 +1450,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
},
};
-static struct hda_pcm_stream vt1708_pcm_analog_capture = {
+static const struct hda_pcm_stream vt1708_pcm_analog_capture = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -1900,7 +1461,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt1708_pcm_digital_playback = {
+static const struct hda_pcm_stream vt1708_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -1913,7 +1474,7 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
},
};
-static struct hda_pcm_stream vt1708_pcm_digital_capture = {
+static const struct hda_pcm_stream vt1708_pcm_digital_capture = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -1923,7 +1484,7 @@ static int via_build_controls(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
struct snd_kcontrol *kctl;
- struct snd_kcontrol_new *knew;
+ const struct snd_kcontrol_new *knew;
int err, i;
for (i = 0; i < spec->num_mixers; i++) {
@@ -1971,7 +1532,7 @@ static int via_build_controls(struct hda_codec *codec)
}
/* 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 */
@@ -2135,7 +1696,7 @@ static void via_speaker_automute(struct hda_codec *codec)
unsigned int hp_present;
struct via_spec *spec = codec->spec;
- if (spec->codec_type != VT2002P && spec->codec_type != VT1812)
+ if (!VT2002P_COMPATIBLE(spec))
return;
hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
@@ -2194,17 +1755,21 @@ static void via_unsol_event(struct hda_codec *codec,
unsigned int res)
{
res >>= 26;
- if (res & VIA_HP_EVENT)
+
+ if (res & VIA_JACK_EVENT)
+ set_widgets_power_state(codec);
+
+ res &= ~VIA_JACK_EVENT;
+
+ if (res == VIA_HP_EVENT)
via_hp_automute(codec);
- if (res & VIA_GPIO_EVENT)
+ else if (res == VIA_GPIO_EVENT)
via_gpio_control(codec);
- if (res & VIA_JACK_EVENT)
- set_jack_power_state(codec);
- if (res & VIA_MONO_EVENT)
+ else if (res == VIA_MONO_EVENT)
via_mono_automute(codec);
- if (res & VIA_SPEAKER_EVENT)
+ else if (res == VIA_SPEAKER_EVENT)
via_speaker_automute(codec);
- if (res & VIA_BIND_HP_EVENT)
+ else if (res == VIA_BIND_HP_EVENT)
via_hp_bind_automute(codec);
}
@@ -2254,7 +1819,7 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
/*
*/
-static struct hda_codec_ops via_patch_ops = {
+static const struct hda_codec_ops via_patch_ops = {
.build_controls = via_build_controls,
.build_pcms = via_build_pcms,
.init = via_init,
@@ -2284,16 +1849,16 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
/* config dac list */
switch (i) {
case AUTO_SEQ_FRONT:
- spec->multiout.dac_nids[i] = 0x10;
+ spec->private_dac_nids[i] = 0x10;
break;
case AUTO_SEQ_CENLFE:
- spec->multiout.dac_nids[i] = 0x12;
+ spec->private_dac_nids[i] = 0x12;
break;
case AUTO_SEQ_SURROUND:
- spec->multiout.dac_nids[i] = 0x11;
+ spec->private_dac_nids[i] = 0x11;
break;
case AUTO_SEQ_SIDE:
- spec->multiout.dac_nids[i] = 0x13;
+ spec->private_dac_nids[i] = 0x13;
break;
}
}
@@ -2437,7 +2002,8 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg,
hda_nid_t cap_nid,
- hda_nid_t pin_idxs[], int num_idxs)
+ const hda_nid_t pin_idxs[],
+ int num_idxs)
{
struct via_spec *spec = codec->spec;
struct hda_input_mux *imux = &spec->private_imux[0];
@@ -2483,13 +2049,13 @@ static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
+ static const hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs,
ARRAY_SIZE(pin_idxs));
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt1708_loopbacks[] = {
+static const struct hda_amp_list vt1708_loopbacks[] = {
{ 0x17, HDA_INPUT, 1 },
{ 0x17, HDA_INPUT, 2 },
{ 0x17, HDA_INPUT, 3 },
@@ -2548,7 +2114,7 @@ static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
return change;
}
-static struct snd_kcontrol_new vt1708_jack_detectect[] = {
+static const struct snd_kcontrol_new vt1708_jack_detectect[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Jack Detect",
@@ -2623,7 +2189,8 @@ static int via_auto_init(struct hda_codec *codec)
via_auto_init_multi_out(codec);
via_auto_init_hp_out(codec);
via_auto_init_analog_input(codec);
- if (spec->codec_type == VT2002P || spec->codec_type == VT1812) {
+
+ if (VT2002P_COMPATIBLE(spec)) {
via_hp_bind_automute(codec);
} else {
via_hp_automute(codec);
@@ -2727,7 +2294,7 @@ static int patch_vt1708(struct hda_codec *codec)
}
/* capture mixer elements */
-static struct snd_kcontrol_new vt1709_capture_mixer[] = {
+static const struct snd_kcontrol_new vt1709_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
@@ -2749,7 +2316,7 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = {
{ } /* end */
};
-static struct hda_verb vt1709_uniwill_init_verbs[] = {
+static const struct hda_verb vt1709_uniwill_init_verbs[] = {
{0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
{ }
@@ -2758,7 +2325,7 @@ static struct hda_verb vt1709_uniwill_init_verbs[] = {
/*
* generic initialization of ADC, input mixers and output mixers
*/
-static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
+static const struct hda_verb vt1709_10ch_volume_init_verbs[] = {
/*
* Unmute ADC0-2 and set the default input to mic-in
*/
@@ -2798,7 +2365,7 @@ static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
{ }
};
-static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 10,
@@ -2810,7 +2377,7 @@ static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 6,
@@ -2822,7 +2389,7 @@ static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1709_pcm_analog_capture = {
+static const struct hda_pcm_stream vt1709_pcm_analog_capture = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -2833,7 +2400,7 @@ static struct hda_pcm_stream vt1709_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt1709_pcm_digital_playback = {
+static const struct hda_pcm_stream vt1709_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -2844,7 +2411,7 @@ static struct hda_pcm_stream vt1709_pcm_digital_playback = {
},
};
-static struct hda_pcm_stream vt1709_pcm_digital_capture = {
+static const struct hda_pcm_stream vt1709_pcm_digital_capture = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -2871,26 +2438,26 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
switch (i) {
case AUTO_SEQ_FRONT:
/* AOW0 */
- spec->multiout.dac_nids[i] = 0x10;
+ spec->private_dac_nids[i] = 0x10;
break;
case AUTO_SEQ_CENLFE:
/* AOW2 */
- spec->multiout.dac_nids[i] = 0x12;
+ spec->private_dac_nids[i] = 0x12;
break;
case AUTO_SEQ_SURROUND:
/* AOW3 */
- spec->multiout.dac_nids[i] = 0x11;
+ spec->private_dac_nids[i] = 0x11;
break;
case AUTO_SEQ_SIDE:
/* AOW1 */
- spec->multiout.dac_nids[i] = 0x27;
+ spec->private_dac_nids[i] = 0x27;
break;
default:
break;
}
}
}
- spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
+ spec->private_dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
} else if (cfg->line_outs == 3) { /* 6 channels */
for (i = 0; i < cfg->line_outs; i++) {
@@ -2900,15 +2467,15 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
switch (i) {
case AUTO_SEQ_FRONT:
/* AOW0 */
- spec->multiout.dac_nids[i] = 0x10;
+ spec->private_dac_nids[i] = 0x10;
break;
case AUTO_SEQ_CENLFE:
/* AOW2 */
- spec->multiout.dac_nids[i] = 0x12;
+ spec->private_dac_nids[i] = 0x12;
break;
case AUTO_SEQ_SURROUND:
/* AOW1 */
- spec->multiout.dac_nids[i] = 0x11;
+ spec->private_dac_nids[i] = 0x11;
break;
default:
break;
@@ -3056,7 +2623,7 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
+ static const hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
ARRAY_SIZE(pin_idxs));
}
@@ -3106,7 +2673,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt1709_loopbacks[] = {
+static const struct hda_amp_list vt1709_loopbacks[] = {
{ 0x18, HDA_INPUT, 1 },
{ 0x18, HDA_INPUT, 2 },
{ 0x18, HDA_INPUT, 3 },
@@ -3167,7 +2734,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
/*
* generic initialization of ADC, input mixers and output mixers
*/
-static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
+static const struct hda_verb vt1709_6ch_volume_init_verbs[] = {
/*
* Unmute ADC0-2 and set the default input to mic-in
*/
@@ -3257,7 +2824,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
}
/* capture mixer elements */
-static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
+static const struct snd_kcontrol_new vt1708B_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -3279,7 +2846,7 @@ static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
/*
* generic initialization of ADC, input mixers and output mixers
*/
-static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
+static const struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
/*
* Unmute ADC0-1 and set the default input to mic-in
*/
@@ -3314,7 +2881,7 @@ static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
{ }
};
-static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
+static const struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
/*
* Unmute ADC0-1 and set the default input to mic-in
*/
@@ -3349,7 +2916,7 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
{ }
};
-static struct hda_verb vt1708B_uniwill_init_verbs[] = {
+static const struct hda_verb vt1708B_uniwill_init_verbs[] = {
{0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -3373,7 +2940,7 @@ static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
return 0;
}
-static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 8,
@@ -3386,7 +2953,7 @@ static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 4,
@@ -3398,7 +2965,7 @@ static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
+static const struct hda_pcm_stream vt1708B_pcm_analog_capture = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -3411,7 +2978,7 @@ static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
+static const struct hda_pcm_stream vt1708B_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -3424,7 +2991,7 @@ static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
},
};
-static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
+static const struct hda_pcm_stream vt1708B_pcm_digital_capture = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -3447,16 +3014,16 @@ static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
/* config dac list */
switch (i) {
case AUTO_SEQ_FRONT:
- spec->multiout.dac_nids[i] = 0x10;
+ spec->private_dac_nids[i] = 0x10;
break;
case AUTO_SEQ_CENLFE:
- spec->multiout.dac_nids[i] = 0x24;
+ spec->private_dac_nids[i] = 0x24;
break;
case AUTO_SEQ_SURROUND:
- spec->multiout.dac_nids[i] = 0x11;
+ spec->private_dac_nids[i] = 0x11;
break;
case AUTO_SEQ_SIDE:
- spec->multiout.dac_nids[i] = 0x25;
+ spec->private_dac_nids[i] = 0x25;
break;
}
}
@@ -3588,7 +3155,7 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
+ static const hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
ARRAY_SIZE(pin_idxs));
}
@@ -3638,7 +3205,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt1708B_loopbacks[] = {
+static const struct hda_amp_list vt1708B_loopbacks[] = {
{ 0x16, HDA_INPUT, 1 },
{ 0x16, HDA_INPUT, 2 },
{ 0x16, HDA_INPUT, 3 },
@@ -3646,6 +3213,87 @@ static struct hda_amp_list vt1708B_loopbacks[] = {
{ } /* 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) &&
+ (codec->vendor_id != 0x11064397))
+ 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);
+ } else if (codec->vendor_id == 0x11064397) {
+ /* PW7(23h), SW2(27h), AOW2(25h) */
+ parm = AC_PWRST_D3;
+ set_pin_power_state(codec, 0x23, &parm);
+ if (spec->smart51_enabled)
+ set_pin_power_state(codec, 0x1a, &parm);
+ snd_hda_codec_write(codec, 0x27, 0,
+ AC_VERB_SET_POWER_STATE, parm);
+ snd_hda_codec_write(codec, 0x25, 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 (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
+ snd_hda_codec_write(codec, 0x25, 0,
+ AC_VERB_SET_POWER_STATE, parm);
+}
+
static int patch_vt1708S(struct hda_codec *codec);
static int patch_vt1708B_8ch(struct hda_codec *codec)
{
@@ -3696,6 +3344,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
spec->loopback.amplist = vt1708B_loopbacks;
#endif
+ spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
+
return 0;
}
@@ -3746,13 +3396,15 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
spec->loopback.amplist = vt1708B_loopbacks;
#endif
+ spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
+
return 0;
}
/* Patch for VT1708S */
/* capture mixer elements */
-static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
+static const struct snd_kcontrol_new vt1708S_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -3775,7 +3427,7 @@ static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
{ } /* end */
};
-static struct hda_verb vt1708S_volume_init_verbs[] = {
+static const struct hda_verb vt1708S_volume_init_verbs[] = {
/* Unmute ADC0-1 and set the default input to mic-in */
{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -3801,7 +3453,7 @@ static struct hda_verb vt1708S_volume_init_verbs[] = {
{ }
};
-static struct hda_verb vt1708S_uniwill_init_verbs[] = {
+static const struct hda_verb vt1708S_uniwill_init_verbs[] = {
{0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -3814,7 +3466,19 @@ static struct hda_verb vt1708S_uniwill_init_verbs[] = {
{ }
};
-static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
+static const struct hda_verb vt1705_uniwill_init_verbs[] = {
+ {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
+ {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ { }
+};
+
+static const struct hda_pcm_stream vt1708S_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 8,
@@ -3827,7 +3491,20 @@ static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
+static const struct hda_pcm_stream vt1705_pcm_analog_playback = {
+ .substreams = 2,
+ .channels_min = 2,
+ .channels_max = 6,
+ .nid = 0x10, /* NID to query formats and rates */
+ .ops = {
+ .open = via_playback_pcm_open,
+ .prepare = via_playback_multi_pcm_prepare,
+ .cleanup = via_playback_multi_pcm_cleanup,
+ .close = via_pcm_open_close
+ },
+};
+
+static const struct hda_pcm_stream vt1708S_pcm_analog_capture = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -3840,7 +3517,7 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
+static const struct hda_pcm_stream vt1708S_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -3870,16 +3547,19 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
/* config dac list */
switch (i) {
case AUTO_SEQ_FRONT:
- spec->multiout.dac_nids[i] = 0x10;
+ spec->private_dac_nids[i] = 0x10;
break;
case AUTO_SEQ_CENLFE:
- spec->multiout.dac_nids[i] = 0x24;
+ if (spec->codec->vendor_id == 0x11064397)
+ spec->private_dac_nids[i] = 0x25;
+ else
+ spec->private_dac_nids[i] = 0x24;
break;
case AUTO_SEQ_SURROUND:
- spec->multiout.dac_nids[i] = 0x11;
+ spec->private_dac_nids[i] = 0x11;
break;
case AUTO_SEQ_SIDE:
- spec->multiout.dac_nids[i] = 0x25;
+ spec->private_dac_nids[i] = 0x25;
break;
}
}
@@ -3888,23 +3568,29 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
/* for Smart 5.1, line/mic inputs double as output pins */
if (cfg->line_outs == 1) {
spec->multiout.num_dacs = 3;
- spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
- spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
+ spec->private_dac_nids[AUTO_SEQ_SURROUND] = 0x11;
+ if (spec->codec->vendor_id == 0x11064397)
+ spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x25;
+ else
+ spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x24;
}
return 0;
}
/* add playback controls from the parsed DAC table */
-static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
+static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
+ struct via_spec *spec = codec->spec;
char name[32];
static const char * const chname[4] = {
"Front", "Surround", "C/LFE", "Side"
};
- hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
- hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
+ hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25},
+ {0x10, 0x11, 0x25, 0} };
+ hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27},
+ {0x1C, 0x18, 0x27, 0} };
hda_nid_t nid, nid_vol, nid_mute;
int i, err;
@@ -3915,8 +3601,15 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
if (!nid && i > AUTO_SEQ_CENLFE)
continue;
- nid_vol = nid_vols[i];
- nid_mute = nid_mutes[i];
+ if (codec->vendor_id == 0x11064397) {
+ nid_vol = nid_vols[1][i];
+ nid_mute = nid_mutes[1][i];
+ } else {
+ nid_vol = nid_vols[0][i];
+ nid_mute = nid_mutes[0][i];
+ }
+ if (!nid_vol && !nid_mute)
+ continue;
if (i == AUTO_SEQ_CENLFE) {
/* Center/LFE */
@@ -4026,7 +3719,7 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
+ static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
ARRAY_SIZE(pin_idxs));
}
@@ -4070,7 +3763,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
return 0; /* can't find valid BIOS pin config */
- err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg);
if (err < 0)
return err;
err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
@@ -4097,7 +3790,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt1708S_loopbacks[] = {
+static const struct hda_amp_list vt1708S_loopbacks[] = {
{ 0x16, HDA_INPUT, 1 },
{ 0x16, HDA_INPUT, 2 },
{ 0x16, HDA_INPUT, 3 },
@@ -4137,17 +3830,29 @@ static int patch_vt1708S(struct hda_codec *codec)
}
spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
- spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
+ if (codec->vendor_id == 0x11064397)
+ spec->init_verbs[spec->num_iverbs++] =
+ vt1705_uniwill_init_verbs;
+ else
+ spec->init_verbs[spec->num_iverbs++] =
+ vt1708S_uniwill_init_verbs;
if (codec->vendor_id == 0x11060440)
spec->stream_name_analog = "VT1818S Analog";
+ else if (codec->vendor_id == 0x11064397)
+ spec->stream_name_analog = "VT1705 Analog";
else
spec->stream_name_analog = "VT1708S Analog";
- spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
+ if (codec->vendor_id == 0x11064397)
+ spec->stream_analog_playback = &vt1705_pcm_analog_playback;
+ else
+ spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
if (codec->vendor_id == 0x11060440)
spec->stream_name_digital = "VT1818S Digital";
+ else if (codec->vendor_id == 0x11064397)
+ spec->stream_name_digital = "VT1705 Digital";
else
spec->stream_name_digital = "VT1708S Digital";
spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
@@ -4185,13 +3890,22 @@ static int patch_vt1708S(struct hda_codec *codec)
spec->stream_name_analog = "VT1818S Analog";
spec->stream_name_digital = "VT1818S Digital";
}
+ /* correct names for VT1705 */
+ if (codec->vendor_id == 0x11064397) {
+ kfree(codec->chip_name);
+ codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
+ snprintf(codec->bus->card->mixername,
+ sizeof(codec->bus->card->mixername),
+ "%s %s", codec->vendor_name, codec->chip_name);
+ }
+ spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
return 0;
}
/* Patch for VT1702 */
/* capture mixer elements */
-static struct snd_kcontrol_new vt1702_capture_mixer[] = {
+static const struct snd_kcontrol_new vt1702_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
@@ -4215,7 +3929,7 @@ static struct snd_kcontrol_new vt1702_capture_mixer[] = {
{ } /* end */
};
-static struct hda_verb vt1702_volume_init_verbs[] = {
+static const struct hda_verb vt1702_volume_init_verbs[] = {
/*
* Unmute ADC0-1 and set the default input to mic-in
*/
@@ -4246,7 +3960,7 @@ static struct hda_verb vt1702_volume_init_verbs[] = {
{ }
};
-static struct hda_verb vt1702_uniwill_init_verbs[] = {
+static const struct hda_verb vt1702_uniwill_init_verbs[] = {
{0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -4256,7 +3970,7 @@ static struct hda_verb vt1702_uniwill_init_verbs[] = {
{ }
};
-static struct hda_pcm_stream vt1702_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1702_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -4269,7 +3983,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1702_pcm_analog_capture = {
+static const struct hda_pcm_stream vt1702_pcm_analog_capture = {
.substreams = 3,
.channels_min = 2,
.channels_max = 2,
@@ -4282,7 +3996,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt1702_pcm_digital_playback = {
+static const struct hda_pcm_stream vt1702_pcm_digital_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -4304,7 +4018,7 @@ static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
if (cfg->line_out_pins[0]) {
/* config dac list */
- spec->multiout.dac_nids[0] = 0x10;
+ spec->private_dac_nids[0] = 0x10;
}
return 0;
@@ -4382,7 +4096,7 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
+ static const hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs,
ARRAY_SIZE(pin_idxs));
}
@@ -4433,7 +4147,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt1702_loopbacks[] = {
+static const struct hda_amp_list vt1702_loopbacks[] = {
{ 0x1A, HDA_INPUT, 1 },
{ 0x1A, HDA_INPUT, 2 },
{ 0x1A, HDA_INPUT, 3 },
@@ -4442,6 +4156,37 @@ static struct hda_amp_list vt1702_loopbacks[] = {
};
#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;
@@ -4488,13 +4233,14 @@ static int patch_vt1702(struct hda_codec *codec)
spec->loopback.amplist = vt1702_loopbacks;
#endif
+ spec->set_widgets_power_state = set_widgets_power_state_vt1702;
return 0;
}
/* Patch for VT1718S */
/* capture mixer elements */
-static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
+static const struct snd_kcontrol_new vt1718S_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -4516,14 +4262,15 @@ static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
{ } /* end */
};
-static struct hda_verb vt1718S_volume_init_verbs[] = {
+static const struct hda_verb vt1718S_volume_init_verbs[] = {
/*
* Unmute ADC0-1 and set the default input to mic-in
*/
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
+ /* Enable MW0 adjust Gain 5 */
+ {0x1, 0xfb2, 0x10},
/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
*/
@@ -4532,7 +4279,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = {
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
- {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
/* Setup default input of Front HP to MW9 */
{0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
@@ -4563,7 +4310,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = {
};
-static struct hda_verb vt1718S_uniwill_init_verbs[] = {
+static const struct hda_verb vt1718S_uniwill_init_verbs[] = {
{0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
{0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -4576,7 +4323,7 @@ static struct hda_verb vt1718S_uniwill_init_verbs[] = {
{ }
};
-static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 10,
@@ -4589,7 +4336,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
+static const struct hda_pcm_stream vt1718S_pcm_analog_capture = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -4602,7 +4349,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
+static const struct hda_pcm_stream vt1718S_pcm_digital_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -4615,7 +4362,7 @@ static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
},
};
-static struct hda_pcm_stream vt1718S_pcm_digital_capture = {
+static const struct hda_pcm_stream vt1718S_pcm_digital_capture = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -4638,16 +4385,16 @@ static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
/* config dac list */
switch (i) {
case AUTO_SEQ_FRONT:
- spec->multiout.dac_nids[i] = 0x8;
+ spec->private_dac_nids[i] = 0x8;
break;
case AUTO_SEQ_CENLFE:
- spec->multiout.dac_nids[i] = 0xa;
+ spec->private_dac_nids[i] = 0xa;
break;
case AUTO_SEQ_SURROUND:
- spec->multiout.dac_nids[i] = 0x9;
+ spec->private_dac_nids[i] = 0x9;
break;
case AUTO_SEQ_SIDE:
- spec->multiout.dac_nids[i] = 0xb;
+ spec->private_dac_nids[i] = 0xb;
break;
}
}
@@ -4769,7 +4516,7 @@ static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
+ static const hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
ARRAY_SIZE(pin_idxs));
}
@@ -4820,7 +4567,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt1718S_loopbacks[] = {
+static const struct hda_amp_list vt1718S_loopbacks[] = {
{ 0x21, HDA_INPUT, 1 },
{ 0x21, HDA_INPUT, 2 },
{ 0x21, HDA_INPUT, 3 },
@@ -4829,6 +4576,72 @@ static struct hda_amp_list vt1718S_loopbacks[] = {
};
#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;
@@ -4890,6 +4703,8 @@ static int patch_vt1718S(struct hda_codec *codec)
spec->loopback.amplist = vt1718S_loopbacks;
#endif
+ spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
+
return 0;
}
@@ -4929,13 +4744,12 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
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;
}
/* capture mixer elements */
-static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
+static const struct snd_kcontrol_new vt1716S_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
@@ -4954,7 +4768,7 @@ static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
{ } /* end */
};
-static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
+static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -4970,12 +4784,12 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
/* mono-out mixer elements */
-static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
+static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
{ } /* end */
};
-static struct hda_verb vt1716S_volume_init_verbs[] = {
+static const struct hda_verb vt1716S_volume_init_verbs[] = {
/*
* Unmute ADC0-1 and set the default input to mic-in
*/
@@ -5024,7 +4838,7 @@ static struct hda_verb vt1716S_volume_init_verbs[] = {
};
-static struct hda_verb vt1716S_uniwill_init_verbs[] = {
+static const struct hda_verb vt1716S_uniwill_init_verbs[] = {
{0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
@@ -5037,7 +4851,7 @@ static struct hda_verb vt1716S_uniwill_init_verbs[] = {
{ }
};
-static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1716S_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 6,
@@ -5050,7 +4864,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
+static const struct hda_pcm_stream vt1716S_pcm_analog_capture = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -5063,7 +4877,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt1716S_pcm_digital_playback = {
+static const struct hda_pcm_stream vt1716S_pcm_digital_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -5092,13 +4906,13 @@ static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
/* config dac list */
switch (i) {
case AUTO_SEQ_FRONT:
- spec->multiout.dac_nids[i] = 0x10;
+ spec->private_dac_nids[i] = 0x10;
break;
case AUTO_SEQ_CENLFE:
- spec->multiout.dac_nids[i] = 0x25;
+ spec->private_dac_nids[i] = 0x25;
break;
case AUTO_SEQ_SURROUND:
- spec->multiout.dac_nids[i] = 0x11;
+ spec->private_dac_nids[i] = 0x11;
break;
}
}
@@ -5233,7 +5047,7 @@ static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
+ static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
ARRAY_SIZE(pin_idxs));
}
@@ -5280,7 +5094,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt1716S_loopbacks[] = {
+static const struct hda_amp_list vt1716S_loopbacks[] = {
{ 0x16, HDA_INPUT, 1 },
{ 0x16, HDA_INPUT, 2 },
{ 0x16, HDA_INPUT, 3 },
@@ -5289,6 +5103,99 @@ static struct hda_amp_list vt1716S_loopbacks[] = {
};
#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;
@@ -5343,13 +5250,14 @@ static int patch_vt1716S(struct hda_codec *codec)
spec->loopback.amplist = vt1716S_loopbacks;
#endif
+ spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
return 0;
}
/* for vt2002P */
/* capture mixer elements */
-static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
+static const struct snd_kcontrol_new vt2002P_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -5372,7 +5280,11 @@ static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
{ } /* end */
};
-static struct hda_verb vt2002P_volume_init_verbs[] = {
+static const struct hda_verb vt2002P_volume_init_verbs[] = {
+ /* Class-D speaker related verbs */
+ {0x1, 0xfe0, 0x4},
+ {0x1, 0xfe9, 0x80},
+ {0x1, 0xfe2, 0x22},
/*
* Unmute ADC0-1 and set the default input to mic-in
*/
@@ -5423,9 +5335,60 @@ static struct hda_verb vt2002P_volume_init_verbs[] = {
{0x1, 0xfb8, 0x88},
{ }
};
+static const struct hda_verb vt1802_volume_init_verbs[] = {
+ /*
+ * Unmute ADC0-1 and set the default input to mic-in
+ */
+ {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ * mixer widget
+ */
+ /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+
+ /* MUX Indices: Mic = 0 */
+ {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
+ {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
+
+ /* PW9 Output enable */
+ {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
+
+ /* Enable Boost Volume backdoor */
+ {0x1, 0xfb9, 0x24},
+
+ /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+ /* set MUX0/1/4/8 = 0 (AOW0) */
+ {0x34, AC_VERB_SET_CONNECT_SEL, 0},
+ {0x35, AC_VERB_SET_CONNECT_SEL, 0},
+ {0x38, AC_VERB_SET_CONNECT_SEL, 0},
+ {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
+
+ /* set PW0 index=0 (MW0) */
+ {0x24, AC_VERB_SET_CONNECT_SEL, 0},
+
+ /* Enable AOW0 to MW9 */
+ {0x1, 0xfb8, 0x88},
+ { }
+};
-static struct hda_verb vt2002P_uniwill_init_verbs[] = {
+static const struct hda_verb vt2002P_uniwill_init_verbs[] = {
{0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
{0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
@@ -5435,8 +5398,18 @@ static struct hda_verb vt2002P_uniwill_init_verbs[] = {
{0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
{ }
};
+static const struct hda_verb vt1802_uniwill_init_verbs[] = {
+ {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
+ {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
+ {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
+ { }
+};
-static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
+static const struct hda_pcm_stream vt2002P_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -5449,7 +5422,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
+static const struct hda_pcm_stream vt2002P_pcm_analog_capture = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -5462,7 +5435,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt2002P_pcm_digital_playback = {
+static const struct hda_pcm_stream vt2002P_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -5482,7 +5455,7 @@ static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
spec->multiout.num_dacs = 1;
spec->multiout.dac_nids = spec->private_dac_nids;
if (cfg->line_out_pins[0])
- spec->multiout.dac_nids[0] = 0x8;
+ spec->private_dac_nids[0] = 0x8;
return 0;
}
@@ -5491,10 +5464,15 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
const struct auto_pin_cfg *cfg)
{
int err;
+ hda_nid_t sw_nid;
if (!cfg->line_out_pins[0])
return -1;
+ if (spec->codec_type == VT1802)
+ sw_nid = 0x28;
+ else
+ sw_nid = 0x26;
/* Line-Out: PortE */
err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
@@ -5504,7 +5482,7 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
return err;
err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
"Master Front Playback Switch",
- HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT));
+ HDA_COMPOSE_AMP_VAL(sw_nid, 3, 0, HDA_OUTPUT));
if (err < 0)
return err;
@@ -5544,7 +5522,7 @@ static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec,
{
struct via_spec *spec = codec->spec;
struct hda_input_mux *imux = &spec->private_imux[0];
- static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
+ static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
int err;
err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
@@ -5605,7 +5583,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt2002P_loopbacks[] = {
+static const struct hda_amp_list vt2002P_loopbacks[] = {
{ 0x21, HDA_INPUT, 0 },
{ 0x21, HDA_INPUT, 1 },
{ 0x21, HDA_INPUT, 2 },
@@ -5613,6 +5591,116 @@ static struct hda_amp_list vt2002P_loopbacks[] = {
};
#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);
+
+ if (spec->codec_type == VT1802) {
+ /* 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);
+ } else {
+ /* 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);
+ }
+
+ if (spec->codec_type == VT1802) {
+ /* 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);
+ } else {
+ /* 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;
+ if (spec->codec_type == VT1802)
+ snd_hda_codec_write(codec, 0x14, 0,
+ AC_VERB_SET_POWER_STATE, parm);
+ else
+ 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;
+ if (spec->codec_type == VT1802) {
+ /* PW15 (33h), MW8(1ch), MUX8(3ch) */
+ snd_hda_codec_write(codec, 0x33, 0,
+ AC_VERB_SET_POWER_STATE, parm);
+ snd_hda_codec_write(codec, 0x1c, 0,
+ AC_VERB_SET_POWER_STATE, parm);
+ snd_hda_codec_write(codec, 0x3c, 0,
+ AC_VERB_SET_POWER_STATE, parm);
+ } else {
+ /* 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)
@@ -5635,14 +5723,31 @@ static int patch_vt2002P(struct hda_codec *codec)
"from BIOS. Using genenic mode...\n");
}
- spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs;
- spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs;
+ if (spec->codec_type == VT1802)
+ spec->init_verbs[spec->num_iverbs++] =
+ vt1802_volume_init_verbs;
+ else
+ spec->init_verbs[spec->num_iverbs++] =
+ vt2002P_volume_init_verbs;
+
+ if (spec->codec_type == VT1802)
+ spec->init_verbs[spec->num_iverbs++] =
+ vt1802_uniwill_init_verbs;
+ else
+ spec->init_verbs[spec->num_iverbs++] =
+ vt2002P_uniwill_init_verbs;
- spec->stream_name_analog = "VT2002P Analog";
+ if (spec->codec_type == VT1802)
+ spec->stream_name_analog = "VT1802 Analog";
+ else
+ spec->stream_name_analog = "VT2002P Analog";
spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
- spec->stream_name_digital = "VT2002P Digital";
+ if (spec->codec_type == VT1802)
+ spec->stream_name_digital = "VT1802 Digital";
+ else
+ spec->stream_name_digital = "VT2002P Digital";
spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
if (!spec->adc_nids && spec->input_mux) {
@@ -5664,13 +5769,14 @@ static int patch_vt2002P(struct hda_codec *codec)
spec->loopback.amplist = vt2002P_loopbacks;
#endif
+ spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
return 0;
}
/* for vt1812 */
/* capture mixer elements */
-static struct snd_kcontrol_new vt1812_capture_mixer[] = {
+static const struct snd_kcontrol_new vt1812_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
@@ -5692,7 +5798,7 @@ static struct snd_kcontrol_new vt1812_capture_mixer[] = {
{ } /* end */
};
-static struct hda_verb vt1812_volume_init_verbs[] = {
+static const struct hda_verb vt1812_volume_init_verbs[] = {
/*
* Unmute ADC0-1 and set the default input to mic-in
*/
@@ -5745,7 +5851,7 @@ static struct hda_verb vt1812_volume_init_verbs[] = {
};
-static struct hda_verb vt1812_uniwill_init_verbs[] = {
+static const struct hda_verb vt1812_uniwill_init_verbs[] = {
{0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
{0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
@@ -5757,7 +5863,7 @@ static struct hda_verb vt1812_uniwill_init_verbs[] = {
{ }
};
-static struct hda_pcm_stream vt1812_pcm_analog_playback = {
+static const struct hda_pcm_stream vt1812_pcm_analog_playback = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -5770,7 +5876,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_playback = {
},
};
-static struct hda_pcm_stream vt1812_pcm_analog_capture = {
+static const struct hda_pcm_stream vt1812_pcm_analog_capture = {
.substreams = 2,
.channels_min = 2,
.channels_max = 2,
@@ -5783,7 +5889,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_capture = {
},
};
-static struct hda_pcm_stream vt1812_pcm_digital_playback = {
+static const struct hda_pcm_stream vt1812_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
@@ -5802,7 +5908,7 @@ static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
spec->multiout.num_dacs = 1;
spec->multiout.dac_nids = spec->private_dac_nids;
if (cfg->line_out_pins[0])
- spec->multiout.dac_nids[0] = 0x8;
+ spec->private_dac_nids[0] = 0x8;
return 0;
}
@@ -5865,7 +5971,7 @@ static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec,
{
struct via_spec *spec = codec->spec;
struct hda_input_mux *imux = &spec->private_imux[0];
- static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
+ static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
int err;
err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
@@ -5927,7 +6033,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
-static struct hda_amp_list vt1812_loopbacks[] = {
+static const struct hda_amp_list vt1812_loopbacks[] = {
{ 0x21, HDA_INPUT, 0 },
{ 0x21, HDA_INPUT, 1 },
{ 0x21, HDA_INPUT, 2 },
@@ -5935,6 +6041,97 @@ static struct hda_amp_list vt1812_loopbacks[] = {
};
#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)
@@ -5988,13 +6185,14 @@ static int patch_vt1812(struct hda_codec *codec)
spec->loopback.amplist = vt1812_loopbacks;
#endif
+ spec->set_widgets_power_state = set_widgets_power_state_vt1812;
return 0;
}
/*
* patch entries
*/
-static struct hda_codec_preset snd_hda_preset_via[] = {
+static const struct hda_codec_preset snd_hda_preset_via[] = {
{ .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
{ .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
{ .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
@@ -6039,7 +6237,7 @@ static struct hda_codec_preset snd_hda_preset_via[] = {
.patch = patch_vt1708S},
{ .id = 0x11063397, .name = "VT1708S",
.patch = patch_vt1708S},
- { .id = 0x11064397, .name = "VT1708S",
+ { .id = 0x11064397, .name = "VT1705",
.patch = patch_vt1708S},
{ .id = 0x11065397, .name = "VT1708S",
.patch = patch_vt1708S},
@@ -6080,6 +6278,10 @@ static struct hda_codec_preset snd_hda_preset_via[] = {
{ .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
{ .id = 0x11060440, .name = "VT1818S",
.patch = patch_vt1708S},
+ { .id = 0x11060446, .name = "VT1802",
+ .patch = patch_vt2002P},
+ { .id = 0x11068446, .name = "VT1802",
+ .patch = patch_vt2002P},
{} /* terminator */
};