• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/sound/pci/hda/
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec
5 *
6 *  (C) 2006-2009 VIA Technology, Inc.
7 *  (C) 2006-2008 Takashi Iwai <tiwai@suse.de>
8 *
9 *  This driver is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  This driver is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22 */
23
24/* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
25/*									     */
26/* 2006-03-03  Lydia Wang  Create the basic patch to support VT1708 codec    */
27/* 2006-03-14  Lydia Wang  Modify hard code for some pin widget nid	     */
28/* 2006-08-02  Lydia Wang  Add support to VT1709 codec			     */
29/* 2006-09-08  Lydia Wang  Fix internal loopback recording source select bug */
30/* 2007-09-12  Lydia Wang  Add EAPD enable during driver initialization	     */
31/* 2007-09-17  Lydia Wang  Add VT1708B codec support			    */
32/* 2007-11-14  Lydia Wang  Add VT1708A codec HP and CD pin connect config    */
33/* 2008-02-03  Lydia Wang  Fix Rear channels and Back channels inverse issue */
34/* 2008-03-06  Lydia Wang  Add VT1702 codec and VT1708S codec support	     */
35/* 2008-04-09  Lydia Wang  Add mute front speaker when HP plugin	     */
36/* 2008-04-09  Lydia Wang  Add Independent HP feature			     */
37/* 2008-05-28  Lydia Wang  Add second S/PDIF Out support for VT1702	     */
38/* 2009-02-16  Logan Li	   Add support for VT1718S			     */
39/* 2009-03-13  Logan Li	   Add support for VT1716S			     */
40/* 2009-04-14  Lydai Wang  Add support for VT1828S and VT2020		     */
41/* 2009-07-08  Lydia Wang  Add support for VT2002P			     */
42/* 2009-07-21  Lydia Wang  Add support for VT1812			     */
43/* 2009-09-19  Lydia Wang  Add support for VT1818S			     */
44/*									     */
45/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
46
47
48#include <linux/init.h>
49#include <linux/delay.h>
50#include <linux/slab.h>
51#include <sound/core.h>
52#include <sound/asoundef.h>
53#include "hda_codec.h"
54#include "hda_local.h"
55
56#define NID_MAPPING		(-1)
57
58/* amp values */
59#define AMP_VAL_IDX_SHIFT	19
60#define AMP_VAL_IDX_MASK	(0x0f<<19)
61
62/* Pin Widget NID */
63#define VT1708_HP_NID		0x13
64#define VT1708_DIGOUT_NID	0x14
65#define VT1708_DIGIN_NID	0x16
66#define VT1708_DIGIN_PIN	0x26
67#define VT1708_HP_PIN_NID	0x20
68#define VT1708_CD_PIN_NID	0x24
69
70#define VT1709_HP_DAC_NID	0x28
71#define VT1709_DIGOUT_NID	0x13
72#define VT1709_DIGIN_NID	0x17
73#define VT1709_DIGIN_PIN	0x25
74
75#define VT1708B_HP_NID		0x25
76#define VT1708B_DIGOUT_NID	0x12
77#define VT1708B_DIGIN_NID	0x15
78#define VT1708B_DIGIN_PIN	0x21
79
80#define VT1708S_HP_NID		0x25
81#define VT1708S_DIGOUT_NID	0x12
82
83#define VT1702_HP_NID		0x17
84#define VT1702_DIGOUT_NID	0x11
85
86enum VIA_HDA_CODEC {
87	UNKNOWN = -1,
88	VT1708,
89	VT1709_10CH,
90	VT1709_6CH,
91	VT1708B_8CH,
92	VT1708B_4CH,
93	VT1708S,
94	VT1708BCE,
95	VT1702,
96	VT1718S,
97	VT1716S,
98	VT2002P,
99	VT1812,
100	CODEC_TYPES,
101};
102
103struct via_spec {
104	/* codec parameterization */
105	struct snd_kcontrol_new *mixers[6];
106	unsigned int num_mixers;
107
108	struct hda_verb *init_verbs[5];
109	unsigned int num_iverbs;
110
111	char *stream_name_analog;
112	struct hda_pcm_stream *stream_analog_playback;
113	struct hda_pcm_stream *stream_analog_capture;
114
115	char *stream_name_digital;
116	struct hda_pcm_stream *stream_digital_playback;
117	struct hda_pcm_stream *stream_digital_capture;
118
119	/* playback */
120	struct hda_multi_out multiout;
121	hda_nid_t slave_dig_outs[2];
122
123	/* capture */
124	unsigned int num_adc_nids;
125	hda_nid_t *adc_nids;
126	hda_nid_t mux_nids[3];
127	hda_nid_t dig_in_nid;
128	hda_nid_t dig_in_pin;
129
130	/* capture source */
131	const struct hda_input_mux *input_mux;
132	unsigned int cur_mux[3];
133
134	/* PCM information */
135	struct hda_pcm pcm_rec[3];
136
137	/* dynamic controls, init_verbs and input_mux */
138	struct auto_pin_cfg autocfg;
139	struct snd_array kctls;
140	struct hda_input_mux private_imux[2];
141	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
142
143	/* HP mode source */
144	const struct hda_input_mux *hp_mux;
145	unsigned int hp_independent_mode;
146	unsigned int hp_independent_mode_index;
147	unsigned int smart51_enabled;
148	unsigned int dmic_enabled;
149	enum VIA_HDA_CODEC codec_type;
150
151	/* work to check hp jack state */
152	struct hda_codec *codec;
153	struct delayed_work vt1708_hp_work;
154	int vt1708_jack_detectect;
155	int vt1708_hp_present;
156#ifdef CONFIG_SND_HDA_POWER_SAVE
157	struct hda_loopback_check loopback;
158#endif
159};
160
161static struct via_spec * via_new_spec(struct hda_codec *codec)
162{
163	struct via_spec *spec;
164
165	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
166	if (spec == NULL)
167		return NULL;
168
169	codec->spec = spec;
170	spec->codec = codec;
171	return spec;
172}
173
174static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
175{
176	u32 vendor_id = codec->vendor_id;
177	u16 ven_id = vendor_id >> 16;
178	u16 dev_id = vendor_id & 0xffff;
179	enum VIA_HDA_CODEC codec_type;
180
181	/* get codec type */
182	if (ven_id != 0x1106)
183		codec_type = UNKNOWN;
184	else if (dev_id >= 0x1708 && dev_id <= 0x170b)
185		codec_type = VT1708;
186	else if (dev_id >= 0xe710 && dev_id <= 0xe713)
187		codec_type = VT1709_10CH;
188	else if (dev_id >= 0xe714 && dev_id <= 0xe717)
189		codec_type = VT1709_6CH;
190	else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
191		codec_type = VT1708B_8CH;
192		if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
193			codec_type = VT1708BCE;
194	} else if (dev_id >= 0xe724 && dev_id <= 0xe727)
195		codec_type = VT1708B_4CH;
196	else if ((dev_id & 0xfff) == 0x397
197		 && (dev_id >> 12) < 8)
198		codec_type = VT1708S;
199	else if ((dev_id & 0xfff) == 0x398
200		 && (dev_id >> 12) < 8)
201		codec_type = VT1702;
202	else if ((dev_id & 0xfff) == 0x428
203		 && (dev_id >> 12) < 8)
204		codec_type = VT1718S;
205	else if (dev_id == 0x0433 || dev_id == 0xa721)
206		codec_type = VT1716S;
207	else if (dev_id == 0x0441 || dev_id == 0x4441)
208		codec_type = VT1718S;
209	else if (dev_id == 0x0438 || dev_id == 0x4438)
210		codec_type = VT2002P;
211	else if (dev_id == 0x0448)
212		codec_type = VT1812;
213	else if (dev_id == 0x0440)
214		codec_type = VT1708S;
215	else
216		codec_type = UNKNOWN;
217	return codec_type;
218};
219
220#define VIA_HP_EVENT		0x01
221#define VIA_GPIO_EVENT		0x02
222#define VIA_JACK_EVENT		0x04
223#define VIA_MONO_EVENT		0x08
224#define VIA_SPEAKER_EVENT	0x10
225#define VIA_BIND_HP_EVENT	0x20
226
227enum {
228	VIA_CTL_WIDGET_VOL,
229	VIA_CTL_WIDGET_MUTE,
230	VIA_CTL_WIDGET_ANALOG_MUTE,
231	VIA_CTL_WIDGET_BIND_PIN_MUTE,
232};
233
234enum {
235	AUTO_SEQ_FRONT = 0,
236	AUTO_SEQ_SURROUND,
237	AUTO_SEQ_CENLFE,
238	AUTO_SEQ_SIDE
239};
240
241static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
242static void set_jack_power_state(struct hda_codec *codec);
243static int is_aa_path_mute(struct hda_codec *codec);
244
245static void vt1708_start_hp_work(struct via_spec *spec)
246{
247	if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
248		return;
249	snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
250			    !spec->vt1708_jack_detectect);
251	if (!delayed_work_pending(&spec->vt1708_hp_work))
252		schedule_delayed_work(&spec->vt1708_hp_work,
253				      msecs_to_jiffies(100));
254}
255
256static void vt1708_stop_hp_work(struct via_spec *spec)
257{
258	if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
259		return;
260	if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
261	    && !is_aa_path_mute(spec->codec))
262		return;
263	snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
264			    !spec->vt1708_jack_detectect);
265	cancel_delayed_work(&spec->vt1708_hp_work);
266	flush_scheduled_work();
267}
268
269
270static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
271				   struct snd_ctl_elem_value *ucontrol)
272{
273	int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
274	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
275
276	set_jack_power_state(codec);
277	analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
278	if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
279		if (is_aa_path_mute(codec))
280			vt1708_start_hp_work(codec->spec);
281		else
282			vt1708_stop_hp_work(codec->spec);
283	}
284	return change;
285}
286
287/* modify .put = snd_hda_mixer_amp_switch_put */
288#define ANALOG_INPUT_MUTE						\
289	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
290			.name = NULL,					\
291			.index = 0,					\
292			.info = snd_hda_mixer_amp_switch_info,		\
293			.get = snd_hda_mixer_amp_switch_get,		\
294			.put = analog_input_switch_put,			\
295			.private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
296
297static void via_hp_bind_automute(struct hda_codec *codec);
298
299static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
300			       struct snd_ctl_elem_value *ucontrol)
301{
302	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
303	struct via_spec *spec = codec->spec;
304	int i;
305	int change = 0;
306
307	long *valp = ucontrol->value.integer.value;
308	int lmute, rmute;
309	if (strstr(kcontrol->id.name, "Switch") == NULL) {
310		snd_printd("Invalid control!\n");
311		return change;
312	}
313	change = snd_hda_mixer_amp_switch_put(kcontrol,
314					      ucontrol);
315	/* Get mute value */
316	lmute = *valp ? 0 : HDA_AMP_MUTE;
317	valp++;
318	rmute = *valp ? 0 : HDA_AMP_MUTE;
319
320	/* Set hp pins */
321	if (!spec->hp_independent_mode) {
322		for (i = 0; i < spec->autocfg.hp_outs; i++) {
323			snd_hda_codec_amp_update(
324				codec, spec->autocfg.hp_pins[i],
325				0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
326				lmute);
327			snd_hda_codec_amp_update(
328				codec, spec->autocfg.hp_pins[i],
329				1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
330				rmute);
331		}
332	}
333
334	if (!lmute && !rmute) {
335		/* Line Outs */
336		for (i = 0; i < spec->autocfg.line_outs; i++)
337			snd_hda_codec_amp_stereo(
338				codec, spec->autocfg.line_out_pins[i],
339				HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
340		/* Speakers */
341		for (i = 0; i < spec->autocfg.speaker_outs; i++)
342			snd_hda_codec_amp_stereo(
343				codec, spec->autocfg.speaker_pins[i],
344				HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
345		/* unmute */
346		via_hp_bind_automute(codec);
347
348	} else {
349		if (lmute) {
350			/* Mute all left channels */
351			for (i = 1; i < spec->autocfg.line_outs; i++)
352				snd_hda_codec_amp_update(
353					codec,
354					spec->autocfg.line_out_pins[i],
355					0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
356					lmute);
357			for (i = 0; i < spec->autocfg.speaker_outs; i++)
358				snd_hda_codec_amp_update(
359					codec,
360					spec->autocfg.speaker_pins[i],
361					0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
362					lmute);
363		}
364		if (rmute) {
365			/* mute all right channels */
366			for (i = 1; i < spec->autocfg.line_outs; i++)
367				snd_hda_codec_amp_update(
368					codec,
369					spec->autocfg.line_out_pins[i],
370					1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
371					rmute);
372			for (i = 0; i < spec->autocfg.speaker_outs; i++)
373				snd_hda_codec_amp_update(
374					codec,
375					spec->autocfg.speaker_pins[i],
376					1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
377					rmute);
378		}
379	}
380	return change;
381}
382
383#define BIND_PIN_MUTE							\
384	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		\
385			.name = NULL,					\
386			.index = 0,					\
387			.info = snd_hda_mixer_amp_switch_info,		\
388			.get = snd_hda_mixer_amp_switch_get,		\
389			.put = bind_pin_switch_put,			\
390			.private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
391
392static struct snd_kcontrol_new via_control_templates[] = {
393	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
394	HDA_CODEC_MUTE(NULL, 0, 0, 0),
395	ANALOG_INPUT_MUTE,
396	BIND_PIN_MUTE,
397};
398
399static hda_nid_t vt1708_adc_nids[2] = {
400	/* ADC1-2 */
401	0x15, 0x27
402};
403
404static hda_nid_t vt1709_adc_nids[3] = {
405	/* ADC1-2 */
406	0x14, 0x15, 0x16
407};
408
409static hda_nid_t vt1708B_adc_nids[2] = {
410	/* ADC1-2 */
411	0x13, 0x14
412};
413
414static hda_nid_t vt1708S_adc_nids[2] = {
415	/* ADC1-2 */
416	0x13, 0x14
417};
418
419static hda_nid_t vt1702_adc_nids[3] = {
420	/* ADC1-2 */
421	0x12, 0x20, 0x1F
422};
423
424static hda_nid_t vt1718S_adc_nids[2] = {
425	/* ADC1-2 */
426	0x10, 0x11
427};
428
429static hda_nid_t vt1716S_adc_nids[2] = {
430	/* ADC1-2 */
431	0x13, 0x14
432};
433
434static hda_nid_t vt2002P_adc_nids[2] = {
435	/* ADC1-2 */
436	0x10, 0x11
437};
438
439static hda_nid_t vt1812_adc_nids[2] = {
440	/* ADC1-2 */
441	0x10, 0x11
442};
443
444
445/* add dynamic controls */
446static int via_add_control(struct via_spec *spec, int type, const char *name,
447			   unsigned long val)
448{
449	struct snd_kcontrol_new *knew;
450
451	snd_array_init(&spec->kctls, sizeof(*knew), 32);
452	knew = snd_array_new(&spec->kctls);
453	if (!knew)
454		return -ENOMEM;
455	*knew = via_control_templates[type];
456	knew->name = kstrdup(name, GFP_KERNEL);
457	if (!knew->name)
458		return -ENOMEM;
459	if (get_amp_nid_(val))
460		knew->subdevice = HDA_SUBDEV_AMP_FLAG;
461	knew->private_value = val;
462	return 0;
463}
464
465static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
466						struct snd_kcontrol_new *tmpl)
467{
468	struct snd_kcontrol_new *knew;
469
470	snd_array_init(&spec->kctls, sizeof(*knew), 32);
471	knew = snd_array_new(&spec->kctls);
472	if (!knew)
473		return NULL;
474	*knew = *tmpl;
475	knew->name = kstrdup(tmpl->name, GFP_KERNEL);
476	if (!knew->name)
477		return NULL;
478	return knew;
479}
480
481static void via_free_kctls(struct hda_codec *codec)
482{
483	struct via_spec *spec = codec->spec;
484
485	if (spec->kctls.list) {
486		struct snd_kcontrol_new *kctl = spec->kctls.list;
487		int i;
488		for (i = 0; i < spec->kctls.used; i++)
489			kfree(kctl[i].name);
490	}
491	snd_array_free(&spec->kctls);
492}
493
494/* create input playback/capture controls for the given pin */
495static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
496				int idx, int mix_nid)
497{
498	char name[32];
499	int err;
500
501	sprintf(name, "%s Playback Volume", ctlname);
502	err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
503			      HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
504	if (err < 0)
505		return err;
506	sprintf(name, "%s Playback Switch", ctlname);
507	err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name,
508			      HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
509	if (err < 0)
510		return err;
511	return 0;
512}
513
514static void via_auto_set_output_and_unmute(struct hda_codec *codec,
515					   hda_nid_t nid, int pin_type,
516					   int dac_idx)
517{
518	/* set as output */
519	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
520			    pin_type);
521	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
522			    AMP_OUT_UNMUTE);
523	if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
524		snd_hda_codec_write(codec, nid, 0,
525				    AC_VERB_SET_EAPD_BTLENABLE, 0x02);
526}
527
528
529static void via_auto_init_multi_out(struct hda_codec *codec)
530{
531	struct via_spec *spec = codec->spec;
532	int i;
533
534	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
535		hda_nid_t nid = spec->autocfg.line_out_pins[i];
536		if (nid)
537			via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
538	}
539}
540
541static void via_auto_init_hp_out(struct hda_codec *codec)
542{
543	struct via_spec *spec = codec->spec;
544	hda_nid_t pin;
545	int i;
546
547	for (i = 0; i < spec->autocfg.hp_outs; i++) {
548		pin = spec->autocfg.hp_pins[i];
549		if (pin) /* connect to front */
550			via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
551	}
552}
553
554static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
555
556static void via_auto_init_analog_input(struct hda_codec *codec)
557{
558	struct via_spec *spec = codec->spec;
559	unsigned int ctl;
560	int i;
561
562	for (i = 0; i < AUTO_PIN_LAST; i++) {
563		hda_nid_t nid = spec->autocfg.input_pins[i];
564		if (!nid)
565			continue;
566
567		if (spec->smart51_enabled && is_smart51_pins(spec, nid))
568			ctl = PIN_OUT;
569		else if (i <= AUTO_PIN_FRONT_MIC)
570			ctl = PIN_VREF50;
571		else
572			ctl = PIN_IN;
573		snd_hda_codec_write(codec, nid, 0,
574				    AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
575	}
576}
577
578static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
579				unsigned int *affected_parm)
580{
581	unsigned parm;
582	unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
583	unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
584		>> AC_DEFCFG_MISC_SHIFT
585		& AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
586	unsigned present = snd_hda_jack_detect(codec, nid);
587	struct via_spec *spec = codec->spec;
588	if ((spec->smart51_enabled && is_smart51_pins(spec, nid))
589	    || ((no_presence || present)
590		&& get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
591		*affected_parm = AC_PWRST_D0; /* if it's connected */
592		parm = AC_PWRST_D0;
593	} else
594		parm = AC_PWRST_D3;
595
596	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
597}
598
599static void set_jack_power_state(struct hda_codec *codec)
600{
601	struct via_spec *spec = codec->spec;
602	int imux_is_smixer;
603	unsigned int parm;
604
605	if (spec->codec_type == VT1702) {
606		imux_is_smixer = snd_hda_codec_read(
607			codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
608		/* inputs */
609		/* PW 1/2/5 (14h/15h/18h) */
610		parm = AC_PWRST_D3;
611		set_pin_power_state(codec, 0x14, &parm);
612		set_pin_power_state(codec, 0x15, &parm);
613		set_pin_power_state(codec, 0x18, &parm);
614		if (imux_is_smixer)
615			parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
616		/* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
617		snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
618				    parm);
619		snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
620				    parm);
621		snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
622				    parm);
623		snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
624				    parm);
625
626		/* outputs */
627		/* PW 3/4 (16h/17h) */
628		parm = AC_PWRST_D3;
629		set_pin_power_state(codec, 0x16, &parm);
630		set_pin_power_state(codec, 0x17, &parm);
631		/* MW0 (1ah), AOW 0/1 (10h/1dh) */
632		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
633				    imux_is_smixer ? AC_PWRST_D0 : parm);
634		snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
635				    parm);
636		snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
637				    parm);
638	} else if (spec->codec_type == VT1708B_8CH
639		   || spec->codec_type == VT1708B_4CH
640		   || spec->codec_type == VT1708S) {
641		/* SW0 (17h) = stereo mixer */
642		int is_8ch = spec->codec_type != VT1708B_4CH;
643		imux_is_smixer = snd_hda_codec_read(
644			codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
645			== ((spec->codec_type == VT1708S)  ? 5 : 0);
646		/* inputs */
647		/* PW 1/2/5 (1ah/1bh/1eh) */
648		parm = AC_PWRST_D3;
649		set_pin_power_state(codec, 0x1a, &parm);
650		set_pin_power_state(codec, 0x1b, &parm);
651		set_pin_power_state(codec, 0x1e, &parm);
652		if (imux_is_smixer)
653			parm = AC_PWRST_D0;
654		/* SW0 (17h), AIW 0/1 (13h/14h) */
655		snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
656				    parm);
657		snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
658				    parm);
659		snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
660				    parm);
661
662		/* outputs */
663		/* PW0 (19h), SW1 (18h), AOW1 (11h) */
664		parm = AC_PWRST_D3;
665		set_pin_power_state(codec, 0x19, &parm);
666		if (spec->smart51_enabled)
667			parm = AC_PWRST_D0;
668		snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
669				    parm);
670		snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
671				    parm);
672
673		/* PW6 (22h), SW2 (26h), AOW2 (24h) */
674		if (is_8ch) {
675			parm = AC_PWRST_D3;
676			set_pin_power_state(codec, 0x22, &parm);
677			if (spec->smart51_enabled)
678				parm = AC_PWRST_D0;
679			snd_hda_codec_write(codec, 0x26, 0,
680					    AC_VERB_SET_POWER_STATE, parm);
681			snd_hda_codec_write(codec, 0x24, 0,
682					    AC_VERB_SET_POWER_STATE, parm);
683		}
684
685		/* PW 3/4/7 (1ch/1dh/23h) */
686		parm = AC_PWRST_D3;
687		/* force to D0 for internal Speaker */
688		set_pin_power_state(codec, 0x1c, &parm);
689		set_pin_power_state(codec, 0x1d, &parm);
690		if (is_8ch)
691			set_pin_power_state(codec, 0x23, &parm);
692		/* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
693		snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
694				    imux_is_smixer ? AC_PWRST_D0 : parm);
695		snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
696				    parm);
697		if (is_8ch) {
698			snd_hda_codec_write(codec, 0x25, 0,
699					    AC_VERB_SET_POWER_STATE, parm);
700			snd_hda_codec_write(codec, 0x27, 0,
701					    AC_VERB_SET_POWER_STATE, parm);
702		}
703	}  else if (spec->codec_type == VT1718S) {
704		/* MUX6 (1eh) = stereo mixer */
705		imux_is_smixer = snd_hda_codec_read(
706			codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
707		/* inputs */
708		/* PW 5/6/7 (29h/2ah/2bh) */
709		parm = AC_PWRST_D3;
710		set_pin_power_state(codec, 0x29, &parm);
711		set_pin_power_state(codec, 0x2a, &parm);
712		set_pin_power_state(codec, 0x2b, &parm);
713		if (imux_is_smixer)
714			parm = AC_PWRST_D0;
715		/* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
716		snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
717				    parm);
718		snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
719				    parm);
720		snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
721				    parm);
722		snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
723				    parm);
724
725		/* outputs */
726		/* PW3 (27h), MW2 (1ah), AOW3 (bh) */
727		parm = AC_PWRST_D3;
728		set_pin_power_state(codec, 0x27, &parm);
729		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
730				    parm);
731		snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
732				    parm);
733
734		/* PW2 (26h), AOW2 (ah) */
735		parm = AC_PWRST_D3;
736		set_pin_power_state(codec, 0x26, &parm);
737		snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
738				    parm);
739
740		/* PW0/1 (24h/25h) */
741		parm = AC_PWRST_D3;
742		set_pin_power_state(codec, 0x24, &parm);
743		set_pin_power_state(codec, 0x25, &parm);
744		if (!spec->hp_independent_mode) /* check for redirected HP */
745			set_pin_power_state(codec, 0x28, &parm);
746		snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
747				    parm);
748		snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
749				    parm);
750		/* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
751		snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
752				    imux_is_smixer ? AC_PWRST_D0 : parm);
753		if (spec->hp_independent_mode) {
754			/* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
755			parm = AC_PWRST_D3;
756			set_pin_power_state(codec, 0x28, &parm);
757			snd_hda_codec_write(codec, 0x1b, 0,
758					    AC_VERB_SET_POWER_STATE, parm);
759			snd_hda_codec_write(codec, 0x34, 0,
760					    AC_VERB_SET_POWER_STATE, parm);
761			snd_hda_codec_write(codec, 0xc, 0,
762					    AC_VERB_SET_POWER_STATE, parm);
763		}
764	} else if (spec->codec_type == VT1716S) {
765		unsigned int mono_out, present;
766		/* SW0 (17h) = stereo mixer */
767		imux_is_smixer = snd_hda_codec_read(
768			codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) ==  5;
769		/* inputs */
770		/* PW 1/2/5 (1ah/1bh/1eh) */
771		parm = AC_PWRST_D3;
772		set_pin_power_state(codec, 0x1a, &parm);
773		set_pin_power_state(codec, 0x1b, &parm);
774		set_pin_power_state(codec, 0x1e, &parm);
775		if (imux_is_smixer)
776			parm = AC_PWRST_D0;
777		/* SW0 (17h), AIW0(13h) */
778		snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
779				    parm);
780		snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
781				    parm);
782
783		parm = AC_PWRST_D3;
784		set_pin_power_state(codec, 0x1e, &parm);
785		/* PW11 (22h) */
786		if (spec->dmic_enabled)
787			set_pin_power_state(codec, 0x22, &parm);
788		else
789			snd_hda_codec_write(
790				codec, 0x22, 0,
791				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
792
793		/* SW2(26h), AIW1(14h) */
794		snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
795				    parm);
796		snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
797				    parm);
798
799		/* outputs */
800		/* PW0 (19h), SW1 (18h), AOW1 (11h) */
801		parm = AC_PWRST_D3;
802		set_pin_power_state(codec, 0x19, &parm);
803		/* Smart 5.1 PW2(1bh) */
804		if (spec->smart51_enabled)
805			set_pin_power_state(codec, 0x1b, &parm);
806		snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
807				    parm);
808		snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
809				    parm);
810
811		/* PW7 (23h), SW3 (27h), AOW3 (25h) */
812		parm = AC_PWRST_D3;
813		set_pin_power_state(codec, 0x23, &parm);
814		/* Smart 5.1 PW1(1ah) */
815		if (spec->smart51_enabled)
816			set_pin_power_state(codec, 0x1a, &parm);
817		snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
818				    parm);
819
820		/* Smart 5.1 PW5(1eh) */
821		if (spec->smart51_enabled)
822			set_pin_power_state(codec, 0x1e, &parm);
823		snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
824				    parm);
825
826		/* Mono out */
827		/* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
828		present = snd_hda_jack_detect(codec, 0x1c);
829		if (present)
830			mono_out = 0;
831		else {
832			present = snd_hda_jack_detect(codec, 0x1d);
833			if (!spec->hp_independent_mode && present)
834				mono_out = 0;
835			else
836				mono_out = 1;
837		}
838		parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
839		snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
840				    parm);
841		snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
842				    parm);
843		snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
844				    parm);
845
846		/* PW 3/4 (1ch/1dh) */
847		parm = AC_PWRST_D3;
848		set_pin_power_state(codec, 0x1c, &parm);
849		set_pin_power_state(codec, 0x1d, &parm);
850		/* HP Independent Mode, power on AOW3 */
851		if (spec->hp_independent_mode)
852			snd_hda_codec_write(codec, 0x25, 0,
853					    AC_VERB_SET_POWER_STATE, parm);
854
855		/* force to D0 for internal Speaker */
856		/* MW0 (16h), AOW0 (10h) */
857		snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
858				    imux_is_smixer ? AC_PWRST_D0 : parm);
859		snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
860				    mono_out ? AC_PWRST_D0 : parm);
861	} else if (spec->codec_type == VT2002P) {
862		unsigned int present;
863		/* MUX9 (1eh) = stereo mixer */
864		imux_is_smixer = snd_hda_codec_read(
865			codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
866		/* inputs */
867		/* PW 5/6/7 (29h/2ah/2bh) */
868		parm = AC_PWRST_D3;
869		set_pin_power_state(codec, 0x29, &parm);
870		set_pin_power_state(codec, 0x2a, &parm);
871		set_pin_power_state(codec, 0x2b, &parm);
872		if (imux_is_smixer)
873			parm = AC_PWRST_D0;
874		/* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
875		snd_hda_codec_write(codec, 0x1e, 0,
876				    AC_VERB_SET_POWER_STATE, parm);
877		snd_hda_codec_write(codec, 0x1f, 0,
878				    AC_VERB_SET_POWER_STATE, parm);
879		snd_hda_codec_write(codec, 0x10, 0,
880				    AC_VERB_SET_POWER_STATE, parm);
881		snd_hda_codec_write(codec, 0x11, 0,
882				    AC_VERB_SET_POWER_STATE, parm);
883
884		/* outputs */
885		/* AOW0 (8h)*/
886		snd_hda_codec_write(codec, 0x8, 0,
887				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
888
889		/* PW4 (26h), MW4 (1ch), MUX4(37h) */
890		parm = AC_PWRST_D3;
891		set_pin_power_state(codec, 0x26, &parm);
892		snd_hda_codec_write(codec, 0x1c, 0,
893				    AC_VERB_SET_POWER_STATE, parm);
894		snd_hda_codec_write(codec, 0x37,
895				    0, AC_VERB_SET_POWER_STATE, parm);
896
897		/* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
898		parm = AC_PWRST_D3;
899		set_pin_power_state(codec, 0x25, &parm);
900		snd_hda_codec_write(codec, 0x19, 0,
901				    AC_VERB_SET_POWER_STATE, parm);
902		snd_hda_codec_write(codec, 0x35, 0,
903				    AC_VERB_SET_POWER_STATE, parm);
904		if (spec->hp_independent_mode)	{
905			snd_hda_codec_write(codec, 0x9, 0,
906					    AC_VERB_SET_POWER_STATE, parm);
907		}
908
909		/* Class-D */
910		/* PW0 (24h), MW0(18h), MUX0(34h) */
911		present = snd_hda_jack_detect(codec, 0x25);
912		parm = AC_PWRST_D3;
913		set_pin_power_state(codec, 0x24, &parm);
914		if (present) {
915			snd_hda_codec_write(
916				codec, 0x18, 0,
917				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
918			snd_hda_codec_write(
919				codec, 0x34, 0,
920				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
921		} else {
922			snd_hda_codec_write(
923				codec, 0x18, 0,
924				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
925			snd_hda_codec_write(
926				codec, 0x34, 0,
927				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
928		}
929
930		/* Mono Out */
931		/* PW15 (31h), MW8(17h), MUX8(3bh) */
932		present = snd_hda_jack_detect(codec, 0x26);
933		parm = AC_PWRST_D3;
934		set_pin_power_state(codec, 0x31, &parm);
935		if (present) {
936			snd_hda_codec_write(
937				codec, 0x17, 0,
938				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
939			snd_hda_codec_write(
940				codec, 0x3b, 0,
941				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
942		} else {
943			snd_hda_codec_write(
944				codec, 0x17, 0,
945				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
946			snd_hda_codec_write(
947				codec, 0x3b, 0,
948				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
949		}
950
951		/* MW9 (21h) */
952		if (imux_is_smixer || !is_aa_path_mute(codec))
953			snd_hda_codec_write(
954				codec, 0x21, 0,
955				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
956		else
957			snd_hda_codec_write(
958				codec, 0x21, 0,
959				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
960	} else if (spec->codec_type == VT1812) {
961		unsigned int present;
962		/* MUX10 (1eh) = stereo mixer */
963		imux_is_smixer = snd_hda_codec_read(
964			codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
965		/* inputs */
966		/* PW 5/6/7 (29h/2ah/2bh) */
967		parm = AC_PWRST_D3;
968		set_pin_power_state(codec, 0x29, &parm);
969		set_pin_power_state(codec, 0x2a, &parm);
970		set_pin_power_state(codec, 0x2b, &parm);
971		if (imux_is_smixer)
972			parm = AC_PWRST_D0;
973		/* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
974		snd_hda_codec_write(codec, 0x1e, 0,
975				    AC_VERB_SET_POWER_STATE, parm);
976		snd_hda_codec_write(codec, 0x1f, 0,
977				    AC_VERB_SET_POWER_STATE, parm);
978		snd_hda_codec_write(codec, 0x10, 0,
979				    AC_VERB_SET_POWER_STATE, parm);
980		snd_hda_codec_write(codec, 0x11, 0,
981				    AC_VERB_SET_POWER_STATE, parm);
982
983		/* outputs */
984		/* AOW0 (8h)*/
985		snd_hda_codec_write(codec, 0x8, 0,
986				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
987
988		/* PW4 (28h), MW4 (18h), MUX4(38h) */
989		parm = AC_PWRST_D3;
990		set_pin_power_state(codec, 0x28, &parm);
991		snd_hda_codec_write(codec, 0x18, 0,
992				    AC_VERB_SET_POWER_STATE, parm);
993		snd_hda_codec_write(codec, 0x38, 0,
994				    AC_VERB_SET_POWER_STATE, parm);
995
996		/* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
997		parm = AC_PWRST_D3;
998		set_pin_power_state(codec, 0x25, &parm);
999		snd_hda_codec_write(codec, 0x15, 0,
1000				    AC_VERB_SET_POWER_STATE, parm);
1001		snd_hda_codec_write(codec, 0x35, 0,
1002				    AC_VERB_SET_POWER_STATE, parm);
1003		if (spec->hp_independent_mode)	{
1004			snd_hda_codec_write(codec, 0x9, 0,
1005					    AC_VERB_SET_POWER_STATE, parm);
1006		}
1007
1008		/* Internal Speaker */
1009		/* PW0 (24h), MW0(14h), MUX0(34h) */
1010		present = snd_hda_jack_detect(codec, 0x25);
1011		parm = AC_PWRST_D3;
1012		set_pin_power_state(codec, 0x24, &parm);
1013		if (present) {
1014			snd_hda_codec_write(codec, 0x14, 0,
1015					    AC_VERB_SET_POWER_STATE,
1016					    AC_PWRST_D3);
1017			snd_hda_codec_write(codec, 0x34, 0,
1018					    AC_VERB_SET_POWER_STATE,
1019					    AC_PWRST_D3);
1020		} else {
1021			snd_hda_codec_write(codec, 0x14, 0,
1022					    AC_VERB_SET_POWER_STATE,
1023					    AC_PWRST_D0);
1024			snd_hda_codec_write(codec, 0x34, 0,
1025					    AC_VERB_SET_POWER_STATE,
1026					    AC_PWRST_D0);
1027		}
1028		/* Mono Out */
1029		/* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1030		present = snd_hda_jack_detect(codec, 0x28);
1031		parm = AC_PWRST_D3;
1032		set_pin_power_state(codec, 0x31, &parm);
1033		if (present) {
1034			snd_hda_codec_write(codec, 0x1c, 0,
1035					    AC_VERB_SET_POWER_STATE,
1036					    AC_PWRST_D3);
1037			snd_hda_codec_write(codec, 0x3c, 0,
1038					    AC_VERB_SET_POWER_STATE,
1039					    AC_PWRST_D3);
1040			snd_hda_codec_write(codec, 0x3e, 0,
1041					    AC_VERB_SET_POWER_STATE,
1042					    AC_PWRST_D3);
1043		} else {
1044			snd_hda_codec_write(codec, 0x1c, 0,
1045					    AC_VERB_SET_POWER_STATE,
1046					    AC_PWRST_D0);
1047			snd_hda_codec_write(codec, 0x3c, 0,
1048					    AC_VERB_SET_POWER_STATE,
1049					    AC_PWRST_D0);
1050			snd_hda_codec_write(codec, 0x3e, 0,
1051					    AC_VERB_SET_POWER_STATE,
1052					    AC_PWRST_D0);
1053		}
1054
1055		/* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1056		parm = AC_PWRST_D3;
1057		set_pin_power_state(codec, 0x33, &parm);
1058		snd_hda_codec_write(codec, 0x1d, 0,
1059				    AC_VERB_SET_POWER_STATE, parm);
1060		snd_hda_codec_write(codec, 0x3d, 0,
1061				    AC_VERB_SET_POWER_STATE, parm);
1062
1063		/* MW9 (21h) */
1064		if (imux_is_smixer || !is_aa_path_mute(codec))
1065			snd_hda_codec_write(
1066				codec, 0x21, 0,
1067				AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1068		else
1069			snd_hda_codec_write(
1070				codec, 0x21, 0,
1071				AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1072	}
1073}
1074
1075/*
1076 * input MUX handling
1077 */
1078static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
1079			     struct snd_ctl_elem_info *uinfo)
1080{
1081	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1082	struct via_spec *spec = codec->spec;
1083	return snd_hda_input_mux_info(spec->input_mux, uinfo);
1084}
1085
1086static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
1087			    struct snd_ctl_elem_value *ucontrol)
1088{
1089	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1090	struct via_spec *spec = codec->spec;
1091	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1092
1093	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
1094	return 0;
1095}
1096
1097static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1098			    struct snd_ctl_elem_value *ucontrol)
1099{
1100	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1101	struct via_spec *spec = codec->spec;
1102	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1103
1104	if (!spec->mux_nids[adc_idx])
1105		return -EINVAL;
1106	/* switch to D0 beofre change index */
1107	if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
1108			       AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
1109		snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
1110				    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1111	/* update jack power state */
1112	set_jack_power_state(codec);
1113
1114	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
1115				     spec->mux_nids[adc_idx],
1116				     &spec->cur_mux[adc_idx]);
1117}
1118
1119static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
1120				   struct snd_ctl_elem_info *uinfo)
1121{
1122	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1123	struct via_spec *spec = codec->spec;
1124	return snd_hda_input_mux_info(spec->hp_mux, uinfo);
1125}
1126
1127static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1128				  struct snd_ctl_elem_value *ucontrol)
1129{
1130	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1131	hda_nid_t nid = kcontrol->private_value;
1132	unsigned int pinsel;
1133
1134	/* use !! to translate conn sel 2 for VT1718S */
1135	pinsel = !!snd_hda_codec_read(codec, nid, 0,
1136				      AC_VERB_GET_CONNECT_SEL,
1137				      0x00);
1138	ucontrol->value.enumerated.item[0] = pinsel;
1139
1140	return 0;
1141}
1142
1143static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1144{
1145	struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
1146	if (ctl) {
1147		ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1148		ctl->vd[0].access |= active
1149			? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1150		snd_ctl_notify(codec->bus->card,
1151			       SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
1152	}
1153}
1154
1155static hda_nid_t side_mute_channel(struct via_spec *spec)
1156{
1157	switch (spec->codec_type) {
1158	case VT1708:		return 0x1b;
1159	case VT1709_10CH:	return 0x29;
1160	case VT1708B_8CH:	/* fall thru */
1161	case VT1708S:		return 0x27;
1162	default:		return 0;
1163	}
1164}
1165
1166static int update_side_mute_status(struct hda_codec *codec)
1167{
1168	/* mute side channel */
1169	struct via_spec *spec = codec->spec;
1170	unsigned int parm = spec->hp_independent_mode
1171		? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1172	hda_nid_t sw3 = side_mute_channel(spec);
1173
1174	if (sw3)
1175		snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1176				    parm);
1177	return 0;
1178}
1179
1180static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1181				  struct snd_ctl_elem_value *ucontrol)
1182{
1183	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1184	struct via_spec *spec = codec->spec;
1185	hda_nid_t nid = kcontrol->private_value;
1186	unsigned int pinsel = ucontrol->value.enumerated.item[0];
1187	/* Get Independent Mode index of headphone pin widget */
1188	spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1189		? 1 : 0;
1190	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
1191
1192	if (spec->multiout.hp_nid && spec->multiout.hp_nid
1193	    != spec->multiout.dac_nids[HDA_FRONT])
1194		snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
1195					   0, 0, 0);
1196
1197	update_side_mute_status(codec);
1198	/* update HP volume/swtich active state */
1199	if (spec->codec_type == VT1708S
1200	    || spec->codec_type == VT1702
1201	    || spec->codec_type == VT1718S
1202	    || spec->codec_type == VT1716S
1203	    || spec->codec_type == VT2002P
1204	    || spec->codec_type == VT1812) {
1205		activate_ctl(codec, "Headphone Playback Volume",
1206			     spec->hp_independent_mode);
1207		activate_ctl(codec, "Headphone Playback Switch",
1208			     spec->hp_independent_mode);
1209	}
1210	return 0;
1211}
1212
1213static struct snd_kcontrol_new via_hp_mixer[2] = {
1214	{
1215		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1216		.name = "Independent HP",
1217		.info = via_independent_hp_info,
1218		.get = via_independent_hp_get,
1219		.put = via_independent_hp_put,
1220	},
1221	{
1222		.iface = NID_MAPPING,
1223		.name = "Independent HP",
1224	},
1225};
1226
1227static int via_hp_build(struct hda_codec *codec)
1228{
1229	struct via_spec *spec = codec->spec;
1230	struct snd_kcontrol_new *knew;
1231	hda_nid_t nid;
1232	int nums;
1233	hda_nid_t conn[HDA_MAX_CONNECTIONS];
1234
1235	switch (spec->codec_type) {
1236	case VT1718S:
1237		nid = 0x34;
1238		break;
1239	case VT2002P:
1240		nid = 0x35;
1241		break;
1242	case VT1812:
1243		nid = 0x3d;
1244		break;
1245	default:
1246		nid = spec->autocfg.hp_pins[0];
1247		break;
1248	}
1249
1250	nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
1251	if (nums <= 1)
1252		return 0;
1253
1254	knew = via_clone_control(spec, &via_hp_mixer[0]);
1255	if (knew == NULL)
1256		return -ENOMEM;
1257
1258	knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1259	knew->private_value = nid;
1260
1261	knew = via_clone_control(spec, &via_hp_mixer[1]);
1262	if (knew == NULL)
1263		return -ENOMEM;
1264	knew->subdevice = side_mute_channel(spec);
1265
1266	return 0;
1267}
1268
1269static void notify_aa_path_ctls(struct hda_codec *codec)
1270{
1271	int i;
1272	struct snd_ctl_elem_id id;
1273	const char *labels[] = {"Mic", "Front Mic", "Line"};
1274
1275	memset(&id, 0, sizeof(id));
1276	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1277	for (i = 0; i < ARRAY_SIZE(labels); i++) {
1278		sprintf(id.name, "%s Playback Volume", labels[i]);
1279		snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1280			       &id);
1281	}
1282}
1283
1284static void mute_aa_path(struct hda_codec *codec, int mute)
1285{
1286	struct via_spec *spec = codec->spec;
1287	hda_nid_t  nid_mixer;
1288	int start_idx;
1289	int end_idx;
1290	int i;
1291	/* get nid of MW0 and start & end index */
1292	switch (spec->codec_type) {
1293	case VT1708:
1294		nid_mixer = 0x17;
1295		start_idx = 2;
1296		end_idx = 4;
1297		break;
1298	case VT1709_10CH:
1299	case VT1709_6CH:
1300		nid_mixer = 0x18;
1301		start_idx = 2;
1302		end_idx = 4;
1303		break;
1304	case VT1708B_8CH:
1305	case VT1708B_4CH:
1306	case VT1708S:
1307	case VT1716S:
1308		nid_mixer = 0x16;
1309		start_idx = 2;
1310		end_idx = 4;
1311		break;
1312	default:
1313		return;
1314	}
1315	/* check AA path's mute status */
1316	for (i = start_idx; i <= end_idx; i++) {
1317		int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
1318		snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i,
1319					 HDA_AMP_MUTE, val);
1320	}
1321}
1322static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1323{
1324	int res = 0;
1325	int index;
1326	for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) {
1327		if (pin == spec->autocfg.input_pins[index]) {
1328			res = 1;
1329			break;
1330		}
1331	}
1332	return res;
1333}
1334
1335static int via_smart51_info(struct snd_kcontrol *kcontrol,
1336			    struct snd_ctl_elem_info *uinfo)
1337{
1338	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1339	uinfo->count = 1;
1340	uinfo->value.integer.min = 0;
1341	uinfo->value.integer.max = 1;
1342	return 0;
1343}
1344
1345static int via_smart51_get(struct snd_kcontrol *kcontrol,
1346			   struct snd_ctl_elem_value *ucontrol)
1347{
1348	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1349	struct via_spec *spec = codec->spec;
1350	int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1351	int on = 1;
1352	int i;
1353
1354	for (i = 0; i < ARRAY_SIZE(index); i++) {
1355		hda_nid_t nid = spec->autocfg.input_pins[index[i]];
1356		if (nid) {
1357			int ctl =
1358			    snd_hda_codec_read(codec, nid, 0,
1359					       AC_VERB_GET_PIN_WIDGET_CONTROL,
1360					       0);
1361			if (i == AUTO_PIN_FRONT_MIC
1362			    && spec->hp_independent_mode
1363			    && spec->codec_type != VT1718S)
1364				continue; /* ignore FMic for independent HP */
1365			if (ctl & AC_PINCTL_IN_EN
1366			    && !(ctl & AC_PINCTL_OUT_EN))
1367				on = 0;
1368		}
1369	}
1370	*ucontrol->value.integer.value = on;
1371	return 0;
1372}
1373
1374static int via_smart51_put(struct snd_kcontrol *kcontrol,
1375			   struct snd_ctl_elem_value *ucontrol)
1376{
1377	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1378	struct via_spec *spec = codec->spec;
1379	int out_in = *ucontrol->value.integer.value
1380		? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1381	int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1382	int i;
1383
1384	for (i = 0; i < ARRAY_SIZE(index); i++) {
1385		hda_nid_t nid = spec->autocfg.input_pins[index[i]];
1386		if (i == AUTO_PIN_FRONT_MIC
1387		    && spec->hp_independent_mode
1388		    && spec->codec_type != VT1718S)
1389			continue; /* don't retask FMic for independent HP */
1390		if (nid) {
1391			unsigned int parm = snd_hda_codec_read(
1392				codec, nid, 0,
1393				AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1394			parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1395			parm |= out_in;
1396			snd_hda_codec_write(codec, nid, 0,
1397					    AC_VERB_SET_PIN_WIDGET_CONTROL,
1398					    parm);
1399			if (out_in == AC_PINCTL_OUT_EN) {
1400				mute_aa_path(codec, 1);
1401				notify_aa_path_ctls(codec);
1402			}
1403			if (spec->codec_type == VT1718S)
1404				snd_hda_codec_amp_stereo(
1405					codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1406					HDA_AMP_UNMUTE);
1407		}
1408		if (i == AUTO_PIN_FRONT_MIC) {
1409			if (spec->codec_type == VT1708S
1410			    || spec->codec_type == VT1716S) {
1411				/* input = index 1 (AOW3) */
1412				snd_hda_codec_write(
1413					codec, nid, 0,
1414					AC_VERB_SET_CONNECT_SEL, 1);
1415				snd_hda_codec_amp_stereo(
1416					codec, nid, HDA_OUTPUT,
1417					0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1418			}
1419		}
1420	}
1421	spec->smart51_enabled = *ucontrol->value.integer.value;
1422	set_jack_power_state(codec);
1423	return 1;
1424}
1425
1426static struct snd_kcontrol_new via_smart51_mixer[2] = {
1427	{
1428	 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1429	 .name = "Smart 5.1",
1430	 .count = 1,
1431	 .info = via_smart51_info,
1432	 .get = via_smart51_get,
1433	 .put = via_smart51_put,
1434	 },
1435	{
1436	 .iface = NID_MAPPING,
1437	 .name = "Smart 5.1",
1438	}
1439};
1440
1441static int via_smart51_build(struct via_spec *spec)
1442{
1443	struct snd_kcontrol_new *knew;
1444	int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1445	hda_nid_t nid;
1446	int i;
1447
1448	knew = via_clone_control(spec, &via_smart51_mixer[0]);
1449	if (knew == NULL)
1450		return -ENOMEM;
1451
1452	for (i = 0; i < ARRAY_SIZE(index); i++) {
1453		nid = spec->autocfg.input_pins[index[i]];
1454		if (nid) {
1455			knew = via_clone_control(spec, &via_smart51_mixer[1]);
1456			if (knew == NULL)
1457				return -ENOMEM;
1458			knew->subdevice = nid;
1459		}
1460	}
1461
1462	return 0;
1463}
1464
1465/* capture mixer elements */
1466static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1467	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1468	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1469	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1470	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1471	{
1472		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1473		/* The multiple "Capture Source" controls confuse alsamixer
1474		 * So call somewhat different..
1475		 */
1476		/* .name = "Capture Source", */
1477		.name = "Input Source",
1478		.count = 1,
1479		.info = via_mux_enum_info,
1480		.get = via_mux_enum_get,
1481		.put = via_mux_enum_put,
1482	},
1483	{ } /* end */
1484};
1485
1486/* check AA path's mute statue */
1487static int is_aa_path_mute(struct hda_codec *codec)
1488{
1489	int mute = 1;
1490	hda_nid_t  nid_mixer;
1491	int start_idx;
1492	int end_idx;
1493	int i;
1494	struct via_spec *spec = codec->spec;
1495	/* get nid of MW0 and start & end index */
1496	switch (spec->codec_type) {
1497	case VT1708B_8CH:
1498	case VT1708B_4CH:
1499	case VT1708S:
1500	case VT1716S:
1501		nid_mixer = 0x16;
1502		start_idx = 2;
1503		end_idx = 4;
1504		break;
1505	case VT1702:
1506		nid_mixer = 0x1a;
1507		start_idx = 1;
1508		end_idx = 3;
1509		break;
1510	case VT1718S:
1511		nid_mixer = 0x21;
1512		start_idx = 1;
1513		end_idx = 3;
1514		break;
1515	case VT2002P:
1516	case VT1812:
1517		nid_mixer = 0x21;
1518		start_idx = 0;
1519		end_idx = 2;
1520		break;
1521	default:
1522		return 0;
1523	}
1524	/* check AA path's mute status */
1525	for (i = start_idx; i <= end_idx; i++) {
1526		unsigned int con_list = snd_hda_codec_read(
1527			codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1528		int shift = 8 * (i % 4);
1529		hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1530		unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1531		if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1532			/* check mute status while the pin is connected */
1533			int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1534							    HDA_INPUT, i) >> 7;
1535			int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1536							    HDA_INPUT, i) >> 7;
1537			if (!mute_l || !mute_r) {
1538				mute = 0;
1539				break;
1540			}
1541		}
1542	}
1543	return mute;
1544}
1545
1546/* enter/exit analog low-current mode */
1547static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1548{
1549	struct via_spec *spec = codec->spec;
1550	static int saved_stream_idle = 1; /* saved stream idle status */
1551	int enable = is_aa_path_mute(codec);
1552	unsigned int verb = 0;
1553	unsigned int parm = 0;
1554
1555	if (stream_idle == -1)	/* stream status did not change */
1556		enable = enable && saved_stream_idle;
1557	else {
1558		enable = enable && stream_idle;
1559		saved_stream_idle = stream_idle;
1560	}
1561
1562	/* decide low current mode's verb & parameter */
1563	switch (spec->codec_type) {
1564	case VT1708B_8CH:
1565	case VT1708B_4CH:
1566		verb = 0xf70;
1567		parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1568		break;
1569	case VT1708S:
1570	case VT1718S:
1571	case VT1716S:
1572		verb = 0xf73;
1573		parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1574		break;
1575	case VT1702:
1576		verb = 0xf73;
1577		parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1578		break;
1579	case VT2002P:
1580	case VT1812:
1581		verb = 0xf93;
1582		parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1583		break;
1584	default:
1585		return;		/* other codecs are not supported */
1586	}
1587	/* send verb */
1588	snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1589}
1590
1591/*
1592 * generic initialization of ADC, input mixers and output mixers
1593 */
1594static struct hda_verb vt1708_volume_init_verbs[] = {
1595	/*
1596	 * Unmute ADC0-1 and set the default input to mic-in
1597	 */
1598	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1599	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1600
1601
1602	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1603	 * mixer widget
1604	 */
1605	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1606	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1607	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1608	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1609	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1610	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1611
1612	/*
1613	 * Set up output mixers (0x19 - 0x1b)
1614	 */
1615	/* set vol=0 to output mixers */
1616	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1617	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1618	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1619
1620	/* Setup default input MW0 to PW4 */
1621	{0x20, AC_VERB_SET_CONNECT_SEL, 0},
1622	/* PW9 Output enable */
1623	{0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1624	{ }
1625};
1626
1627static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
1628				 struct hda_codec *codec,
1629				 struct snd_pcm_substream *substream)
1630{
1631	struct via_spec *spec = codec->spec;
1632	int idle = substream->pstr->substream_opened == 1
1633		&& substream->ref_count == 0;
1634	analog_low_current_mode(codec, idle);
1635	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1636					     hinfo);
1637}
1638
1639static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1640				      unsigned int stream_tag,
1641				      unsigned int format,
1642				      struct snd_pcm_substream *substream)
1643{
1644	struct via_spec *spec = codec->spec;
1645	struct hda_multi_out *mout = &spec->multiout;
1646	hda_nid_t *nids = mout->dac_nids;
1647	int chs = substream->runtime->channels;
1648	int i;
1649
1650	mutex_lock(&codec->spdif_mutex);
1651	if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1652		if (chs == 2 &&
1653		    snd_hda_is_supported_format(codec, mout->dig_out_nid,
1654						format) &&
1655		    !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1656			mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1657			/* turn off SPDIF once; otherwise the IEC958 bits won't
1658			 * be updated */
1659			if (codec->spdif_ctls & AC_DIG1_ENABLE)
1660				snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1661						    AC_VERB_SET_DIGI_CONVERT_1,
1662						    codec->spdif_ctls &
1663							~AC_DIG1_ENABLE & 0xff);
1664			snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1665						   stream_tag, 0, format);
1666			/* turn on again (if needed) */
1667			if (codec->spdif_ctls & AC_DIG1_ENABLE)
1668				snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1669						    AC_VERB_SET_DIGI_CONVERT_1,
1670						    codec->spdif_ctls & 0xff);
1671		} else {
1672			mout->dig_out_used = 0;
1673			snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1674						   0, 0, 0);
1675		}
1676	}
1677	mutex_unlock(&codec->spdif_mutex);
1678
1679	/* front */
1680	snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1681				   0, format);
1682
1683	if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1684	    && !spec->hp_independent_mode)
1685		/* headphone out will just decode front left/right (stereo) */
1686		snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1687					   0, format);
1688
1689	/* extra outputs copied from front */
1690	for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1691		if (mout->extra_out_nid[i])
1692			snd_hda_codec_setup_stream(codec,
1693						   mout->extra_out_nid[i],
1694						   stream_tag, 0, format);
1695
1696	/* surrounds */
1697	for (i = 1; i < mout->num_dacs; i++) {
1698		if (chs >= (i + 1) * 2) /* independent out */
1699			snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1700						   i * 2, format);
1701		else /* copy front */
1702			snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1703						   0, format);
1704	}
1705}
1706
1707static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1708					  struct hda_codec *codec,
1709					  unsigned int stream_tag,
1710					  unsigned int format,
1711					  struct snd_pcm_substream *substream)
1712{
1713	struct via_spec *spec = codec->spec;
1714	struct hda_multi_out *mout = &spec->multiout;
1715	hda_nid_t *nids = mout->dac_nids;
1716
1717	if (substream->number == 0)
1718		playback_multi_pcm_prep_0(codec, stream_tag, format,
1719					  substream);
1720	else {
1721		if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1722		    spec->hp_independent_mode)
1723			snd_hda_codec_setup_stream(codec, mout->hp_nid,
1724						   stream_tag, 0, format);
1725	}
1726	vt1708_start_hp_work(spec);
1727	return 0;
1728}
1729
1730static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1731				    struct hda_codec *codec,
1732				    struct snd_pcm_substream *substream)
1733{
1734	struct via_spec *spec = codec->spec;
1735	struct hda_multi_out *mout = &spec->multiout;
1736	hda_nid_t *nids = mout->dac_nids;
1737	int i;
1738
1739	if (substream->number == 0) {
1740		for (i = 0; i < mout->num_dacs; i++)
1741			snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1742
1743		if (mout->hp_nid && !spec->hp_independent_mode)
1744			snd_hda_codec_setup_stream(codec, mout->hp_nid,
1745						   0, 0, 0);
1746
1747		for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1748			if (mout->extra_out_nid[i])
1749				snd_hda_codec_setup_stream(codec,
1750							mout->extra_out_nid[i],
1751							0, 0, 0);
1752		mutex_lock(&codec->spdif_mutex);
1753		if (mout->dig_out_nid &&
1754		    mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1755			snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1756						   0, 0, 0);
1757			mout->dig_out_used = 0;
1758		}
1759		mutex_unlock(&codec->spdif_mutex);
1760	} else {
1761		if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1762		    spec->hp_independent_mode)
1763			snd_hda_codec_setup_stream(codec, mout->hp_nid,
1764						   0, 0, 0);
1765	}
1766	vt1708_stop_hp_work(spec);
1767	return 0;
1768}
1769
1770/*
1771 * Digital out
1772 */
1773static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1774				     struct hda_codec *codec,
1775				     struct snd_pcm_substream *substream)
1776{
1777	struct via_spec *spec = codec->spec;
1778	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1779}
1780
1781static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1782				      struct hda_codec *codec,
1783				      struct snd_pcm_substream *substream)
1784{
1785	struct via_spec *spec = codec->spec;
1786	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1787}
1788
1789static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1790					struct hda_codec *codec,
1791					unsigned int stream_tag,
1792					unsigned int format,
1793					struct snd_pcm_substream *substream)
1794{
1795	struct via_spec *spec = codec->spec;
1796	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1797					     stream_tag, format, substream);
1798}
1799
1800static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1801					struct hda_codec *codec,
1802					struct snd_pcm_substream *substream)
1803{
1804	struct via_spec *spec = codec->spec;
1805	snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1806	return 0;
1807}
1808
1809/*
1810 * Analog capture
1811 */
1812static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1813				   struct hda_codec *codec,
1814				   unsigned int stream_tag,
1815				   unsigned int format,
1816				   struct snd_pcm_substream *substream)
1817{
1818	struct via_spec *spec = codec->spec;
1819
1820	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1821				   stream_tag, 0, format);
1822	return 0;
1823}
1824
1825static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1826				   struct hda_codec *codec,
1827				   struct snd_pcm_substream *substream)
1828{
1829	struct via_spec *spec = codec->spec;
1830	snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1831	return 0;
1832}
1833
1834static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1835	.substreams = 2,
1836	.channels_min = 2,
1837	.channels_max = 8,
1838	.nid = 0x10, /* NID to query formats and rates */
1839	.ops = {
1840		.open = via_playback_pcm_open,
1841		.prepare = via_playback_multi_pcm_prepare,
1842		.cleanup = via_playback_multi_pcm_cleanup
1843	},
1844};
1845
1846static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1847	.substreams = 2,
1848	.channels_min = 2,
1849	.channels_max = 8,
1850	.nid = 0x10, /* NID to query formats and rates */
1851	.formats = SNDRV_PCM_FMTBIT_S16_LE,
1852	.ops = {
1853		.open = via_playback_pcm_open,
1854		.prepare = via_playback_multi_pcm_prepare,
1855		.cleanup = via_playback_multi_pcm_cleanup
1856	},
1857};
1858
1859static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1860	.substreams = 2,
1861	.channels_min = 2,
1862	.channels_max = 2,
1863	.nid = 0x15, /* NID to query formats and rates */
1864	.ops = {
1865		.prepare = via_capture_pcm_prepare,
1866		.cleanup = via_capture_pcm_cleanup
1867	},
1868};
1869
1870static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1871	.substreams = 1,
1872	.channels_min = 2,
1873	.channels_max = 2,
1874	/* NID is set in via_build_pcms */
1875	.ops = {
1876		.open = via_dig_playback_pcm_open,
1877		.close = via_dig_playback_pcm_close,
1878		.prepare = via_dig_playback_pcm_prepare,
1879		.cleanup = via_dig_playback_pcm_cleanup
1880	},
1881};
1882
1883static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1884	.substreams = 1,
1885	.channels_min = 2,
1886	.channels_max = 2,
1887};
1888
1889static int via_build_controls(struct hda_codec *codec)
1890{
1891	struct via_spec *spec = codec->spec;
1892	struct snd_kcontrol *kctl;
1893	struct snd_kcontrol_new *knew;
1894	int err, i;
1895
1896	for (i = 0; i < spec->num_mixers; i++) {
1897		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1898		if (err < 0)
1899			return err;
1900	}
1901
1902	if (spec->multiout.dig_out_nid) {
1903		err = snd_hda_create_spdif_out_ctls(codec,
1904						    spec->multiout.dig_out_nid);
1905		if (err < 0)
1906			return err;
1907		err = snd_hda_create_spdif_share_sw(codec,
1908						    &spec->multiout);
1909		if (err < 0)
1910			return err;
1911		spec->multiout.share_spdif = 1;
1912	}
1913	if (spec->dig_in_nid) {
1914		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1915		if (err < 0)
1916			return err;
1917	}
1918
1919	/* assign Capture Source enums to NID */
1920	kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1921	for (i = 0; kctl && i < kctl->count; i++) {
1922		err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1923		if (err < 0)
1924			return err;
1925	}
1926
1927	/* other nid->control mapping */
1928	for (i = 0; i < spec->num_mixers; i++) {
1929		for (knew = spec->mixers[i]; knew->name; knew++) {
1930			if (knew->iface != NID_MAPPING)
1931				continue;
1932			kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1933			if (kctl == NULL)
1934				continue;
1935			err = snd_hda_add_nid(codec, kctl, 0,
1936					      knew->subdevice);
1937		}
1938	}
1939
1940	/* init power states */
1941	set_jack_power_state(codec);
1942	analog_low_current_mode(codec, 1);
1943
1944	via_free_kctls(codec); /* no longer needed */
1945	return 0;
1946}
1947
1948static int via_build_pcms(struct hda_codec *codec)
1949{
1950	struct via_spec *spec = codec->spec;
1951	struct hda_pcm *info = spec->pcm_rec;
1952
1953	codec->num_pcms = 1;
1954	codec->pcm_info = info;
1955
1956	info->name = spec->stream_name_analog;
1957	info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1958		*(spec->stream_analog_playback);
1959	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1960		spec->multiout.dac_nids[0];
1961	info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1962	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1963
1964	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1965		spec->multiout.max_channels;
1966
1967	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1968		codec->num_pcms++;
1969		info++;
1970		info->name = spec->stream_name_digital;
1971		info->pcm_type = HDA_PCM_TYPE_SPDIF;
1972		if (spec->multiout.dig_out_nid) {
1973			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1974				*(spec->stream_digital_playback);
1975			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1976				spec->multiout.dig_out_nid;
1977		}
1978		if (spec->dig_in_nid) {
1979			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1980				*(spec->stream_digital_capture);
1981			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1982				spec->dig_in_nid;
1983		}
1984	}
1985
1986	return 0;
1987}
1988
1989static void via_free(struct hda_codec *codec)
1990{
1991	struct via_spec *spec = codec->spec;
1992
1993	if (!spec)
1994		return;
1995
1996	via_free_kctls(codec);
1997	vt1708_stop_hp_work(spec);
1998	kfree(codec->spec);
1999}
2000
2001/* mute internal speaker if HP is plugged */
2002static void via_hp_automute(struct hda_codec *codec)
2003{
2004	unsigned int present = 0;
2005	struct via_spec *spec = codec->spec;
2006
2007	present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2008
2009	if (!spec->hp_independent_mode) {
2010		struct snd_ctl_elem_id id;
2011		/* auto mute */
2012		snd_hda_codec_amp_stereo(
2013			codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0,
2014			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2015		/* notify change */
2016		memset(&id, 0, sizeof(id));
2017		id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2018		strcpy(id.name, "Front Playback Switch");
2019		snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2020			       &id);
2021	}
2022}
2023
2024/* mute mono out if HP or Line out is plugged */
2025static void via_mono_automute(struct hda_codec *codec)
2026{
2027	unsigned int hp_present, lineout_present;
2028	struct via_spec *spec = codec->spec;
2029
2030	if (spec->codec_type != VT1716S)
2031		return;
2032
2033	lineout_present = snd_hda_jack_detect(codec,
2034					      spec->autocfg.line_out_pins[0]);
2035
2036	/* Mute Mono Out if Line Out is plugged */
2037	if (lineout_present) {
2038		snd_hda_codec_amp_stereo(
2039			codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE);
2040		return;
2041	}
2042
2043	hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2044
2045	if (!spec->hp_independent_mode)
2046		snd_hda_codec_amp_stereo(
2047			codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE,
2048			hp_present ? HDA_AMP_MUTE : 0);
2049}
2050
2051static void via_gpio_control(struct hda_codec *codec)
2052{
2053	unsigned int gpio_data;
2054	unsigned int vol_counter;
2055	unsigned int vol;
2056	unsigned int master_vol;
2057
2058	struct via_spec *spec = codec->spec;
2059
2060	gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
2061				       AC_VERB_GET_GPIO_DATA, 0) & 0x03;
2062
2063	vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
2064					  0xF84, 0) & 0x3F0000) >> 16;
2065
2066	vol = vol_counter & 0x1F;
2067	master_vol = snd_hda_codec_read(codec, 0x1A, 0,
2068					AC_VERB_GET_AMP_GAIN_MUTE,
2069					AC_AMP_GET_INPUT);
2070
2071	if (gpio_data == 0x02) {
2072		/* unmute line out */
2073		snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
2074					 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
2075
2076		if (vol_counter & 0x20) {
2077			/* decrease volume */
2078			if (vol > master_vol)
2079				vol = master_vol;
2080			snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
2081						 0, HDA_AMP_VOLMASK,
2082						 master_vol-vol);
2083		} else {
2084			/* increase volume */
2085			snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
2086					 HDA_AMP_VOLMASK,
2087					 ((master_vol+vol) > 0x2A) ? 0x2A :
2088					  (master_vol+vol));
2089		}
2090	} else if (!(gpio_data & 0x02)) {
2091		/* mute line out */
2092		snd_hda_codec_amp_stereo(codec,
2093					 spec->autocfg.line_out_pins[0],
2094					 HDA_OUTPUT, 0, HDA_AMP_MUTE,
2095					 HDA_AMP_MUTE);
2096	}
2097}
2098
2099/* mute Internal-Speaker if HP is plugged */
2100static void via_speaker_automute(struct hda_codec *codec)
2101{
2102	unsigned int hp_present;
2103	struct via_spec *spec = codec->spec;
2104
2105	if (spec->codec_type != VT2002P && spec->codec_type != VT1812)
2106		return;
2107
2108	hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2109
2110	if (!spec->hp_independent_mode) {
2111		struct snd_ctl_elem_id id;
2112		snd_hda_codec_amp_stereo(
2113			codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
2114			HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2115		/* notify change */
2116		memset(&id, 0, sizeof(id));
2117		id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2118		strcpy(id.name, "Speaker Playback Switch");
2119		snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2120			       &id);
2121	}
2122}
2123
2124/* mute line-out and internal speaker if HP is plugged */
2125static void via_hp_bind_automute(struct hda_codec *codec)
2126{
2127	/* use long instead of int below just to avoid an internal compiler
2128	 * error with gcc 4.0.x
2129	 */
2130	unsigned long hp_present, present = 0;
2131	struct via_spec *spec = codec->spec;
2132	int i;
2133
2134	if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
2135		return;
2136
2137	hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2138
2139	present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
2140
2141	if (!spec->hp_independent_mode) {
2142		/* Mute Line-Outs */
2143		for (i = 0; i < spec->autocfg.line_outs; i++)
2144			snd_hda_codec_amp_stereo(
2145				codec, spec->autocfg.line_out_pins[i],
2146				HDA_OUTPUT, 0,
2147				HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2148		if (hp_present)
2149			present = hp_present;
2150	}
2151	/* Speakers */
2152	for (i = 0; i < spec->autocfg.speaker_outs; i++)
2153		snd_hda_codec_amp_stereo(
2154			codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
2155			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2156}
2157
2158
2159/* unsolicited event for jack sensing */
2160static void via_unsol_event(struct hda_codec *codec,
2161				  unsigned int res)
2162{
2163	res >>= 26;
2164	if (res & VIA_HP_EVENT)
2165		via_hp_automute(codec);
2166	if (res & VIA_GPIO_EVENT)
2167		via_gpio_control(codec);
2168	if (res & VIA_JACK_EVENT)
2169		set_jack_power_state(codec);
2170	if (res & VIA_MONO_EVENT)
2171		via_mono_automute(codec);
2172	if (res & VIA_SPEAKER_EVENT)
2173		via_speaker_automute(codec);
2174	if (res & VIA_BIND_HP_EVENT)
2175		via_hp_bind_automute(codec);
2176}
2177
2178static int via_init(struct hda_codec *codec)
2179{
2180	struct via_spec *spec = codec->spec;
2181	int i;
2182	for (i = 0; i < spec->num_iverbs; i++)
2183		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2184
2185	spec->codec_type = get_codec_type(codec);
2186	if (spec->codec_type == VT1708BCE)
2187		spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost
2188					       same */
2189	/* Lydia Add for EAPD enable */
2190	if (!spec->dig_in_nid) { /* No Digital In connection */
2191		if (spec->dig_in_pin) {
2192			snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2193					    AC_VERB_SET_PIN_WIDGET_CONTROL,
2194					    PIN_OUT);
2195			snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2196					    AC_VERB_SET_EAPD_BTLENABLE, 0x02);
2197		}
2198	} else /* enable SPDIF-input pin */
2199		snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2200				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2201
2202	/* assign slave outs */
2203	if (spec->slave_dig_outs[0])
2204		codec->slave_dig_outs = spec->slave_dig_outs;
2205
2206	return 0;
2207}
2208
2209#ifdef SND_HDA_NEEDS_RESUME
2210static int via_suspend(struct hda_codec *codec, pm_message_t state)
2211{
2212	struct via_spec *spec = codec->spec;
2213	vt1708_stop_hp_work(spec);
2214	return 0;
2215}
2216#endif
2217
2218#ifdef CONFIG_SND_HDA_POWER_SAVE
2219static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2220{
2221	struct via_spec *spec = codec->spec;
2222	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2223}
2224#endif
2225
2226/*
2227 */
2228static struct hda_codec_ops via_patch_ops = {
2229	.build_controls = via_build_controls,
2230	.build_pcms = via_build_pcms,
2231	.init = via_init,
2232	.free = via_free,
2233#ifdef SND_HDA_NEEDS_RESUME
2234	.suspend = via_suspend,
2235#endif
2236#ifdef CONFIG_SND_HDA_POWER_SAVE
2237	.check_power_status = via_check_power_status,
2238#endif
2239};
2240
2241/* fill in the dac_nids table from the parsed pin configuration */
2242static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
2243				     const struct auto_pin_cfg *cfg)
2244{
2245	int i;
2246	hda_nid_t nid;
2247
2248	spec->multiout.num_dacs = cfg->line_outs;
2249
2250	spec->multiout.dac_nids = spec->private_dac_nids;
2251
2252	for (i = 0; i < 4; i++) {
2253		nid = cfg->line_out_pins[i];
2254		if (nid) {
2255			/* config dac list */
2256			switch (i) {
2257			case AUTO_SEQ_FRONT:
2258				spec->multiout.dac_nids[i] = 0x10;
2259				break;
2260			case AUTO_SEQ_CENLFE:
2261				spec->multiout.dac_nids[i] = 0x12;
2262				break;
2263			case AUTO_SEQ_SURROUND:
2264				spec->multiout.dac_nids[i] = 0x11;
2265				break;
2266			case AUTO_SEQ_SIDE:
2267				spec->multiout.dac_nids[i] = 0x13;
2268				break;
2269			}
2270		}
2271	}
2272
2273	return 0;
2274}
2275
2276/* add playback controls from the parsed DAC table */
2277static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
2278					     const struct auto_pin_cfg *cfg)
2279{
2280	char name[32];
2281	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2282	hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
2283	int i, err;
2284
2285	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2286		nid = cfg->line_out_pins[i];
2287
2288		if (!nid)
2289			continue;
2290
2291		nid_vol = nid_vols[i];
2292
2293		if (i == AUTO_SEQ_CENLFE) {
2294			/* Center/LFE */
2295			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2296					"Center Playback Volume",
2297					HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2298							    HDA_OUTPUT));
2299			if (err < 0)
2300				return err;
2301			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2302					      "LFE Playback Volume",
2303					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2304								  HDA_OUTPUT));
2305			if (err < 0)
2306				return err;
2307			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2308					      "Center Playback Switch",
2309					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2310								  HDA_OUTPUT));
2311			if (err < 0)
2312				return err;
2313			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2314					      "LFE Playback Switch",
2315					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2316								  HDA_OUTPUT));
2317			if (err < 0)
2318				return err;
2319		} else if (i == AUTO_SEQ_FRONT) {
2320			/* add control to mixer index 0 */
2321			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2322					      "Master Front Playback Volume",
2323					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2324								  HDA_INPUT));
2325			if (err < 0)
2326				return err;
2327			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2328					      "Master Front Playback Switch",
2329					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2330								  HDA_INPUT));
2331			if (err < 0)
2332				return err;
2333
2334			/* add control to PW3 */
2335			sprintf(name, "%s Playback Volume", chname[i]);
2336			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2337					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2338								  HDA_OUTPUT));
2339			if (err < 0)
2340				return err;
2341			sprintf(name, "%s Playback Switch", chname[i]);
2342			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2343					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2344								  HDA_OUTPUT));
2345			if (err < 0)
2346				return err;
2347		} else {
2348			sprintf(name, "%s Playback Volume", chname[i]);
2349			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2350					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2351								  HDA_OUTPUT));
2352			if (err < 0)
2353				return err;
2354			sprintf(name, "%s Playback Switch", chname[i]);
2355			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2356					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2357								  HDA_OUTPUT));
2358			if (err < 0)
2359				return err;
2360		}
2361	}
2362
2363	return 0;
2364}
2365
2366static void create_hp_imux(struct via_spec *spec)
2367{
2368	int i;
2369	struct hda_input_mux *imux = &spec->private_imux[1];
2370	static const char *texts[] = { "OFF", "ON", NULL};
2371
2372	/* for hp mode select */
2373	i = 0;
2374	while (texts[i] != NULL) {
2375		imux->items[imux->num_items].label =  texts[i];
2376		imux->items[imux->num_items].index = i;
2377		imux->num_items++;
2378		i++;
2379	}
2380
2381	spec->hp_mux = &spec->private_imux[1];
2382}
2383
2384static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2385{
2386	int err;
2387
2388	if (!pin)
2389		return 0;
2390
2391	spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
2392	spec->hp_independent_mode_index = 1;
2393
2394	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2395			      "Headphone Playback Volume",
2396			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2397	if (err < 0)
2398		return err;
2399	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2400			      "Headphone Playback Switch",
2401			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2402	if (err < 0)
2403		return err;
2404
2405	create_hp_imux(spec);
2406
2407	return 0;
2408}
2409
2410/* create playback/capture controls for input pins */
2411static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
2412						const struct auto_pin_cfg *cfg)
2413{
2414	static char *labels[] = {
2415		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2416	};
2417	struct hda_input_mux *imux = &spec->private_imux[0];
2418	int i, err, idx = 0;
2419
2420	/* for internal loopback recording select */
2421	imux->items[imux->num_items].label = "Stereo Mixer";
2422	imux->items[imux->num_items].index = idx;
2423	imux->num_items++;
2424
2425	for (i = 0; i < AUTO_PIN_LAST; i++) {
2426		if (!cfg->input_pins[i])
2427			continue;
2428
2429		switch (cfg->input_pins[i]) {
2430		case 0x1d: /* Mic */
2431			idx = 2;
2432			break;
2433
2434		case 0x1e: /* Line In */
2435			idx = 3;
2436			break;
2437
2438		case 0x21: /* Front Mic */
2439			idx = 4;
2440			break;
2441
2442		case 0x24: /* CD */
2443			idx = 1;
2444			break;
2445		}
2446		err = via_new_analog_input(spec, labels[i], idx, 0x17);
2447		if (err < 0)
2448			return err;
2449		imux->items[imux->num_items].label = labels[i];
2450		imux->items[imux->num_items].index = idx;
2451		imux->num_items++;
2452	}
2453	return 0;
2454}
2455
2456#ifdef CONFIG_SND_HDA_POWER_SAVE
2457static struct hda_amp_list vt1708_loopbacks[] = {
2458	{ 0x17, HDA_INPUT, 1 },
2459	{ 0x17, HDA_INPUT, 2 },
2460	{ 0x17, HDA_INPUT, 3 },
2461	{ 0x17, HDA_INPUT, 4 },
2462	{ } /* end */
2463};
2464#endif
2465
2466static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2467{
2468	unsigned int def_conf;
2469	unsigned char seqassoc;
2470
2471	def_conf = snd_hda_codec_get_pincfg(codec, nid);
2472	seqassoc = (unsigned char) get_defcfg_association(def_conf);
2473	seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
2474	if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2475	    && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2476		def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2477		snd_hda_codec_set_pincfg(codec, nid, def_conf);
2478	}
2479
2480	return;
2481}
2482
2483static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2484				     struct snd_ctl_elem_value *ucontrol)
2485{
2486	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2487	struct via_spec *spec = codec->spec;
2488
2489	if (spec->codec_type != VT1708)
2490		return 0;
2491	spec->vt1708_jack_detectect =
2492		!((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2493	ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
2494	return 0;
2495}
2496
2497static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2498				     struct snd_ctl_elem_value *ucontrol)
2499{
2500	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2501	struct via_spec *spec = codec->spec;
2502	int change;
2503
2504	if (spec->codec_type != VT1708)
2505		return 0;
2506	spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
2507	change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2508		== !spec->vt1708_jack_detectect;
2509	if (spec->vt1708_jack_detectect) {
2510		mute_aa_path(codec, 1);
2511		notify_aa_path_ctls(codec);
2512	}
2513	return change;
2514}
2515
2516static struct snd_kcontrol_new vt1708_jack_detectect[] = {
2517	{
2518		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2519		.name = "Jack Detect",
2520		.count = 1,
2521		.info = snd_ctl_boolean_mono_info,
2522		.get = vt1708_jack_detectect_get,
2523		.put = vt1708_jack_detectect_put,
2524	},
2525	{} /* end */
2526};
2527
2528static int vt1708_parse_auto_config(struct hda_codec *codec)
2529{
2530	struct via_spec *spec = codec->spec;
2531	int err;
2532
2533	/* Add HP and CD pin config connect bit re-config action */
2534	vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2535	vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2536
2537	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2538	if (err < 0)
2539		return err;
2540	err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2541	if (err < 0)
2542		return err;
2543	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2544		return 0; /* can't find valid BIOS pin config */
2545
2546	err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
2547	if (err < 0)
2548		return err;
2549	err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2550	if (err < 0)
2551		return err;
2552	err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
2553	if (err < 0)
2554		return err;
2555	/* add jack detect on/off control */
2556	err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
2557	if (err < 0)
2558		return err;
2559
2560	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2561
2562	if (spec->autocfg.dig_outs)
2563		spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
2564	spec->dig_in_pin = VT1708_DIGIN_PIN;
2565	if (spec->autocfg.dig_in_pin)
2566		spec->dig_in_nid = VT1708_DIGIN_NID;
2567
2568	if (spec->kctls.list)
2569		spec->mixers[spec->num_mixers++] = spec->kctls.list;
2570
2571	spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2572
2573	spec->input_mux = &spec->private_imux[0];
2574
2575	if (spec->hp_mux)
2576		via_hp_build(codec);
2577
2578	via_smart51_build(spec);
2579	return 1;
2580}
2581
2582/* init callback for auto-configuration model -- overriding the default init */
2583static int via_auto_init(struct hda_codec *codec)
2584{
2585	struct via_spec *spec = codec->spec;
2586
2587	via_init(codec);
2588	via_auto_init_multi_out(codec);
2589	via_auto_init_hp_out(codec);
2590	via_auto_init_analog_input(codec);
2591	if (spec->codec_type == VT2002P || spec->codec_type == VT1812) {
2592		via_hp_bind_automute(codec);
2593	} else {
2594		via_hp_automute(codec);
2595		via_speaker_automute(codec);
2596	}
2597
2598	return 0;
2599}
2600
2601static void vt1708_update_hp_jack_state(struct work_struct *work)
2602{
2603	struct via_spec *spec = container_of(work, struct via_spec,
2604					     vt1708_hp_work.work);
2605	if (spec->codec_type != VT1708)
2606		return;
2607	/* if jack state toggled */
2608	if (spec->vt1708_hp_present
2609	    != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2610		spec->vt1708_hp_present ^= 1;
2611		via_hp_automute(spec->codec);
2612	}
2613	vt1708_start_hp_work(spec);
2614}
2615
2616static int get_mux_nids(struct hda_codec *codec)
2617{
2618	struct via_spec *spec = codec->spec;
2619	hda_nid_t nid, conn[8];
2620	unsigned int type;
2621	int i, n;
2622
2623	for (i = 0; i < spec->num_adc_nids; i++) {
2624		nid = spec->adc_nids[i];
2625		while (nid) {
2626			type = get_wcaps_type(get_wcaps(codec, nid));
2627			if (type == AC_WID_PIN)
2628				break;
2629			n = snd_hda_get_connections(codec, nid, conn,
2630						    ARRAY_SIZE(conn));
2631			if (n <= 0)
2632				break;
2633			if (n > 1) {
2634				spec->mux_nids[i] = nid;
2635				break;
2636			}
2637			nid = conn[0];
2638		}
2639	}
2640	return 0;
2641}
2642
2643static int patch_vt1708(struct hda_codec *codec)
2644{
2645	struct via_spec *spec;
2646	int err;
2647
2648	/* create a codec specific record */
2649	spec = via_new_spec(codec);
2650	if (spec == NULL)
2651		return -ENOMEM;
2652
2653	/* automatic parse from the BIOS config */
2654	err = vt1708_parse_auto_config(codec);
2655	if (err < 0) {
2656		via_free(codec);
2657		return err;
2658	} else if (!err) {
2659		printk(KERN_INFO "hda_codec: Cannot set up configuration "
2660		       "from BIOS.  Using genenic mode...\n");
2661	}
2662
2663
2664	spec->stream_name_analog = "VT1708 Analog";
2665	spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2666	/* disable 32bit format on VT1708 */
2667	if (codec->vendor_id == 0x11061708)
2668		spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2669	spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2670
2671	spec->stream_name_digital = "VT1708 Digital";
2672	spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2673	spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2674
2675
2676	if (!spec->adc_nids && spec->input_mux) {
2677		spec->adc_nids = vt1708_adc_nids;
2678		spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2679		get_mux_nids(codec);
2680		spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2681		spec->num_mixers++;
2682	}
2683
2684	codec->patch_ops = via_patch_ops;
2685
2686	codec->patch_ops.init = via_auto_init;
2687#ifdef CONFIG_SND_HDA_POWER_SAVE
2688	spec->loopback.amplist = vt1708_loopbacks;
2689#endif
2690	INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2691	return 0;
2692}
2693
2694/* capture mixer elements */
2695static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2696	HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2697	HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2698	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2699	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2700	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2701	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2702	{
2703		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2704		/* The multiple "Capture Source" controls confuse alsamixer
2705		 * So call somewhat different..
2706		 */
2707		/* .name = "Capture Source", */
2708		.name = "Input Source",
2709		.count = 1,
2710		.info = via_mux_enum_info,
2711		.get = via_mux_enum_get,
2712		.put = via_mux_enum_put,
2713	},
2714	{ } /* end */
2715};
2716
2717static struct hda_verb vt1709_uniwill_init_verbs[] = {
2718	{0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2719	 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2720	{ }
2721};
2722
2723/*
2724 * generic initialization of ADC, input mixers and output mixers
2725 */
2726static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2727	/*
2728	 * Unmute ADC0-2 and set the default input to mic-in
2729	 */
2730	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2731	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2732	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2733
2734
2735	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2736	 * mixer widget
2737	 */
2738	/* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2739	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2740	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2741	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2742	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2743	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2744
2745	/*
2746	 * Set up output selector (0x1a, 0x1b, 0x29)
2747	 */
2748	/* set vol=0 to output mixers */
2749	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2750	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2751	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2752
2753	/*
2754	 *  Unmute PW3 and PW4
2755	 */
2756	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2757	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2758
2759	/* Set input of PW4 as MW0 */
2760	{0x20, AC_VERB_SET_CONNECT_SEL, 0},
2761	/* PW9 Output enable */
2762	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2763	{ }
2764};
2765
2766static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2767	.substreams = 1,
2768	.channels_min = 2,
2769	.channels_max = 10,
2770	.nid = 0x10, /* NID to query formats and rates */
2771	.ops = {
2772		.open = via_playback_pcm_open,
2773		.prepare = via_playback_multi_pcm_prepare,
2774		.cleanup = via_playback_multi_pcm_cleanup,
2775	},
2776};
2777
2778static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2779	.substreams = 1,
2780	.channels_min = 2,
2781	.channels_max = 6,
2782	.nid = 0x10, /* NID to query formats and rates */
2783	.ops = {
2784		.open = via_playback_pcm_open,
2785		.prepare = via_playback_multi_pcm_prepare,
2786		.cleanup = via_playback_multi_pcm_cleanup,
2787	},
2788};
2789
2790static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2791	.substreams = 2,
2792	.channels_min = 2,
2793	.channels_max = 2,
2794	.nid = 0x14, /* NID to query formats and rates */
2795	.ops = {
2796		.prepare = via_capture_pcm_prepare,
2797		.cleanup = via_capture_pcm_cleanup
2798	},
2799};
2800
2801static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2802	.substreams = 1,
2803	.channels_min = 2,
2804	.channels_max = 2,
2805	/* NID is set in via_build_pcms */
2806	.ops = {
2807		.open = via_dig_playback_pcm_open,
2808		.close = via_dig_playback_pcm_close
2809	},
2810};
2811
2812static struct hda_pcm_stream vt1709_pcm_digital_capture = {
2813	.substreams = 1,
2814	.channels_min = 2,
2815	.channels_max = 2,
2816};
2817
2818static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2819				     const struct auto_pin_cfg *cfg)
2820{
2821	int i;
2822	hda_nid_t nid;
2823
2824	if (cfg->line_outs == 4)  /* 10 channels */
2825		spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2826	else if (cfg->line_outs == 3) /* 6 channels */
2827		spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2828
2829	spec->multiout.dac_nids = spec->private_dac_nids;
2830
2831	if (cfg->line_outs == 4) { /* 10 channels */
2832		for (i = 0; i < cfg->line_outs; i++) {
2833			nid = cfg->line_out_pins[i];
2834			if (nid) {
2835				/* config dac list */
2836				switch (i) {
2837				case AUTO_SEQ_FRONT:
2838					/* AOW0 */
2839					spec->multiout.dac_nids[i] = 0x10;
2840					break;
2841				case AUTO_SEQ_CENLFE:
2842					/* AOW2 */
2843					spec->multiout.dac_nids[i] = 0x12;
2844					break;
2845				case AUTO_SEQ_SURROUND:
2846					/* AOW3 */
2847					spec->multiout.dac_nids[i] = 0x11;
2848					break;
2849				case AUTO_SEQ_SIDE:
2850					/* AOW1 */
2851					spec->multiout.dac_nids[i] = 0x27;
2852					break;
2853				default:
2854					break;
2855				}
2856			}
2857		}
2858		spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2859
2860	} else if (cfg->line_outs == 3) { /* 6 channels */
2861		for (i = 0; i < cfg->line_outs; i++) {
2862			nid = cfg->line_out_pins[i];
2863			if (nid) {
2864				/* config dac list */
2865				switch (i) {
2866				case AUTO_SEQ_FRONT:
2867					/* AOW0 */
2868					spec->multiout.dac_nids[i] = 0x10;
2869					break;
2870				case AUTO_SEQ_CENLFE:
2871					/* AOW2 */
2872					spec->multiout.dac_nids[i] = 0x12;
2873					break;
2874				case AUTO_SEQ_SURROUND:
2875					/* AOW1 */
2876					spec->multiout.dac_nids[i] = 0x11;
2877					break;
2878				default:
2879					break;
2880				}
2881			}
2882		}
2883	}
2884
2885	return 0;
2886}
2887
2888/* add playback controls from the parsed DAC table */
2889static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2890					     const struct auto_pin_cfg *cfg)
2891{
2892	char name[32];
2893	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2894	hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2895	int i, err;
2896
2897	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2898		nid = cfg->line_out_pins[i];
2899
2900		if (!nid)
2901			continue;
2902
2903		nid_vol = nid_vols[i];
2904
2905		if (i == AUTO_SEQ_CENLFE) {
2906			/* Center/LFE */
2907			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2908					      "Center Playback Volume",
2909					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2910								  HDA_OUTPUT));
2911			if (err < 0)
2912				return err;
2913			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2914					      "LFE Playback Volume",
2915					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2916								  HDA_OUTPUT));
2917			if (err < 0)
2918				return err;
2919			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2920					      "Center Playback Switch",
2921					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2922								  HDA_OUTPUT));
2923			if (err < 0)
2924				return err;
2925			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2926					      "LFE Playback Switch",
2927					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2928								  HDA_OUTPUT));
2929			if (err < 0)
2930				return err;
2931		} else if (i == AUTO_SEQ_FRONT) {
2932			/* ADD control to mixer index 0 */
2933			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2934					      "Master Front Playback Volume",
2935					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2936								  HDA_INPUT));
2937			if (err < 0)
2938				return err;
2939			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2940					      "Master Front Playback Switch",
2941					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2942								  HDA_INPUT));
2943			if (err < 0)
2944				return err;
2945
2946			/* add control to PW3 */
2947			sprintf(name, "%s Playback Volume", chname[i]);
2948			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2949					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2950								  HDA_OUTPUT));
2951			if (err < 0)
2952				return err;
2953			sprintf(name, "%s Playback Switch", chname[i]);
2954			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2955					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2956								  HDA_OUTPUT));
2957			if (err < 0)
2958				return err;
2959		} else if (i == AUTO_SEQ_SURROUND) {
2960			sprintf(name, "%s Playback Volume", chname[i]);
2961			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2962					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2963								  HDA_OUTPUT));
2964			if (err < 0)
2965				return err;
2966			sprintf(name, "%s Playback Switch", chname[i]);
2967			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2968					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2969								  HDA_OUTPUT));
2970			if (err < 0)
2971				return err;
2972		} else if (i == AUTO_SEQ_SIDE) {
2973			sprintf(name, "%s Playback Volume", chname[i]);
2974			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2975					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2976								  HDA_OUTPUT));
2977			if (err < 0)
2978				return err;
2979			sprintf(name, "%s Playback Switch", chname[i]);
2980			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2981					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2982								  HDA_OUTPUT));
2983			if (err < 0)
2984				return err;
2985		}
2986	}
2987
2988	return 0;
2989}
2990
2991static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2992{
2993	int err;
2994
2995	if (!pin)
2996		return 0;
2997
2998	if (spec->multiout.num_dacs == 5) /* 10 channels */
2999		spec->multiout.hp_nid = VT1709_HP_DAC_NID;
3000	else if (spec->multiout.num_dacs == 3) /* 6 channels */
3001		spec->multiout.hp_nid = 0;
3002	spec->hp_independent_mode_index = 1;
3003
3004	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3005			      "Headphone Playback Volume",
3006			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3007	if (err < 0)
3008		return err;
3009	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3010			      "Headphone Playback Switch",
3011			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3012	if (err < 0)
3013		return err;
3014
3015	return 0;
3016}
3017
3018/* create playback/capture controls for input pins */
3019static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
3020						const struct auto_pin_cfg *cfg)
3021{
3022	static char *labels[] = {
3023		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
3024	};
3025	struct hda_input_mux *imux = &spec->private_imux[0];
3026	int i, err, idx = 0;
3027
3028	/* for internal loopback recording select */
3029	imux->items[imux->num_items].label = "Stereo Mixer";
3030	imux->items[imux->num_items].index = idx;
3031	imux->num_items++;
3032
3033	for (i = 0; i < AUTO_PIN_LAST; i++) {
3034		if (!cfg->input_pins[i])
3035			continue;
3036
3037		switch (cfg->input_pins[i]) {
3038		case 0x1d: /* Mic */
3039			idx = 2;
3040			break;
3041
3042		case 0x1e: /* Line In */
3043			idx = 3;
3044			break;
3045
3046		case 0x21: /* Front Mic */
3047			idx = 4;
3048			break;
3049
3050		case 0x23: /* CD */
3051			idx = 1;
3052			break;
3053		}
3054		err = via_new_analog_input(spec, labels[i], idx, 0x18);
3055		if (err < 0)
3056			return err;
3057		imux->items[imux->num_items].label = labels[i];
3058		imux->items[imux->num_items].index = idx;
3059		imux->num_items++;
3060	}
3061	return 0;
3062}
3063
3064static int vt1709_parse_auto_config(struct hda_codec *codec)
3065{
3066	struct via_spec *spec = codec->spec;
3067	int err;
3068
3069	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3070	if (err < 0)
3071		return err;
3072	err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
3073	if (err < 0)
3074		return err;
3075	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3076		return 0; /* can't find valid BIOS pin config */
3077
3078	err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
3079	if (err < 0)
3080		return err;
3081	err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3082	if (err < 0)
3083		return err;
3084	err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
3085	if (err < 0)
3086		return err;
3087
3088	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3089
3090	if (spec->autocfg.dig_outs)
3091		spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
3092	spec->dig_in_pin = VT1709_DIGIN_PIN;
3093	if (spec->autocfg.dig_in_pin)
3094		spec->dig_in_nid = VT1709_DIGIN_NID;
3095
3096	if (spec->kctls.list)
3097		spec->mixers[spec->num_mixers++] = spec->kctls.list;
3098
3099	spec->input_mux = &spec->private_imux[0];
3100
3101	if (spec->hp_mux)
3102		via_hp_build(codec);
3103
3104	via_smart51_build(spec);
3105	return 1;
3106}
3107
3108#ifdef CONFIG_SND_HDA_POWER_SAVE
3109static struct hda_amp_list vt1709_loopbacks[] = {
3110	{ 0x18, HDA_INPUT, 1 },
3111	{ 0x18, HDA_INPUT, 2 },
3112	{ 0x18, HDA_INPUT, 3 },
3113	{ 0x18, HDA_INPUT, 4 },
3114	{ } /* end */
3115};
3116#endif
3117
3118static int patch_vt1709_10ch(struct hda_codec *codec)
3119{
3120	struct via_spec *spec;
3121	int err;
3122
3123	/* create a codec specific record */
3124	spec = via_new_spec(codec);
3125	if (spec == NULL)
3126		return -ENOMEM;
3127
3128	err = vt1709_parse_auto_config(codec);
3129	if (err < 0) {
3130		via_free(codec);
3131		return err;
3132	} else if (!err) {
3133		printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3134		       "Using genenic mode...\n");
3135	}
3136
3137	spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
3138	spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3139
3140	spec->stream_name_analog = "VT1709 Analog";
3141	spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
3142	spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3143
3144	spec->stream_name_digital = "VT1709 Digital";
3145	spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3146	spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3147
3148
3149	if (!spec->adc_nids && spec->input_mux) {
3150		spec->adc_nids = vt1709_adc_nids;
3151		spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3152		get_mux_nids(codec);
3153		spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3154		spec->num_mixers++;
3155	}
3156
3157	codec->patch_ops = via_patch_ops;
3158
3159	codec->patch_ops.init = via_auto_init;
3160	codec->patch_ops.unsol_event = via_unsol_event;
3161#ifdef CONFIG_SND_HDA_POWER_SAVE
3162	spec->loopback.amplist = vt1709_loopbacks;
3163#endif
3164
3165	return 0;
3166}
3167/*
3168 * generic initialization of ADC, input mixers and output mixers
3169 */
3170static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
3171	/*
3172	 * Unmute ADC0-2 and set the default input to mic-in
3173	 */
3174	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3175	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3176	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3177
3178
3179	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3180	 * mixer widget
3181	 */
3182	/* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3183	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3184	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3185	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3186	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3187	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3188
3189	/*
3190	 * Set up output selector (0x1a, 0x1b, 0x29)
3191	 */
3192	/* set vol=0 to output mixers */
3193	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3194	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3195	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3196
3197	/*
3198	 *  Unmute PW3 and PW4
3199	 */
3200	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3201	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3202
3203	/* Set input of PW4 as MW0 */
3204	{0x20, AC_VERB_SET_CONNECT_SEL, 0},
3205	/* PW9 Output enable */
3206	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3207	{ }
3208};
3209
3210static int patch_vt1709_6ch(struct hda_codec *codec)
3211{
3212	struct via_spec *spec;
3213	int err;
3214
3215	/* create a codec specific record */
3216	spec = via_new_spec(codec);
3217	if (spec == NULL)
3218		return -ENOMEM;
3219
3220	err = vt1709_parse_auto_config(codec);
3221	if (err < 0) {
3222		via_free(codec);
3223		return err;
3224	} else if (!err) {
3225		printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3226		       "Using genenic mode...\n");
3227	}
3228
3229	spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
3230	spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3231
3232	spec->stream_name_analog = "VT1709 Analog";
3233	spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
3234	spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3235
3236	spec->stream_name_digital = "VT1709 Digital";
3237	spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3238	spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3239
3240
3241	if (!spec->adc_nids && spec->input_mux) {
3242		spec->adc_nids = vt1709_adc_nids;
3243		spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3244		get_mux_nids(codec);
3245		spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3246		spec->num_mixers++;
3247	}
3248
3249	codec->patch_ops = via_patch_ops;
3250
3251	codec->patch_ops.init = via_auto_init;
3252	codec->patch_ops.unsol_event = via_unsol_event;
3253#ifdef CONFIG_SND_HDA_POWER_SAVE
3254	spec->loopback.amplist = vt1709_loopbacks;
3255#endif
3256	return 0;
3257}
3258
3259/* capture mixer elements */
3260static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3261	HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3262	HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3263	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3264	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3265	{
3266		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3267		/* The multiple "Capture Source" controls confuse alsamixer
3268		 * So call somewhat different..
3269		 */
3270		/* .name = "Capture Source", */
3271		.name = "Input Source",
3272		.count = 1,
3273		.info = via_mux_enum_info,
3274		.get = via_mux_enum_get,
3275		.put = via_mux_enum_put,
3276	},
3277	{ } /* end */
3278};
3279/*
3280 * generic initialization of ADC, input mixers and output mixers
3281 */
3282static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3283	/*
3284	 * Unmute ADC0-1 and set the default input to mic-in
3285	 */
3286	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3287	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3288
3289
3290	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3291	 * mixer widget
3292	 */
3293	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3294	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3295	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3296	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3297	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3298	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3299
3300	/*
3301	 * Set up output mixers
3302	 */
3303	/* set vol=0 to output mixers */
3304	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3305	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3306	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3307
3308	/* Setup default input to PW4 */
3309	{0x1d, AC_VERB_SET_CONNECT_SEL, 0},
3310	/* PW9 Output enable */
3311	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3312	/* PW10 Input enable */
3313	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3314	{ }
3315};
3316
3317static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3318	/*
3319	 * Unmute ADC0-1 and set the default input to mic-in
3320	 */
3321	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3322	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3323
3324
3325	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3326	 * mixer widget
3327	 */
3328	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3329	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3330	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3331	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3332	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3333	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3334
3335	/*
3336	 * Set up output mixers
3337	 */
3338	/* set vol=0 to output mixers */
3339	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3340	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3341	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3342
3343	/* Setup default input of PW4 to MW0 */
3344	{0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3345	/* PW9 Output enable */
3346	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3347	/* PW10 Input enable */
3348	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3349	{ }
3350};
3351
3352static struct hda_verb vt1708B_uniwill_init_verbs[] = {
3353	{0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3354	 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3355	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3356	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3357	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3358	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3359	{0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3360	{0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3361	{0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3362	{ }
3363};
3364
3365static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3366			      struct hda_codec *codec,
3367			      struct snd_pcm_substream *substream)
3368{
3369	int idle = substream->pstr->substream_opened == 1
3370		&& substream->ref_count == 0;
3371
3372	analog_low_current_mode(codec, idle);
3373	return 0;
3374}
3375
3376static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3377	.substreams = 2,
3378	.channels_min = 2,
3379	.channels_max = 8,
3380	.nid = 0x10, /* NID to query formats and rates */
3381	.ops = {
3382		.open = via_playback_pcm_open,
3383		.prepare = via_playback_multi_pcm_prepare,
3384		.cleanup = via_playback_multi_pcm_cleanup,
3385		.close = via_pcm_open_close
3386	},
3387};
3388
3389static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3390	.substreams = 2,
3391	.channels_min = 2,
3392	.channels_max = 4,
3393	.nid = 0x10, /* NID to query formats and rates */
3394	.ops = {
3395		.open = via_playback_pcm_open,
3396		.prepare = via_playback_multi_pcm_prepare,
3397		.cleanup = via_playback_multi_pcm_cleanup
3398	},
3399};
3400
3401static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3402	.substreams = 2,
3403	.channels_min = 2,
3404	.channels_max = 2,
3405	.nid = 0x13, /* NID to query formats and rates */
3406	.ops = {
3407		.open = via_pcm_open_close,
3408		.prepare = via_capture_pcm_prepare,
3409		.cleanup = via_capture_pcm_cleanup,
3410		.close = via_pcm_open_close
3411	},
3412};
3413
3414static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3415	.substreams = 1,
3416	.channels_min = 2,
3417	.channels_max = 2,
3418	/* NID is set in via_build_pcms */
3419	.ops = {
3420		.open = via_dig_playback_pcm_open,
3421		.close = via_dig_playback_pcm_close,
3422		.prepare = via_dig_playback_pcm_prepare,
3423		.cleanup = via_dig_playback_pcm_cleanup
3424	},
3425};
3426
3427static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3428	.substreams = 1,
3429	.channels_min = 2,
3430	.channels_max = 2,
3431};
3432
3433/* fill in the dac_nids table from the parsed pin configuration */
3434static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3435				     const struct auto_pin_cfg *cfg)
3436{
3437	int i;
3438	hda_nid_t nid;
3439
3440	spec->multiout.num_dacs = cfg->line_outs;
3441
3442	spec->multiout.dac_nids = spec->private_dac_nids;
3443
3444	for (i = 0; i < 4; i++) {
3445		nid = cfg->line_out_pins[i];
3446		if (nid) {
3447			/* config dac list */
3448			switch (i) {
3449			case AUTO_SEQ_FRONT:
3450				spec->multiout.dac_nids[i] = 0x10;
3451				break;
3452			case AUTO_SEQ_CENLFE:
3453				spec->multiout.dac_nids[i] = 0x24;
3454				break;
3455			case AUTO_SEQ_SURROUND:
3456				spec->multiout.dac_nids[i] = 0x11;
3457				break;
3458			case AUTO_SEQ_SIDE:
3459				spec->multiout.dac_nids[i] = 0x25;
3460				break;
3461			}
3462		}
3463	}
3464
3465	return 0;
3466}
3467
3468/* add playback controls from the parsed DAC table */
3469static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3470					     const struct auto_pin_cfg *cfg)
3471{
3472	char name[32];
3473	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
3474	hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3475	hda_nid_t nid, nid_vol = 0;
3476	int i, err;
3477
3478	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3479		nid = cfg->line_out_pins[i];
3480
3481		if (!nid)
3482			continue;
3483
3484		nid_vol = nid_vols[i];
3485
3486		if (i == AUTO_SEQ_CENLFE) {
3487			/* Center/LFE */
3488			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3489					      "Center Playback Volume",
3490					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3491								  HDA_OUTPUT));
3492			if (err < 0)
3493				return err;
3494			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3495					      "LFE Playback Volume",
3496					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3497								  HDA_OUTPUT));
3498			if (err < 0)
3499				return err;
3500			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3501					      "Center Playback Switch",
3502					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3503								  HDA_OUTPUT));
3504			if (err < 0)
3505				return err;
3506			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3507					      "LFE Playback Switch",
3508					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3509								  HDA_OUTPUT));
3510			if (err < 0)
3511				return err;
3512		} else if (i == AUTO_SEQ_FRONT) {
3513			/* add control to mixer index 0 */
3514			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3515					      "Master Front Playback Volume",
3516					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3517								  HDA_INPUT));
3518			if (err < 0)
3519				return err;
3520			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3521					      "Master Front Playback Switch",
3522					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3523								  HDA_INPUT));
3524			if (err < 0)
3525				return err;
3526
3527			/* add control to PW3 */
3528			sprintf(name, "%s Playback Volume", chname[i]);
3529			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3530					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3531								  HDA_OUTPUT));
3532			if (err < 0)
3533				return err;
3534			sprintf(name, "%s Playback Switch", chname[i]);
3535			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3536					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3537								  HDA_OUTPUT));
3538			if (err < 0)
3539				return err;
3540		} else {
3541			sprintf(name, "%s Playback Volume", chname[i]);
3542			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3543					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3544								  HDA_OUTPUT));
3545			if (err < 0)
3546				return err;
3547			sprintf(name, "%s Playback Switch", chname[i]);
3548			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3549					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3550								  HDA_OUTPUT));
3551			if (err < 0)
3552				return err;
3553		}
3554	}
3555
3556	return 0;
3557}
3558
3559static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3560{
3561	int err;
3562
3563	if (!pin)
3564		return 0;
3565
3566	spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3567	spec->hp_independent_mode_index = 1;
3568
3569	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3570			      "Headphone Playback Volume",
3571			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3572	if (err < 0)
3573		return err;
3574	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3575			      "Headphone Playback Switch",
3576			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3577	if (err < 0)
3578		return err;
3579
3580	create_hp_imux(spec);
3581
3582	return 0;
3583}
3584
3585/* create playback/capture controls for input pins */
3586static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
3587						const struct auto_pin_cfg *cfg)
3588{
3589	static char *labels[] = {
3590		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
3591	};
3592	struct hda_input_mux *imux = &spec->private_imux[0];
3593	int i, err, idx = 0;
3594
3595	/* for internal loopback recording select */
3596	imux->items[imux->num_items].label = "Stereo Mixer";
3597	imux->items[imux->num_items].index = idx;
3598	imux->num_items++;
3599
3600	for (i = 0; i < AUTO_PIN_LAST; i++) {
3601		if (!cfg->input_pins[i])
3602			continue;
3603
3604		switch (cfg->input_pins[i]) {
3605		case 0x1a: /* Mic */
3606			idx = 2;
3607			break;
3608
3609		case 0x1b: /* Line In */
3610			idx = 3;
3611			break;
3612
3613		case 0x1e: /* Front Mic */
3614			idx = 4;
3615			break;
3616
3617		case 0x1f: /* CD */
3618			idx = 1;
3619			break;
3620		}
3621		err = via_new_analog_input(spec, labels[i], idx, 0x16);
3622		if (err < 0)
3623			return err;
3624		imux->items[imux->num_items].label = labels[i];
3625		imux->items[imux->num_items].index = idx;
3626		imux->num_items++;
3627	}
3628	return 0;
3629}
3630
3631static int vt1708B_parse_auto_config(struct hda_codec *codec)
3632{
3633	struct via_spec *spec = codec->spec;
3634	int err;
3635
3636	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3637	if (err < 0)
3638		return err;
3639	err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
3640	if (err < 0)
3641		return err;
3642	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3643		return 0; /* can't find valid BIOS pin config */
3644
3645	err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
3646	if (err < 0)
3647		return err;
3648	err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3649	if (err < 0)
3650		return err;
3651	err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
3652	if (err < 0)
3653		return err;
3654
3655	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3656
3657	if (spec->autocfg.dig_outs)
3658		spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
3659	spec->dig_in_pin = VT1708B_DIGIN_PIN;
3660	if (spec->autocfg.dig_in_pin)
3661		spec->dig_in_nid = VT1708B_DIGIN_NID;
3662
3663	if (spec->kctls.list)
3664		spec->mixers[spec->num_mixers++] = spec->kctls.list;
3665
3666	spec->input_mux = &spec->private_imux[0];
3667
3668	if (spec->hp_mux)
3669		via_hp_build(codec);
3670
3671	via_smart51_build(spec);
3672	return 1;
3673}
3674
3675#ifdef CONFIG_SND_HDA_POWER_SAVE
3676static struct hda_amp_list vt1708B_loopbacks[] = {
3677	{ 0x16, HDA_INPUT, 1 },
3678	{ 0x16, HDA_INPUT, 2 },
3679	{ 0x16, HDA_INPUT, 3 },
3680	{ 0x16, HDA_INPUT, 4 },
3681	{ } /* end */
3682};
3683#endif
3684static int patch_vt1708S(struct hda_codec *codec);
3685static int patch_vt1708B_8ch(struct hda_codec *codec)
3686{
3687	struct via_spec *spec;
3688	int err;
3689
3690	if (get_codec_type(codec) == VT1708BCE)
3691		return patch_vt1708S(codec);
3692	/* create a codec specific record */
3693	spec = via_new_spec(codec);
3694	if (spec == NULL)
3695		return -ENOMEM;
3696
3697	/* automatic parse from the BIOS config */
3698	err = vt1708B_parse_auto_config(codec);
3699	if (err < 0) {
3700		via_free(codec);
3701		return err;
3702	} else if (!err) {
3703		printk(KERN_INFO "hda_codec: Cannot set up configuration "
3704		       "from BIOS.  Using genenic mode...\n");
3705	}
3706
3707	spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
3708	spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3709
3710	spec->stream_name_analog = "VT1708B Analog";
3711	spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
3712	spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3713
3714	spec->stream_name_digital = "VT1708B Digital";
3715	spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3716	spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3717
3718	if (!spec->adc_nids && spec->input_mux) {
3719		spec->adc_nids = vt1708B_adc_nids;
3720		spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3721		get_mux_nids(codec);
3722		spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3723		spec->num_mixers++;
3724	}
3725
3726	codec->patch_ops = via_patch_ops;
3727
3728	codec->patch_ops.init = via_auto_init;
3729	codec->patch_ops.unsol_event = via_unsol_event;
3730#ifdef CONFIG_SND_HDA_POWER_SAVE
3731	spec->loopback.amplist = vt1708B_loopbacks;
3732#endif
3733
3734	return 0;
3735}
3736
3737static int patch_vt1708B_4ch(struct hda_codec *codec)
3738{
3739	struct via_spec *spec;
3740	int err;
3741
3742	/* create a codec specific record */
3743	spec = via_new_spec(codec);
3744	if (spec == NULL)
3745		return -ENOMEM;
3746
3747	/* automatic parse from the BIOS config */
3748	err = vt1708B_parse_auto_config(codec);
3749	if (err < 0) {
3750		via_free(codec);
3751		return err;
3752	} else if (!err) {
3753		printk(KERN_INFO "hda_codec: Cannot set up configuration "
3754		       "from BIOS.  Using genenic mode...\n");
3755	}
3756
3757	spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
3758	spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3759
3760	spec->stream_name_analog = "VT1708B Analog";
3761	spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
3762	spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3763
3764	spec->stream_name_digital = "VT1708B Digital";
3765	spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3766	spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3767
3768	if (!spec->adc_nids && spec->input_mux) {
3769		spec->adc_nids = vt1708B_adc_nids;
3770		spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3771		get_mux_nids(codec);
3772		spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3773		spec->num_mixers++;
3774	}
3775
3776	codec->patch_ops = via_patch_ops;
3777
3778	codec->patch_ops.init = via_auto_init;
3779	codec->patch_ops.unsol_event = via_unsol_event;
3780#ifdef CONFIG_SND_HDA_POWER_SAVE
3781	spec->loopback.amplist = vt1708B_loopbacks;
3782#endif
3783
3784	return 0;
3785}
3786
3787/* Patch for VT1708S */
3788
3789/* capture mixer elements */
3790static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3791	HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3792	HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3793	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3794	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3795	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
3796	HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3797			 HDA_INPUT),
3798	{
3799		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3800		/* The multiple "Capture Source" controls confuse alsamixer
3801		 * So call somewhat different..
3802		 */
3803		/* .name = "Capture Source", */
3804		.name = "Input Source",
3805		.count = 1,
3806		.info = via_mux_enum_info,
3807		.get = via_mux_enum_get,
3808		.put = via_mux_enum_put,
3809	},
3810	{ } /* end */
3811};
3812
3813static struct hda_verb vt1708S_volume_init_verbs[] = {
3814	/* Unmute ADC0-1 and set the default input to mic-in */
3815	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3816	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3817
3818	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
3819	 * analog-loopback mixer widget */
3820	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3821	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3822	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3823	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3824	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3825	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3826
3827	/* Setup default input of PW4 to MW0 */
3828	{0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3829	/* PW9, PW10  Output enable */
3830	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3831	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3832	/* Enable Mic Boost Volume backdoor */
3833	{0x1, 0xf98, 0x1},
3834	/* don't bybass mixer */
3835	{0x1, 0xf88, 0xc0},
3836	{ }
3837};
3838
3839static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3840	{0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3841	 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3842	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3843	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3844	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3845	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3846	{0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3847	{0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3848	{0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3849	{ }
3850};
3851
3852static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3853	.substreams = 2,
3854	.channels_min = 2,
3855	.channels_max = 8,
3856	.nid = 0x10, /* NID to query formats and rates */
3857	.ops = {
3858		.open = via_playback_pcm_open,
3859		.prepare = via_playback_multi_pcm_prepare,
3860		.cleanup = via_playback_multi_pcm_cleanup,
3861		.close = via_pcm_open_close
3862	},
3863};
3864
3865static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3866	.substreams = 2,
3867	.channels_min = 2,
3868	.channels_max = 2,
3869	.nid = 0x13, /* NID to query formats and rates */
3870	.ops = {
3871		.open = via_pcm_open_close,
3872		.prepare = via_capture_pcm_prepare,
3873		.cleanup = via_capture_pcm_cleanup,
3874		.close = via_pcm_open_close
3875	},
3876};
3877
3878static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3879	.substreams = 1,
3880	.channels_min = 2,
3881	.channels_max = 2,
3882	/* NID is set in via_build_pcms */
3883	.ops = {
3884		.open = via_dig_playback_pcm_open,
3885		.close = via_dig_playback_pcm_close,
3886		.prepare = via_dig_playback_pcm_prepare,
3887		.cleanup = via_dig_playback_pcm_cleanup
3888	},
3889};
3890
3891/* fill in the dac_nids table from the parsed pin configuration */
3892static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3893				     const struct auto_pin_cfg *cfg)
3894{
3895	int i;
3896	hda_nid_t nid;
3897
3898	spec->multiout.num_dacs = cfg->line_outs;
3899
3900	spec->multiout.dac_nids = spec->private_dac_nids;
3901
3902	for (i = 0; i < 4; i++) {
3903		nid = cfg->line_out_pins[i];
3904		if (nid) {
3905			/* config dac list */
3906			switch (i) {
3907			case AUTO_SEQ_FRONT:
3908				spec->multiout.dac_nids[i] = 0x10;
3909				break;
3910			case AUTO_SEQ_CENLFE:
3911				spec->multiout.dac_nids[i] = 0x24;
3912				break;
3913			case AUTO_SEQ_SURROUND:
3914				spec->multiout.dac_nids[i] = 0x11;
3915				break;
3916			case AUTO_SEQ_SIDE:
3917				spec->multiout.dac_nids[i] = 0x25;
3918				break;
3919			}
3920		}
3921	}
3922
3923	/* for Smart 5.1, line/mic inputs double as output pins */
3924	if (cfg->line_outs == 1) {
3925		spec->multiout.num_dacs = 3;
3926		spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3927		spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3928	}
3929
3930	return 0;
3931}
3932
3933/* add playback controls from the parsed DAC table */
3934static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3935					     const struct auto_pin_cfg *cfg)
3936{
3937	char name[32];
3938	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
3939	hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
3940	hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
3941	hda_nid_t nid, nid_vol, nid_mute;
3942	int i, err;
3943
3944	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3945		nid = cfg->line_out_pins[i];
3946
3947		/* for Smart 5.1, there are always at least six channels */
3948		if (!nid && i > AUTO_SEQ_CENLFE)
3949			continue;
3950
3951		nid_vol = nid_vols[i];
3952		nid_mute = nid_mutes[i];
3953
3954		if (i == AUTO_SEQ_CENLFE) {
3955			/* Center/LFE */
3956			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3957					      "Center Playback Volume",
3958					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3959								  HDA_OUTPUT));
3960			if (err < 0)
3961				return err;
3962			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3963					      "LFE Playback Volume",
3964					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3965								  HDA_OUTPUT));
3966			if (err < 0)
3967				return err;
3968			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3969					      "Center Playback Switch",
3970					      HDA_COMPOSE_AMP_VAL(nid_mute,
3971								  1, 0,
3972								  HDA_OUTPUT));
3973			if (err < 0)
3974				return err;
3975			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3976					      "LFE Playback Switch",
3977					      HDA_COMPOSE_AMP_VAL(nid_mute,
3978								  2, 0,
3979								  HDA_OUTPUT));
3980			if (err < 0)
3981				return err;
3982		} else if (i == AUTO_SEQ_FRONT) {
3983			/* add control to mixer index 0 */
3984			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3985					      "Master Front Playback Volume",
3986					      HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3987								  HDA_INPUT));
3988			if (err < 0)
3989				return err;
3990			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3991					      "Master Front Playback Switch",
3992					      HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3993								  HDA_INPUT));
3994			if (err < 0)
3995				return err;
3996
3997			/* Front */
3998			sprintf(name, "%s Playback Volume", chname[i]);
3999			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
4000					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
4001								  HDA_OUTPUT));
4002			if (err < 0)
4003				return err;
4004			sprintf(name, "%s Playback Switch", chname[i]);
4005			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
4006					      HDA_COMPOSE_AMP_VAL(nid_mute,
4007								  3, 0,
4008								  HDA_OUTPUT));
4009			if (err < 0)
4010				return err;
4011		} else {
4012			sprintf(name, "%s Playback Volume", chname[i]);
4013			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
4014					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
4015								  HDA_OUTPUT));
4016			if (err < 0)
4017				return err;
4018			sprintf(name, "%s Playback Switch", chname[i]);
4019			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
4020					      HDA_COMPOSE_AMP_VAL(nid_mute,
4021								  3, 0,
4022								  HDA_OUTPUT));
4023			if (err < 0)
4024				return err;
4025		}
4026	}
4027
4028	return 0;
4029}
4030
4031static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4032{
4033	int err;
4034
4035	if (!pin)
4036		return 0;
4037
4038	spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
4039	spec->hp_independent_mode_index = 1;
4040
4041	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4042			      "Headphone Playback Volume",
4043			      HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
4044	if (err < 0)
4045		return err;
4046
4047	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4048			      "Headphone Playback Switch",
4049			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4050	if (err < 0)
4051		return err;
4052
4053	create_hp_imux(spec);
4054
4055	return 0;
4056}
4057
4058/* create playback/capture controls for input pins */
4059static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
4060						const struct auto_pin_cfg *cfg)
4061{
4062	static char *labels[] = {
4063		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
4064	};
4065	struct hda_input_mux *imux = &spec->private_imux[0];
4066	int i, err, idx = 0;
4067
4068	/* for internal loopback recording select */
4069	imux->items[imux->num_items].label = "Stereo Mixer";
4070	imux->items[imux->num_items].index = 5;
4071	imux->num_items++;
4072
4073	for (i = 0; i < AUTO_PIN_LAST; i++) {
4074		if (!cfg->input_pins[i])
4075			continue;
4076
4077		switch (cfg->input_pins[i]) {
4078		case 0x1a: /* Mic */
4079			idx = 2;
4080			break;
4081
4082		case 0x1b: /* Line In */
4083			idx = 3;
4084			break;
4085
4086		case 0x1e: /* Front Mic */
4087			idx = 4;
4088			break;
4089
4090		case 0x1f: /* CD */
4091			idx = 1;
4092			break;
4093		}
4094		err = via_new_analog_input(spec, labels[i], idx, 0x16);
4095		if (err < 0)
4096			return err;
4097		imux->items[imux->num_items].label = labels[i];
4098		imux->items[imux->num_items].index = idx-1;
4099		imux->num_items++;
4100	}
4101	return 0;
4102}
4103
4104/* fill out digital output widgets; one for master and one for slave outputs */
4105static void fill_dig_outs(struct hda_codec *codec)
4106{
4107	struct via_spec *spec = codec->spec;
4108	int i;
4109
4110	for (i = 0; i < spec->autocfg.dig_outs; i++) {
4111		hda_nid_t nid;
4112		int conn;
4113
4114		nid = spec->autocfg.dig_out_pins[i];
4115		if (!nid)
4116			continue;
4117		conn = snd_hda_get_connections(codec, nid, &nid, 1);
4118		if (conn < 1)
4119			continue;
4120		if (!spec->multiout.dig_out_nid)
4121			spec->multiout.dig_out_nid = nid;
4122		else {
4123			spec->slave_dig_outs[0] = nid;
4124			break; /* at most two dig outs */
4125		}
4126	}
4127}
4128
4129static int vt1708S_parse_auto_config(struct hda_codec *codec)
4130{
4131	struct via_spec *spec = codec->spec;
4132	int err;
4133
4134	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4135	if (err < 0)
4136		return err;
4137	err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
4138	if (err < 0)
4139		return err;
4140	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4141		return 0; /* can't find valid BIOS pin config */
4142
4143	err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4144	if (err < 0)
4145		return err;
4146	err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4147	if (err < 0)
4148		return err;
4149	err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg);
4150	if (err < 0)
4151		return err;
4152
4153	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4154
4155	fill_dig_outs(codec);
4156
4157	if (spec->kctls.list)
4158		spec->mixers[spec->num_mixers++] = spec->kctls.list;
4159
4160	spec->input_mux = &spec->private_imux[0];
4161
4162	if (spec->hp_mux)
4163		via_hp_build(codec);
4164
4165	via_smart51_build(spec);
4166	return 1;
4167}
4168
4169#ifdef CONFIG_SND_HDA_POWER_SAVE
4170static struct hda_amp_list vt1708S_loopbacks[] = {
4171	{ 0x16, HDA_INPUT, 1 },
4172	{ 0x16, HDA_INPUT, 2 },
4173	{ 0x16, HDA_INPUT, 3 },
4174	{ 0x16, HDA_INPUT, 4 },
4175	{ } /* end */
4176};
4177#endif
4178
4179static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
4180			       int offset, int num_steps, int step_size)
4181{
4182	snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
4183				  (offset << AC_AMPCAP_OFFSET_SHIFT) |
4184				  (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
4185				  (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
4186				  (0 << AC_AMPCAP_MUTE_SHIFT));
4187}
4188
4189static int patch_vt1708S(struct hda_codec *codec)
4190{
4191	struct via_spec *spec;
4192	int err;
4193
4194	/* create a codec specific record */
4195	spec = via_new_spec(codec);
4196	if (spec == NULL)
4197		return -ENOMEM;
4198
4199	/* automatic parse from the BIOS config */
4200	err = vt1708S_parse_auto_config(codec);
4201	if (err < 0) {
4202		via_free(codec);
4203		return err;
4204	} else if (!err) {
4205		printk(KERN_INFO "hda_codec: Cannot set up configuration "
4206		       "from BIOS.  Using genenic mode...\n");
4207	}
4208
4209	spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
4210	spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
4211
4212	if (codec->vendor_id == 0x11060440)
4213		spec->stream_name_analog = "VT1818S Analog";
4214	else
4215		spec->stream_name_analog = "VT1708S Analog";
4216	spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
4217	spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
4218
4219	if (codec->vendor_id == 0x11060440)
4220		spec->stream_name_digital = "VT1818S Digital";
4221	else
4222		spec->stream_name_digital = "VT1708S Digital";
4223	spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
4224
4225	if (!spec->adc_nids && spec->input_mux) {
4226		spec->adc_nids = vt1708S_adc_nids;
4227		spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
4228		get_mux_nids(codec);
4229		override_mic_boost(codec, 0x1a, 0, 3, 40);
4230		override_mic_boost(codec, 0x1e, 0, 3, 40);
4231		spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
4232		spec->num_mixers++;
4233	}
4234
4235	codec->patch_ops = via_patch_ops;
4236
4237	codec->patch_ops.init = via_auto_init;
4238	codec->patch_ops.unsol_event = via_unsol_event;
4239#ifdef CONFIG_SND_HDA_POWER_SAVE
4240	spec->loopback.amplist = vt1708S_loopbacks;
4241#endif
4242
4243	/* correct names for VT1708BCE */
4244	if (get_codec_type(codec) == VT1708BCE)	{
4245		kfree(codec->chip_name);
4246		codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
4247		snprintf(codec->bus->card->mixername,
4248			 sizeof(codec->bus->card->mixername),
4249			 "%s %s", codec->vendor_name, codec->chip_name);
4250		spec->stream_name_analog = "VT1708BCE Analog";
4251		spec->stream_name_digital = "VT1708BCE Digital";
4252	}
4253	return 0;
4254}
4255
4256/* Patch for VT1702 */
4257
4258/* capture mixer elements */
4259static struct snd_kcontrol_new vt1702_capture_mixer[] = {
4260	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
4261	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
4262	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
4263	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
4264	HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
4265	HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
4266	HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
4267			 HDA_INPUT),
4268	{
4269		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4270		/* The multiple "Capture Source" controls confuse alsamixer
4271		 * So call somewhat different..
4272		 */
4273		/* .name = "Capture Source", */
4274		.name = "Input Source",
4275		.count = 1,
4276		.info = via_mux_enum_info,
4277		.get = via_mux_enum_get,
4278		.put = via_mux_enum_put,
4279	},
4280	{ } /* end */
4281};
4282
4283static struct hda_verb vt1702_volume_init_verbs[] = {
4284	/*
4285	 * Unmute ADC0-1 and set the default input to mic-in
4286	 */
4287	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4288	{0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4289	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4290
4291
4292	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4293	 * mixer widget
4294	 */
4295	/* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
4296	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4297	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4298	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4299	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4300	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4301
4302	/* Setup default input of PW4 to MW0 */
4303	{0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
4304	/* PW6 PW7 Output enable */
4305	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4306	{0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4307	/* mixer enable */
4308	{0x1, 0xF88, 0x3},
4309	/* GPIO 0~2 */
4310	{0x1, 0xF82, 0x3F},
4311	{ }
4312};
4313
4314static struct hda_verb vt1702_uniwill_init_verbs[] = {
4315	{0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
4316	 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4317	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4318	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4319	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4320	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4321	{ }
4322};
4323
4324static struct hda_pcm_stream vt1702_pcm_analog_playback = {
4325	.substreams = 2,
4326	.channels_min = 2,
4327	.channels_max = 2,
4328	.nid = 0x10, /* NID to query formats and rates */
4329	.ops = {
4330		.open = via_playback_pcm_open,
4331		.prepare = via_playback_multi_pcm_prepare,
4332		.cleanup = via_playback_multi_pcm_cleanup,
4333		.close = via_pcm_open_close
4334	},
4335};
4336
4337static struct hda_pcm_stream vt1702_pcm_analog_capture = {
4338	.substreams = 3,
4339	.channels_min = 2,
4340	.channels_max = 2,
4341	.nid = 0x12, /* NID to query formats and rates */
4342	.ops = {
4343		.open = via_pcm_open_close,
4344		.prepare = via_capture_pcm_prepare,
4345		.cleanup = via_capture_pcm_cleanup,
4346		.close = via_pcm_open_close
4347	},
4348};
4349
4350static struct hda_pcm_stream vt1702_pcm_digital_playback = {
4351	.substreams = 2,
4352	.channels_min = 2,
4353	.channels_max = 2,
4354	/* NID is set in via_build_pcms */
4355	.ops = {
4356		.open = via_dig_playback_pcm_open,
4357		.close = via_dig_playback_pcm_close,
4358		.prepare = via_dig_playback_pcm_prepare,
4359		.cleanup = via_dig_playback_pcm_cleanup
4360	},
4361};
4362
4363/* fill in the dac_nids table from the parsed pin configuration */
4364static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
4365				     const struct auto_pin_cfg *cfg)
4366{
4367	spec->multiout.num_dacs = 1;
4368	spec->multiout.dac_nids = spec->private_dac_nids;
4369
4370	if (cfg->line_out_pins[0]) {
4371		/* config dac list */
4372		spec->multiout.dac_nids[0] = 0x10;
4373	}
4374
4375	return 0;
4376}
4377
4378/* add playback controls from the parsed DAC table */
4379static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
4380					     const struct auto_pin_cfg *cfg)
4381{
4382	int err;
4383
4384	if (!cfg->line_out_pins[0])
4385		return -1;
4386
4387	/* add control to mixer index 0 */
4388	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4389			      "Master Front Playback Volume",
4390			      HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4391	if (err < 0)
4392		return err;
4393	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4394			      "Master Front Playback Switch",
4395			      HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4396	if (err < 0)
4397		return err;
4398
4399	/* Front */
4400	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4401			      "Front Playback Volume",
4402			      HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
4403	if (err < 0)
4404		return err;
4405	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4406			      "Front Playback Switch",
4407			      HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
4408	if (err < 0)
4409		return err;
4410
4411	return 0;
4412}
4413
4414static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4415{
4416	int err, i;
4417	struct hda_input_mux *imux;
4418	static const char *texts[] = { "ON", "OFF", NULL};
4419	if (!pin)
4420		return 0;
4421	spec->multiout.hp_nid = 0x1D;
4422	spec->hp_independent_mode_index = 0;
4423
4424	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4425			      "Headphone Playback Volume",
4426			      HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
4427	if (err < 0)
4428		return err;
4429
4430	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4431			      "Headphone Playback Switch",
4432			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4433	if (err < 0)
4434		return err;
4435
4436	imux = &spec->private_imux[1];
4437
4438	/* for hp mode select */
4439	i = 0;
4440	while (texts[i] != NULL)	{
4441		imux->items[imux->num_items].label =  texts[i];
4442		imux->items[imux->num_items].index = i;
4443		imux->num_items++;
4444		i++;
4445	}
4446
4447	spec->hp_mux = &spec->private_imux[1];
4448	return 0;
4449}
4450
4451/* create playback/capture controls for input pins */
4452static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
4453						const struct auto_pin_cfg *cfg)
4454{
4455	static char *labels[] = {
4456		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
4457	};
4458	struct hda_input_mux *imux = &spec->private_imux[0];
4459	int i, err, idx = 0;
4460
4461	/* for internal loopback recording select */
4462	imux->items[imux->num_items].label = "Stereo Mixer";
4463	imux->items[imux->num_items].index = 3;
4464	imux->num_items++;
4465
4466	for (i = 0; i < AUTO_PIN_LAST; i++) {
4467		if (!cfg->input_pins[i])
4468			continue;
4469
4470		switch (cfg->input_pins[i]) {
4471		case 0x14: /* Mic */
4472			idx = 1;
4473			break;
4474
4475		case 0x15: /* Line In */
4476			idx = 2;
4477			break;
4478
4479		case 0x18: /* Front Mic */
4480			idx = 3;
4481			break;
4482		}
4483		err = via_new_analog_input(spec, labels[i], idx, 0x1A);
4484		if (err < 0)
4485			return err;
4486		imux->items[imux->num_items].label = labels[i];
4487		imux->items[imux->num_items].index = idx-1;
4488		imux->num_items++;
4489	}
4490	return 0;
4491}
4492
4493static int vt1702_parse_auto_config(struct hda_codec *codec)
4494{
4495	struct via_spec *spec = codec->spec;
4496	int err;
4497
4498	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4499	if (err < 0)
4500		return err;
4501	err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
4502	if (err < 0)
4503		return err;
4504	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4505		return 0; /* can't find valid BIOS pin config */
4506
4507	err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
4508	if (err < 0)
4509		return err;
4510	err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4511	if (err < 0)
4512		return err;
4513	/* limit AA path volume to 0 dB */
4514	snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
4515				  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4516				  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4517				  (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4518				  (1 << AC_AMPCAP_MUTE_SHIFT));
4519	err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
4520	if (err < 0)
4521		return err;
4522
4523	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4524
4525	fill_dig_outs(codec);
4526
4527	if (spec->kctls.list)
4528		spec->mixers[spec->num_mixers++] = spec->kctls.list;
4529
4530	spec->input_mux = &spec->private_imux[0];
4531
4532	if (spec->hp_mux)
4533		via_hp_build(codec);
4534
4535	return 1;
4536}
4537
4538#ifdef CONFIG_SND_HDA_POWER_SAVE
4539static struct hda_amp_list vt1702_loopbacks[] = {
4540	{ 0x1A, HDA_INPUT, 1 },
4541	{ 0x1A, HDA_INPUT, 2 },
4542	{ 0x1A, HDA_INPUT, 3 },
4543	{ 0x1A, HDA_INPUT, 4 },
4544	{ } /* end */
4545};
4546#endif
4547
4548static int patch_vt1702(struct hda_codec *codec)
4549{
4550	struct via_spec *spec;
4551	int err;
4552
4553	/* create a codec specific record */
4554	spec = via_new_spec(codec);
4555	if (spec == NULL)
4556		return -ENOMEM;
4557
4558	/* automatic parse from the BIOS config */
4559	err = vt1702_parse_auto_config(codec);
4560	if (err < 0) {
4561		via_free(codec);
4562		return err;
4563	} else if (!err) {
4564		printk(KERN_INFO "hda_codec: Cannot set up configuration "
4565		       "from BIOS.  Using genenic mode...\n");
4566	}
4567
4568	spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
4569	spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
4570
4571	spec->stream_name_analog = "VT1702 Analog";
4572	spec->stream_analog_playback = &vt1702_pcm_analog_playback;
4573	spec->stream_analog_capture = &vt1702_pcm_analog_capture;
4574
4575	spec->stream_name_digital = "VT1702 Digital";
4576	spec->stream_digital_playback = &vt1702_pcm_digital_playback;
4577
4578	if (!spec->adc_nids && spec->input_mux) {
4579		spec->adc_nids = vt1702_adc_nids;
4580		spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
4581		get_mux_nids(codec);
4582		spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
4583		spec->num_mixers++;
4584	}
4585
4586	codec->patch_ops = via_patch_ops;
4587
4588	codec->patch_ops.init = via_auto_init;
4589	codec->patch_ops.unsol_event = via_unsol_event;
4590#ifdef CONFIG_SND_HDA_POWER_SAVE
4591	spec->loopback.amplist = vt1702_loopbacks;
4592#endif
4593
4594	return 0;
4595}
4596
4597/* Patch for VT1718S */
4598
4599/* capture mixer elements */
4600static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4601	HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4602	HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4603	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
4604	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
4605	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
4606	HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
4607			 HDA_INPUT),
4608	{
4609		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4610		/* The multiple "Capture Source" controls confuse alsamixer
4611		 * So call somewhat different..
4612		 */
4613		.name = "Input Source",
4614		.count = 2,
4615		.info = via_mux_enum_info,
4616		.get = via_mux_enum_get,
4617		.put = via_mux_enum_put,
4618	},
4619	{ } /* end */
4620};
4621
4622static struct hda_verb vt1718S_volume_init_verbs[] = {
4623	/*
4624	 * Unmute ADC0-1 and set the default input to mic-in
4625	 */
4626	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4627	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4628
4629
4630	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4631	 * mixer widget
4632	 */
4633	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4634	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4635	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4636	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4637	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4638	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4639
4640	/* Setup default input of Front HP to MW9 */
4641	{0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4642	/* PW9 PW10 Output enable */
4643	{0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4644	{0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4645	/* PW11 Input enable */
4646	{0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN},
4647	/* Enable Boost Volume backdoor */
4648	{0x1, 0xf88, 0x8},
4649	/* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4650	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4651	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4652	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4653	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4654	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4655	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4656	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4657	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4658	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4659	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4660	/* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4661	{0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4662	{0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4663	/* Unmute MW4's index 0 */
4664	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4665	{ }
4666};
4667
4668
4669static struct hda_verb vt1718S_uniwill_init_verbs[] = {
4670	{0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4671	 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4672	{0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4673	{0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4674	{0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4675	{0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4676	{0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4677	{0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4678	{0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4679	{ }
4680};
4681
4682static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4683	.substreams = 2,
4684	.channels_min = 2,
4685	.channels_max = 10,
4686	.nid = 0x8, /* NID to query formats and rates */
4687	.ops = {
4688		.open = via_playback_pcm_open,
4689		.prepare = via_playback_multi_pcm_prepare,
4690		.cleanup = via_playback_multi_pcm_cleanup,
4691		.close = via_pcm_open_close,
4692	},
4693};
4694
4695static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4696	.substreams = 2,
4697	.channels_min = 2,
4698	.channels_max = 2,
4699	.nid = 0x10, /* NID to query formats and rates */
4700	.ops = {
4701		.open = via_pcm_open_close,
4702		.prepare = via_capture_pcm_prepare,
4703		.cleanup = via_capture_pcm_cleanup,
4704		.close = via_pcm_open_close,
4705	},
4706};
4707
4708static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4709	.substreams = 2,
4710	.channels_min = 2,
4711	.channels_max = 2,
4712	/* NID is set in via_build_pcms */
4713	.ops = {
4714		.open = via_dig_playback_pcm_open,
4715		.close = via_dig_playback_pcm_close,
4716		.prepare = via_dig_playback_pcm_prepare,
4717		.cleanup = via_dig_playback_pcm_cleanup
4718	},
4719};
4720
4721static struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4722	.substreams = 1,
4723	.channels_min = 2,
4724	.channels_max = 2,
4725};
4726
4727/* fill in the dac_nids table from the parsed pin configuration */
4728static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4729				     const struct auto_pin_cfg *cfg)
4730{
4731	int i;
4732	hda_nid_t nid;
4733
4734	spec->multiout.num_dacs = cfg->line_outs;
4735
4736	spec->multiout.dac_nids = spec->private_dac_nids;
4737
4738	for (i = 0; i < 4; i++) {
4739		nid = cfg->line_out_pins[i];
4740		if (nid) {
4741			/* config dac list */
4742			switch (i) {
4743			case AUTO_SEQ_FRONT:
4744				spec->multiout.dac_nids[i] = 0x8;
4745				break;
4746			case AUTO_SEQ_CENLFE:
4747				spec->multiout.dac_nids[i] = 0xa;
4748				break;
4749			case AUTO_SEQ_SURROUND:
4750				spec->multiout.dac_nids[i] = 0x9;
4751				break;
4752			case AUTO_SEQ_SIDE:
4753				spec->multiout.dac_nids[i] = 0xb;
4754				break;
4755			}
4756		}
4757	}
4758
4759	return 0;
4760}
4761
4762/* add playback controls from the parsed DAC table */
4763static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4764					     const struct auto_pin_cfg *cfg)
4765{
4766	char name[32];
4767	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
4768	hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4769	hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4770	hda_nid_t nid, nid_vol, nid_mute = 0;
4771	int i, err;
4772
4773	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
4774		nid = cfg->line_out_pins[i];
4775
4776		if (!nid)
4777			continue;
4778		nid_vol = nid_vols[i];
4779		nid_mute = nid_mutes[i];
4780
4781		if (i == AUTO_SEQ_CENLFE) {
4782			/* Center/LFE */
4783			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4784					      "Center Playback Volume",
4785					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
4786								  HDA_OUTPUT));
4787			if (err < 0)
4788				return err;
4789			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4790					      "LFE Playback Volume",
4791					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
4792								  HDA_OUTPUT));
4793			if (err < 0)
4794				return err;
4795			err = via_add_control(
4796				spec, VIA_CTL_WIDGET_MUTE,
4797				"Center Playback Switch",
4798				HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4799						    HDA_OUTPUT));
4800			if (err < 0)
4801				return err;
4802			err = via_add_control(
4803				spec, VIA_CTL_WIDGET_MUTE,
4804				"LFE Playback Switch",
4805				HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4806						    HDA_OUTPUT));
4807			if (err < 0)
4808				return err;
4809		} else if (i == AUTO_SEQ_FRONT) {
4810			/* Front */
4811			sprintf(name, "%s Playback Volume", chname[i]);
4812			err = via_add_control(
4813				spec, VIA_CTL_WIDGET_VOL, name,
4814				HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4815			if (err < 0)
4816				return err;
4817			sprintf(name, "%s Playback Switch", chname[i]);
4818			err = via_add_control(
4819				spec, VIA_CTL_WIDGET_MUTE, name,
4820				HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4821						    HDA_OUTPUT));
4822			if (err < 0)
4823				return err;
4824		} else {
4825			sprintf(name, "%s Playback Volume", chname[i]);
4826			err = via_add_control(
4827				spec, VIA_CTL_WIDGET_VOL, name,
4828				HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4829			if (err < 0)
4830				return err;
4831			sprintf(name, "%s Playback Switch", chname[i]);
4832			err = via_add_control(
4833				spec, VIA_CTL_WIDGET_MUTE, name,
4834				HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4835						    HDA_OUTPUT));
4836			if (err < 0)
4837				return err;
4838		}
4839	}
4840	return 0;
4841}
4842
4843static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4844{
4845	int err;
4846
4847	if (!pin)
4848		return 0;
4849
4850	spec->multiout.hp_nid = 0xc; /* AOW4 */
4851	spec->hp_independent_mode_index = 1;
4852
4853	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4854			      "Headphone Playback Volume",
4855			      HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT));
4856	if (err < 0)
4857		return err;
4858
4859	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4860			      "Headphone Playback Switch",
4861			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4862	if (err < 0)
4863		return err;
4864
4865	create_hp_imux(spec);
4866	return 0;
4867}
4868
4869/* create playback/capture controls for input pins */
4870static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec,
4871						const struct auto_pin_cfg *cfg)
4872{
4873	static char *labels[] = {
4874		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
4875	};
4876	struct hda_input_mux *imux = &spec->private_imux[0];
4877	int i, err, idx = 0;
4878
4879	/* for internal loopback recording select */
4880	imux->items[imux->num_items].label = "Stereo Mixer";
4881	imux->items[imux->num_items].index = 5;
4882	imux->num_items++;
4883
4884	for (i = 0; i < AUTO_PIN_LAST; i++) {
4885		if (!cfg->input_pins[i])
4886			continue;
4887
4888		switch (cfg->input_pins[i]) {
4889		case 0x2b: /* Mic */
4890			idx = 1;
4891			break;
4892
4893		case 0x2a: /* Line In */
4894			idx = 2;
4895			break;
4896
4897		case 0x29: /* Front Mic */
4898			idx = 3;
4899			break;
4900
4901		case 0x2c: /* CD */
4902			idx = 0;
4903			break;
4904		}
4905		err = via_new_analog_input(spec, labels[i], idx, 0x21);
4906		if (err < 0)
4907			return err;
4908		imux->items[imux->num_items].label = labels[i];
4909		imux->items[imux->num_items].index = idx;
4910		imux->num_items++;
4911	}
4912	return 0;
4913}
4914
4915static int vt1718S_parse_auto_config(struct hda_codec *codec)
4916{
4917	struct via_spec *spec = codec->spec;
4918	int err;
4919
4920	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4921
4922	if (err < 0)
4923		return err;
4924	err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg);
4925	if (err < 0)
4926		return err;
4927	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4928		return 0; /* can't find valid BIOS pin config */
4929
4930	err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4931	if (err < 0)
4932		return err;
4933	err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4934	if (err < 0)
4935		return err;
4936	err = vt1718S_auto_create_analog_input_ctls(spec, &spec->autocfg);
4937	if (err < 0)
4938		return err;
4939
4940	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4941
4942	fill_dig_outs(codec);
4943
4944	if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428)
4945		spec->dig_in_nid = 0x13;
4946
4947	if (spec->kctls.list)
4948		spec->mixers[spec->num_mixers++] = spec->kctls.list;
4949
4950	spec->input_mux = &spec->private_imux[0];
4951
4952	if (spec->hp_mux)
4953		via_hp_build(codec);
4954
4955	via_smart51_build(spec);
4956
4957	return 1;
4958}
4959
4960#ifdef CONFIG_SND_HDA_POWER_SAVE
4961static struct hda_amp_list vt1718S_loopbacks[] = {
4962	{ 0x21, HDA_INPUT, 1 },
4963	{ 0x21, HDA_INPUT, 2 },
4964	{ 0x21, HDA_INPUT, 3 },
4965	{ 0x21, HDA_INPUT, 4 },
4966	{ } /* end */
4967};
4968#endif
4969
4970static int patch_vt1718S(struct hda_codec *codec)
4971{
4972	struct via_spec *spec;
4973	int err;
4974
4975	/* create a codec specific record */
4976	spec = via_new_spec(codec);
4977	if (spec == NULL)
4978		return -ENOMEM;
4979
4980	/* automatic parse from the BIOS config */
4981	err = vt1718S_parse_auto_config(codec);
4982	if (err < 0) {
4983		via_free(codec);
4984		return err;
4985	} else if (!err) {
4986		printk(KERN_INFO "hda_codec: Cannot set up configuration "
4987		       "from BIOS.  Using genenic mode...\n");
4988	}
4989
4990	spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs;
4991	spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs;
4992
4993	if (codec->vendor_id == 0x11060441)
4994		spec->stream_name_analog = "VT2020 Analog";
4995	else if (codec->vendor_id == 0x11064441)
4996		spec->stream_name_analog = "VT1828S Analog";
4997	else
4998		spec->stream_name_analog = "VT1718S Analog";
4999	spec->stream_analog_playback = &vt1718S_pcm_analog_playback;
5000	spec->stream_analog_capture = &vt1718S_pcm_analog_capture;
5001
5002	if (codec->vendor_id == 0x11060441)
5003		spec->stream_name_digital = "VT2020 Digital";
5004	else if (codec->vendor_id == 0x11064441)
5005		spec->stream_name_digital = "VT1828S Digital";
5006	else
5007		spec->stream_name_digital = "VT1718S Digital";
5008	spec->stream_digital_playback = &vt1718S_pcm_digital_playback;
5009	if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441)
5010		spec->stream_digital_capture = &vt1718S_pcm_digital_capture;
5011
5012	if (!spec->adc_nids && spec->input_mux) {
5013		spec->adc_nids = vt1718S_adc_nids;
5014		spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
5015		get_mux_nids(codec);
5016		override_mic_boost(codec, 0x2b, 0, 3, 40);
5017		override_mic_boost(codec, 0x29, 0, 3, 40);
5018		spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
5019		spec->num_mixers++;
5020	}
5021
5022	codec->patch_ops = via_patch_ops;
5023
5024	codec->patch_ops.init = via_auto_init;
5025	codec->patch_ops.unsol_event = via_unsol_event;
5026
5027#ifdef CONFIG_SND_HDA_POWER_SAVE
5028	spec->loopback.amplist = vt1718S_loopbacks;
5029#endif
5030
5031	return 0;
5032}
5033
5034/* Patch for VT1716S */
5035
5036static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
5037			    struct snd_ctl_elem_info *uinfo)
5038{
5039	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
5040	uinfo->count = 1;
5041	uinfo->value.integer.min = 0;
5042	uinfo->value.integer.max = 1;
5043	return 0;
5044}
5045
5046static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
5047			   struct snd_ctl_elem_value *ucontrol)
5048{
5049	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5050	int index = 0;
5051
5052	index = snd_hda_codec_read(codec, 0x26, 0,
5053					       AC_VERB_GET_CONNECT_SEL, 0);
5054	if (index != -1)
5055		*ucontrol->value.integer.value = index;
5056
5057	return 0;
5058}
5059
5060static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
5061			   struct snd_ctl_elem_value *ucontrol)
5062{
5063	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5064	struct via_spec *spec = codec->spec;
5065	int index = *ucontrol->value.integer.value;
5066
5067	snd_hda_codec_write(codec, 0x26, 0,
5068					       AC_VERB_SET_CONNECT_SEL, index);
5069	spec->dmic_enabled = index;
5070	set_jack_power_state(codec);
5071
5072	return 1;
5073}
5074
5075/* capture mixer elements */
5076static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
5077	HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
5078	HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
5079	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
5080	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
5081	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
5082	HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
5083			 HDA_INPUT),
5084	{
5085		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5086		.name = "Input Source",
5087		.count = 1,
5088		.info = via_mux_enum_info,
5089		.get = via_mux_enum_get,
5090		.put = via_mux_enum_put,
5091	},
5092	{ } /* end */
5093};
5094
5095static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5096	HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
5097	{
5098	 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5099	 .name = "Digital Mic Capture Switch",
5100	 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
5101	 .count = 1,
5102	 .info = vt1716s_dmic_info,
5103	 .get = vt1716s_dmic_get,
5104	 .put = vt1716s_dmic_put,
5105	 },
5106	{}			/* end */
5107};
5108
5109
5110/* mono-out mixer elements */
5111static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
5112	HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
5113	{ } /* end */
5114};
5115
5116static struct hda_verb vt1716S_volume_init_verbs[] = {
5117	/*
5118	 * Unmute ADC0-1 and set the default input to mic-in
5119	 */
5120	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5121	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5122
5123
5124	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5125	 * mixer widget
5126	 */
5127	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5128	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5129	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5130	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5131	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5132	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5133
5134	/* MUX Indices: Stereo Mixer = 5 */
5135	{0x17, AC_VERB_SET_CONNECT_SEL, 0x5},
5136
5137	/* Setup default input of PW4 to MW0 */
5138	{0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
5139
5140	/* Setup default input of SW1 as MW0 */
5141	{0x18, AC_VERB_SET_CONNECT_SEL, 0x1},
5142
5143	/* Setup default input of SW4 as AOW0 */
5144	{0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
5145
5146	/* PW9 PW10 Output enable */
5147	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5148	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5149
5150	/* Unmute SW1, PW12 */
5151	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5152	{0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5153	/* PW12 Output enable */
5154	{0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5155	/* Enable Boost Volume backdoor */
5156	{0x1, 0xf8a, 0x80},
5157	/* don't bybass mixer */
5158	{0x1, 0xf88, 0xc0},
5159	/* Enable mono output */
5160	{0x1, 0xf90, 0x08},
5161	{ }
5162};
5163
5164
5165static struct hda_verb vt1716S_uniwill_init_verbs[] = {
5166	{0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
5167	 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
5168	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5169	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5170	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5171	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE,
5172	 AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT},
5173	{0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5174	{0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5175	{ }
5176};
5177
5178static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5179	.substreams = 2,
5180	.channels_min = 2,
5181	.channels_max = 6,
5182	.nid = 0x10, /* NID to query formats and rates */
5183	.ops = {
5184		.open = via_playback_pcm_open,
5185		.prepare = via_playback_multi_pcm_prepare,
5186		.cleanup = via_playback_multi_pcm_cleanup,
5187		.close = via_pcm_open_close,
5188	},
5189};
5190
5191static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5192	.substreams = 2,
5193	.channels_min = 2,
5194	.channels_max = 2,
5195	.nid = 0x13, /* NID to query formats and rates */
5196	.ops = {
5197		.open = via_pcm_open_close,
5198		.prepare = via_capture_pcm_prepare,
5199		.cleanup = via_capture_pcm_cleanup,
5200		.close = via_pcm_open_close,
5201	},
5202};
5203
5204static struct hda_pcm_stream vt1716S_pcm_digital_playback = {
5205	.substreams = 2,
5206	.channels_min = 2,
5207	.channels_max = 2,
5208	/* NID is set in via_build_pcms */
5209	.ops = {
5210		.open = via_dig_playback_pcm_open,
5211		.close = via_dig_playback_pcm_close,
5212		.prepare = via_dig_playback_pcm_prepare,
5213		.cleanup = via_dig_playback_pcm_cleanup
5214	},
5215};
5216
5217/* fill in the dac_nids table from the parsed pin configuration */
5218static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
5219				      const struct auto_pin_cfg *cfg)
5220{	int i;
5221	hda_nid_t nid;
5222
5223	spec->multiout.num_dacs = cfg->line_outs;
5224
5225	spec->multiout.dac_nids = spec->private_dac_nids;
5226
5227	for (i = 0; i < 3; i++) {
5228		nid = cfg->line_out_pins[i];
5229		if (nid) {
5230			/* config dac list */
5231			switch (i) {
5232			case AUTO_SEQ_FRONT:
5233				spec->multiout.dac_nids[i] = 0x10;
5234				break;
5235			case AUTO_SEQ_CENLFE:
5236				spec->multiout.dac_nids[i] = 0x25;
5237				break;
5238			case AUTO_SEQ_SURROUND:
5239				spec->multiout.dac_nids[i] = 0x11;
5240				break;
5241			}
5242		}
5243	}
5244
5245	return 0;
5246}
5247
5248/* add playback controls from the parsed DAC table */
5249static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
5250					      const struct auto_pin_cfg *cfg)
5251{
5252	char name[32];
5253	static const char *chname[3] = { "Front", "Surround", "C/LFE" };
5254	hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
5255	hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
5256	hda_nid_t nid, nid_vol, nid_mute;
5257	int i, err;
5258
5259	for (i = 0; i <= AUTO_SEQ_CENLFE; i++) {
5260		nid = cfg->line_out_pins[i];
5261
5262		if (!nid)
5263			continue;
5264
5265		nid_vol = nid_vols[i];
5266		nid_mute = nid_mutes[i];
5267
5268		if (i == AUTO_SEQ_CENLFE) {
5269			err = via_add_control(
5270				spec, VIA_CTL_WIDGET_VOL,
5271				"Center Playback Volume",
5272				HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
5273			if (err < 0)
5274				return err;
5275			err = via_add_control(
5276				spec, VIA_CTL_WIDGET_VOL,
5277				"LFE Playback Volume",
5278				HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
5279			if (err < 0)
5280				return err;
5281			err = via_add_control(
5282				spec, VIA_CTL_WIDGET_MUTE,
5283				"Center Playback Switch",
5284				HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
5285						    HDA_OUTPUT));
5286			if (err < 0)
5287				return err;
5288			err = via_add_control(
5289				spec, VIA_CTL_WIDGET_MUTE,
5290				"LFE Playback Switch",
5291				HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
5292						    HDA_OUTPUT));
5293			if (err < 0)
5294				return err;
5295		} else if (i == AUTO_SEQ_FRONT) {
5296
5297			err = via_add_control(
5298				spec, VIA_CTL_WIDGET_VOL,
5299				"Master Front Playback Volume",
5300				HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5301			if (err < 0)
5302				return err;
5303			err = via_add_control(
5304				spec, VIA_CTL_WIDGET_MUTE,
5305				"Master Front Playback Switch",
5306				HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5307			if (err < 0)
5308				return err;
5309
5310			sprintf(name, "%s Playback Volume", chname[i]);
5311			err = via_add_control(
5312				spec, VIA_CTL_WIDGET_VOL, name,
5313				HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5314			if (err < 0)
5315				return err;
5316			sprintf(name, "%s Playback Switch", chname[i]);
5317			err = via_add_control(
5318				spec, VIA_CTL_WIDGET_MUTE, name,
5319				HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5320						    HDA_OUTPUT));
5321			if (err < 0)
5322				return err;
5323		} else {
5324			sprintf(name, "%s Playback Volume", chname[i]);
5325			err = via_add_control(
5326				spec, VIA_CTL_WIDGET_VOL, name,
5327				HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5328			if (err < 0)
5329				return err;
5330			sprintf(name, "%s Playback Switch", chname[i]);
5331			err = via_add_control(
5332				spec, VIA_CTL_WIDGET_MUTE, name,
5333				HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5334						    HDA_OUTPUT));
5335			if (err < 0)
5336				return err;
5337		}
5338	}
5339	return 0;
5340}
5341
5342static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5343{
5344	int err;
5345
5346	if (!pin)
5347		return 0;
5348
5349	spec->multiout.hp_nid = 0x25; /* AOW3 */
5350	spec->hp_independent_mode_index = 1;
5351
5352	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5353			      "Headphone Playback Volume",
5354			      HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5355	if (err < 0)
5356		return err;
5357
5358	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5359			      "Headphone Playback Switch",
5360			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5361	if (err < 0)
5362		return err;
5363
5364	create_hp_imux(spec);
5365	return 0;
5366}
5367
5368/* create playback/capture controls for input pins */
5369static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec,
5370						const struct auto_pin_cfg *cfg)
5371{
5372	static char *labels[] = {
5373		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
5374	};
5375	struct hda_input_mux *imux = &spec->private_imux[0];
5376	int i, err, idx = 0;
5377
5378	/* for internal loopback recording select */
5379	imux->items[imux->num_items].label = "Stereo Mixer";
5380	imux->items[imux->num_items].index = 5;
5381	imux->num_items++;
5382
5383	for (i = 0; i < AUTO_PIN_LAST; i++) {
5384		if (!cfg->input_pins[i])
5385			continue;
5386
5387		switch (cfg->input_pins[i]) {
5388		case 0x1a: /* Mic */
5389			idx = 2;
5390			break;
5391
5392		case 0x1b: /* Line In */
5393			idx = 3;
5394			break;
5395
5396		case 0x1e: /* Front Mic */
5397			idx = 4;
5398			break;
5399
5400		case 0x1f: /* CD */
5401			idx = 1;
5402			break;
5403		}
5404		err = via_new_analog_input(spec, labels[i], idx, 0x16);
5405		if (err < 0)
5406			return err;
5407		imux->items[imux->num_items].label = labels[i];
5408		imux->items[imux->num_items].index = idx-1;
5409		imux->num_items++;
5410	}
5411	return 0;
5412}
5413
5414static int vt1716S_parse_auto_config(struct hda_codec *codec)
5415{
5416	struct via_spec *spec = codec->spec;
5417	int err;
5418
5419	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5420	if (err < 0)
5421		return err;
5422	err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg);
5423	if (err < 0)
5424		return err;
5425	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5426		return 0; /* can't find valid BIOS pin config */
5427
5428	err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg);
5429	if (err < 0)
5430		return err;
5431	err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5432	if (err < 0)
5433		return err;
5434	err = vt1716S_auto_create_analog_input_ctls(spec, &spec->autocfg);
5435	if (err < 0)
5436		return err;
5437
5438	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5439
5440	fill_dig_outs(codec);
5441
5442	if (spec->kctls.list)
5443		spec->mixers[spec->num_mixers++] = spec->kctls.list;
5444
5445	spec->input_mux = &spec->private_imux[0];
5446
5447	if (spec->hp_mux)
5448		via_hp_build(codec);
5449
5450	via_smart51_build(spec);
5451
5452	return 1;
5453}
5454
5455#ifdef CONFIG_SND_HDA_POWER_SAVE
5456static struct hda_amp_list vt1716S_loopbacks[] = {
5457	{ 0x16, HDA_INPUT, 1 },
5458	{ 0x16, HDA_INPUT, 2 },
5459	{ 0x16, HDA_INPUT, 3 },
5460	{ 0x16, HDA_INPUT, 4 },
5461	{ } /* end */
5462};
5463#endif
5464
5465static int patch_vt1716S(struct hda_codec *codec)
5466{
5467	struct via_spec *spec;
5468	int err;
5469
5470	/* create a codec specific record */
5471	spec = via_new_spec(codec);
5472	if (spec == NULL)
5473		return -ENOMEM;
5474
5475	/* automatic parse from the BIOS config */
5476	err = vt1716S_parse_auto_config(codec);
5477	if (err < 0) {
5478		via_free(codec);
5479		return err;
5480	} else if (!err) {
5481		printk(KERN_INFO "hda_codec: Cannot set up configuration "
5482		       "from BIOS.  Using genenic mode...\n");
5483	}
5484
5485	spec->init_verbs[spec->num_iverbs++]  = vt1716S_volume_init_verbs;
5486	spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs;
5487
5488	spec->stream_name_analog = "VT1716S Analog";
5489	spec->stream_analog_playback = &vt1716S_pcm_analog_playback;
5490	spec->stream_analog_capture = &vt1716S_pcm_analog_capture;
5491
5492	spec->stream_name_digital = "VT1716S Digital";
5493	spec->stream_digital_playback = &vt1716S_pcm_digital_playback;
5494
5495	if (!spec->adc_nids && spec->input_mux) {
5496		spec->adc_nids = vt1716S_adc_nids;
5497		spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids);
5498		get_mux_nids(codec);
5499		override_mic_boost(codec, 0x1a, 0, 3, 40);
5500		override_mic_boost(codec, 0x1e, 0, 3, 40);
5501		spec->mixers[spec->num_mixers] = vt1716S_capture_mixer;
5502		spec->num_mixers++;
5503	}
5504
5505	spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
5506	spec->num_mixers++;
5507
5508	spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
5509
5510	codec->patch_ops = via_patch_ops;
5511
5512	codec->patch_ops.init = via_auto_init;
5513	codec->patch_ops.unsol_event = via_unsol_event;
5514
5515#ifdef CONFIG_SND_HDA_POWER_SAVE
5516	spec->loopback.amplist = vt1716S_loopbacks;
5517#endif
5518
5519	return 0;
5520}
5521
5522/* for vt2002P */
5523
5524/* capture mixer elements */
5525static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5526	HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5527	HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5528	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5529	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5530	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5531	HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
5532			 HDA_INPUT),
5533	{
5534		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5535		/* The multiple "Capture Source" controls confuse alsamixer
5536		 * So call somewhat different..
5537		 */
5538		/* .name = "Capture Source", */
5539		.name = "Input Source",
5540		.count = 2,
5541		.info = via_mux_enum_info,
5542		.get = via_mux_enum_get,
5543		.put = via_mux_enum_put,
5544	},
5545	{ } /* end */
5546};
5547
5548static struct hda_verb vt2002P_volume_init_verbs[] = {
5549	/*
5550	 * Unmute ADC0-1 and set the default input to mic-in
5551	 */
5552	{0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5553	{0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5554
5555
5556	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5557	 * mixer widget
5558	 */
5559	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5560	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5561	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5562	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5563	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5564	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5565
5566	/* MUX Indices: Mic = 0 */
5567	{0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5568	{0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5569
5570	/* PW9 Output enable */
5571	{0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5572
5573	/* Enable Boost Volume backdoor */
5574	{0x1, 0xfb9, 0x24},
5575
5576	/* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5577	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5578	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5579	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5580	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5581	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5582	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5583	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5584	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5585
5586	/* set MUX0/1/4/8 = 0 (AOW0) */
5587	{0x34, AC_VERB_SET_CONNECT_SEL, 0},
5588	{0x35, AC_VERB_SET_CONNECT_SEL, 0},
5589	{0x37, AC_VERB_SET_CONNECT_SEL, 0},
5590	{0x3b, AC_VERB_SET_CONNECT_SEL, 0},
5591
5592	/* set PW0 index=0 (MW0) */
5593	{0x24, AC_VERB_SET_CONNECT_SEL, 0},
5594
5595	/* Enable AOW0 to MW9 */
5596	{0x1, 0xfb8, 0x88},
5597	{ }
5598};
5599
5600
5601static struct hda_verb vt2002P_uniwill_init_verbs[] = {
5602	{0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5603	 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5604	{0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
5605	 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5606	{0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5607	{0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5608	{0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5609	{ }
5610};
5611
5612static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5613	.substreams = 2,
5614	.channels_min = 2,
5615	.channels_max = 2,
5616	.nid = 0x8, /* NID to query formats and rates */
5617	.ops = {
5618		.open = via_playback_pcm_open,
5619		.prepare = via_playback_multi_pcm_prepare,
5620		.cleanup = via_playback_multi_pcm_cleanup,
5621		.close = via_pcm_open_close,
5622	},
5623};
5624
5625static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5626	.substreams = 2,
5627	.channels_min = 2,
5628	.channels_max = 2,
5629	.nid = 0x10, /* NID to query formats and rates */
5630	.ops = {
5631		.open = via_pcm_open_close,
5632		.prepare = via_capture_pcm_prepare,
5633		.cleanup = via_capture_pcm_cleanup,
5634		.close = via_pcm_open_close,
5635	},
5636};
5637
5638static struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5639	.substreams = 1,
5640	.channels_min = 2,
5641	.channels_max = 2,
5642	/* NID is set in via_build_pcms */
5643	.ops = {
5644		.open = via_dig_playback_pcm_open,
5645		.close = via_dig_playback_pcm_close,
5646		.prepare = via_dig_playback_pcm_prepare,
5647		.cleanup = via_dig_playback_pcm_cleanup
5648	},
5649};
5650
5651/* fill in the dac_nids table from the parsed pin configuration */
5652static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5653				      const struct auto_pin_cfg *cfg)
5654{
5655	spec->multiout.num_dacs = 1;
5656	spec->multiout.dac_nids = spec->private_dac_nids;
5657	if (cfg->line_out_pins[0])
5658		spec->multiout.dac_nids[0] = 0x8;
5659	return 0;
5660}
5661
5662/* add playback controls from the parsed DAC table */
5663static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5664					     const struct auto_pin_cfg *cfg)
5665{
5666	int err;
5667
5668	if (!cfg->line_out_pins[0])
5669		return -1;
5670
5671
5672	/* Line-Out: PortE */
5673	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5674			      "Master Front Playback Volume",
5675			      HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5676	if (err < 0)
5677		return err;
5678	err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5679			      "Master Front Playback Switch",
5680			      HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT));
5681	if (err < 0)
5682		return err;
5683
5684	return 0;
5685}
5686
5687static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5688{
5689	int err;
5690
5691	if (!pin)
5692		return 0;
5693
5694	spec->multiout.hp_nid = 0x9;
5695	spec->hp_independent_mode_index = 1;
5696
5697	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5698			      "Headphone Playback Volume",
5699			      HDA_COMPOSE_AMP_VAL(
5700				      spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5701	if (err < 0)
5702		return err;
5703
5704	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5705			      "Headphone Playback Switch",
5706			      HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5707	if (err < 0)
5708		return err;
5709
5710	create_hp_imux(spec);
5711	return 0;
5712}
5713
5714/* create playback/capture controls for input pins */
5715static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec,
5716						const struct auto_pin_cfg *cfg)
5717{
5718	static char *labels[] = {
5719		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
5720	};
5721	struct hda_input_mux *imux = &spec->private_imux[0];
5722	int i, err, idx = 0;
5723
5724	for (i = 0; i < AUTO_PIN_LAST; i++) {
5725		if (!cfg->input_pins[i])
5726			continue;
5727
5728		switch (cfg->input_pins[i]) {
5729		case 0x2b: /* Mic */
5730			idx = 0;
5731			break;
5732
5733		case 0x2a: /* Line In */
5734			idx = 1;
5735			break;
5736
5737		case 0x29: /* Front Mic */
5738			idx = 2;
5739			break;
5740		}
5741		err = via_new_analog_input(spec, labels[i], idx, 0x21);
5742		if (err < 0)
5743			return err;
5744		imux->items[imux->num_items].label = labels[i];
5745		imux->items[imux->num_items].index = idx;
5746		imux->num_items++;
5747	}
5748
5749	/* build volume/mute control of loopback */
5750	err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21);
5751	if (err < 0)
5752		return err;
5753
5754	/* for internal loopback recording select */
5755	imux->items[imux->num_items].label = "Stereo Mixer";
5756	imux->items[imux->num_items].index = 3;
5757	imux->num_items++;
5758
5759	/* for digital mic select */
5760	imux->items[imux->num_items].label = "Digital Mic";
5761	imux->items[imux->num_items].index = 4;
5762	imux->num_items++;
5763
5764	return 0;
5765}
5766
5767static int vt2002P_parse_auto_config(struct hda_codec *codec)
5768{
5769	struct via_spec *spec = codec->spec;
5770	int err;
5771
5772
5773	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5774	if (err < 0)
5775		return err;
5776
5777	err = vt2002P_auto_fill_dac_nids(spec, &spec->autocfg);
5778	if (err < 0)
5779		return err;
5780
5781	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5782		return 0; /* can't find valid BIOS pin config */
5783
5784	err = vt2002P_auto_create_multi_out_ctls(spec, &spec->autocfg);
5785	if (err < 0)
5786		return err;
5787	err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5788	if (err < 0)
5789		return err;
5790	err = vt2002P_auto_create_analog_input_ctls(spec, &spec->autocfg);
5791	if (err < 0)
5792		return err;
5793
5794	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5795
5796	fill_dig_outs(codec);
5797
5798	if (spec->kctls.list)
5799		spec->mixers[spec->num_mixers++] = spec->kctls.list;
5800
5801	spec->input_mux = &spec->private_imux[0];
5802
5803	if (spec->hp_mux)
5804		via_hp_build(codec);
5805
5806	return 1;
5807}
5808
5809#ifdef CONFIG_SND_HDA_POWER_SAVE
5810static struct hda_amp_list vt2002P_loopbacks[] = {
5811	{ 0x21, HDA_INPUT, 0 },
5812	{ 0x21, HDA_INPUT, 1 },
5813	{ 0x21, HDA_INPUT, 2 },
5814	{ } /* end */
5815};
5816#endif
5817
5818
5819/* patch for vt2002P */
5820static int patch_vt2002P(struct hda_codec *codec)
5821{
5822	struct via_spec *spec;
5823	int err;
5824
5825	/* create a codec specific record */
5826	spec = via_new_spec(codec);
5827	if (spec == NULL)
5828		return -ENOMEM;
5829
5830	/* automatic parse from the BIOS config */
5831	err = vt2002P_parse_auto_config(codec);
5832	if (err < 0) {
5833		via_free(codec);
5834		return err;
5835	} else if (!err) {
5836		printk(KERN_INFO "hda_codec: Cannot set up configuration "
5837		       "from BIOS.  Using genenic mode...\n");
5838	}
5839
5840	spec->init_verbs[spec->num_iverbs++]  = vt2002P_volume_init_verbs;
5841	spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs;
5842
5843	spec->stream_name_analog = "VT2002P Analog";
5844	spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5845	spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5846
5847	spec->stream_name_digital = "VT2002P Digital";
5848	spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5849
5850	if (!spec->adc_nids && spec->input_mux) {
5851		spec->adc_nids = vt2002P_adc_nids;
5852		spec->num_adc_nids = ARRAY_SIZE(vt2002P_adc_nids);
5853		get_mux_nids(codec);
5854		override_mic_boost(codec, 0x2b, 0, 3, 40);
5855		override_mic_boost(codec, 0x29, 0, 3, 40);
5856		spec->mixers[spec->num_mixers] = vt2002P_capture_mixer;
5857		spec->num_mixers++;
5858	}
5859
5860	codec->patch_ops = via_patch_ops;
5861
5862	codec->patch_ops.init = via_auto_init;
5863	codec->patch_ops.unsol_event = via_unsol_event;
5864
5865#ifdef CONFIG_SND_HDA_POWER_SAVE
5866	spec->loopback.amplist = vt2002P_loopbacks;
5867#endif
5868
5869	return 0;
5870}
5871
5872/* for vt1812 */
5873
5874/* capture mixer elements */
5875static struct snd_kcontrol_new vt1812_capture_mixer[] = {
5876	HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5877	HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5878	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5879	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5880	HDA_CODEC_MUTE("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5881	HDA_CODEC_MUTE("Front Mic Boost Capture Volume", 0x29, 0x0,
5882		       HDA_INPUT),
5883	{
5884		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5885		/* The multiple "Capture Source" controls confuse alsamixer
5886		 * So call somewhat different..
5887		 */
5888		.name = "Input Source",
5889		.count = 2,
5890		.info = via_mux_enum_info,
5891		.get = via_mux_enum_get,
5892		.put = via_mux_enum_put,
5893	},
5894	{ } /* end */
5895};
5896
5897static struct hda_verb vt1812_volume_init_verbs[] = {
5898	/*
5899	 * Unmute ADC0-1 and set the default input to mic-in
5900	 */
5901	{0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5902	{0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5903
5904
5905	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5906	 * mixer widget
5907	 */
5908	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5909	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5910	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5911	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5912	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5913	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5914
5915	/* MUX Indices: Mic = 0 */
5916	{0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5917	{0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5918
5919	/* PW9 Output enable */
5920	{0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5921
5922	/* Enable Boost Volume backdoor */
5923	{0x1, 0xfb9, 0x24},
5924
5925	/* MW0/1/4/13/15: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5926	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5927	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5928	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5929	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5930	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5931	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5932	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5933	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5934	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5935	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5936
5937	/* set MUX0/1/4/13/15 = 0 (AOW0) */
5938	{0x34, AC_VERB_SET_CONNECT_SEL, 0},
5939	{0x35, AC_VERB_SET_CONNECT_SEL, 0},
5940	{0x38, AC_VERB_SET_CONNECT_SEL, 0},
5941	{0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5942	{0x3d, AC_VERB_SET_CONNECT_SEL, 0},
5943
5944	/* Enable AOW0 to MW9 */
5945	{0x1, 0xfb8, 0xa8},
5946	{ }
5947};
5948
5949
5950static struct hda_verb vt1812_uniwill_init_verbs[] = {
5951	{0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5952	 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5953	{0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
5954	{0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5955	 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5956	{0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5957	{0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5958	{0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5959	{ }
5960};
5961
5962static struct hda_pcm_stream vt1812_pcm_analog_playback = {
5963	.substreams = 2,
5964	.channels_min = 2,
5965	.channels_max = 2,
5966	.nid = 0x8, /* NID to query formats and rates */
5967	.ops = {
5968		.open = via_playback_pcm_open,
5969		.prepare = via_playback_multi_pcm_prepare,
5970		.cleanup = via_playback_multi_pcm_cleanup,
5971		.close = via_pcm_open_close,
5972	},
5973};
5974
5975static struct hda_pcm_stream vt1812_pcm_analog_capture = {
5976	.substreams = 2,
5977	.channels_min = 2,
5978	.channels_max = 2,
5979	.nid = 0x10, /* NID to query formats and rates */
5980	.ops = {
5981		.open = via_pcm_open_close,
5982		.prepare = via_capture_pcm_prepare,
5983		.cleanup = via_capture_pcm_cleanup,
5984		.close = via_pcm_open_close,
5985	},
5986};
5987
5988static struct hda_pcm_stream vt1812_pcm_digital_playback = {
5989	.substreams = 1,
5990	.channels_min = 2,
5991	.channels_max = 2,
5992	/* NID is set in via_build_pcms */
5993	.ops = {
5994		.open = via_dig_playback_pcm_open,
5995		.close = via_dig_playback_pcm_close,
5996		.prepare = via_dig_playback_pcm_prepare,
5997		.cleanup = via_dig_playback_pcm_cleanup
5998	},
5999};
6000/* fill in the dac_nids table from the parsed pin configuration */
6001static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
6002				     const struct auto_pin_cfg *cfg)
6003{
6004	spec->multiout.num_dacs = 1;
6005	spec->multiout.dac_nids = spec->private_dac_nids;
6006	if (cfg->line_out_pins[0])
6007		spec->multiout.dac_nids[0] = 0x8;
6008	return 0;
6009}
6010
6011
6012/* add playback controls from the parsed DAC table */
6013static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
6014					     const struct auto_pin_cfg *cfg)
6015{
6016	int err;
6017
6018	if (!cfg->line_out_pins[0])
6019		return -1;
6020
6021	/* Line-Out: PortE */
6022	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
6023			      "Front Playback Volume",
6024			      HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
6025	if (err < 0)
6026		return err;
6027	err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
6028			      "Front Playback Switch",
6029			      HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
6030	if (err < 0)
6031		return err;
6032
6033	return 0;
6034}
6035
6036static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
6037{
6038	int err;
6039
6040	if (!pin)
6041		return 0;
6042
6043	spec->multiout.hp_nid = 0x9;
6044	spec->hp_independent_mode_index = 1;
6045
6046
6047	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
6048			      "Headphone Playback Volume",
6049			      HDA_COMPOSE_AMP_VAL(
6050				      spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
6051	if (err < 0)
6052		return err;
6053
6054	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
6055			      "Headphone Playback Switch",
6056			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
6057	if (err < 0)
6058		return err;
6059
6060	create_hp_imux(spec);
6061	return 0;
6062}
6063
6064/* create playback/capture controls for input pins */
6065static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec,
6066						const struct auto_pin_cfg *cfg)
6067{
6068	static char *labels[] = {
6069		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
6070	};
6071	struct hda_input_mux *imux = &spec->private_imux[0];
6072	int i, err, idx = 0;
6073
6074	for (i = 0; i < AUTO_PIN_LAST; i++) {
6075		if (!cfg->input_pins[i])
6076			continue;
6077
6078		switch (cfg->input_pins[i]) {
6079		case 0x2b: /* Mic */
6080			idx = 0;
6081			break;
6082
6083		case 0x2a: /* Line In */
6084			idx = 1;
6085			break;
6086
6087		case 0x29: /* Front Mic */
6088			idx = 2;
6089			break;
6090		}
6091		err = via_new_analog_input(spec, labels[i], idx, 0x21);
6092		if (err < 0)
6093			return err;
6094		imux->items[imux->num_items].label = labels[i];
6095		imux->items[imux->num_items].index = idx;
6096		imux->num_items++;
6097	}
6098	/* build volume/mute control of loopback */
6099	err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21);
6100	if (err < 0)
6101		return err;
6102
6103	/* for internal loopback recording select */
6104	imux->items[imux->num_items].label = "Stereo Mixer";
6105	imux->items[imux->num_items].index = 5;
6106	imux->num_items++;
6107
6108	/* for digital mic select */
6109	imux->items[imux->num_items].label = "Digital Mic";
6110	imux->items[imux->num_items].index = 6;
6111	imux->num_items++;
6112
6113	return 0;
6114}
6115
6116static int vt1812_parse_auto_config(struct hda_codec *codec)
6117{
6118	struct via_spec *spec = codec->spec;
6119	int err;
6120
6121
6122	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
6123	if (err < 0)
6124		return err;
6125	fill_dig_outs(codec);
6126	err = vt1812_auto_fill_dac_nids(spec, &spec->autocfg);
6127	if (err < 0)
6128		return err;
6129
6130	if (!spec->autocfg.line_outs && !spec->autocfg.hp_outs)
6131		return 0; /* can't find valid BIOS pin config */
6132
6133	err = vt1812_auto_create_multi_out_ctls(spec, &spec->autocfg);
6134	if (err < 0)
6135		return err;
6136	err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
6137	if (err < 0)
6138		return err;
6139	err = vt1812_auto_create_analog_input_ctls(spec, &spec->autocfg);
6140	if (err < 0)
6141		return err;
6142
6143	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6144
6145	fill_dig_outs(codec);
6146
6147	if (spec->kctls.list)
6148		spec->mixers[spec->num_mixers++] = spec->kctls.list;
6149
6150	spec->input_mux = &spec->private_imux[0];
6151
6152	if (spec->hp_mux)
6153		via_hp_build(codec);
6154
6155	return 1;
6156}
6157
6158#ifdef CONFIG_SND_HDA_POWER_SAVE
6159static struct hda_amp_list vt1812_loopbacks[] = {
6160	{ 0x21, HDA_INPUT, 0 },
6161	{ 0x21, HDA_INPUT, 1 },
6162	{ 0x21, HDA_INPUT, 2 },
6163	{ } /* end */
6164};
6165#endif
6166
6167
6168/* patch for vt1812 */
6169static int patch_vt1812(struct hda_codec *codec)
6170{
6171	struct via_spec *spec;
6172	int err;
6173
6174	/* create a codec specific record */
6175	spec = via_new_spec(codec);
6176	if (spec == NULL)
6177		return -ENOMEM;
6178
6179	/* automatic parse from the BIOS config */
6180	err = vt1812_parse_auto_config(codec);
6181	if (err < 0) {
6182		via_free(codec);
6183		return err;
6184	} else if (!err) {
6185		printk(KERN_INFO "hda_codec: Cannot set up configuration "
6186		       "from BIOS.  Using genenic mode...\n");
6187	}
6188
6189
6190	spec->init_verbs[spec->num_iverbs++]  = vt1812_volume_init_verbs;
6191	spec->init_verbs[spec->num_iverbs++] = vt1812_uniwill_init_verbs;
6192
6193	spec->stream_name_analog = "VT1812 Analog";
6194	spec->stream_analog_playback = &vt1812_pcm_analog_playback;
6195	spec->stream_analog_capture = &vt1812_pcm_analog_capture;
6196
6197	spec->stream_name_digital = "VT1812 Digital";
6198	spec->stream_digital_playback = &vt1812_pcm_digital_playback;
6199
6200
6201	if (!spec->adc_nids && spec->input_mux) {
6202		spec->adc_nids = vt1812_adc_nids;
6203		spec->num_adc_nids = ARRAY_SIZE(vt1812_adc_nids);
6204		get_mux_nids(codec);
6205		override_mic_boost(codec, 0x2b, 0, 3, 40);
6206		override_mic_boost(codec, 0x29, 0, 3, 40);
6207		spec->mixers[spec->num_mixers] = vt1812_capture_mixer;
6208		spec->num_mixers++;
6209	}
6210
6211	codec->patch_ops = via_patch_ops;
6212
6213	codec->patch_ops.init = via_auto_init;
6214	codec->patch_ops.unsol_event = via_unsol_event;
6215
6216#ifdef CONFIG_SND_HDA_POWER_SAVE
6217	spec->loopback.amplist = vt1812_loopbacks;
6218#endif
6219
6220	return 0;
6221}
6222
6223/*
6224 * patch entries
6225 */
6226static struct hda_codec_preset snd_hda_preset_via[] = {
6227	{ .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
6228	{ .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
6229	{ .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
6230	{ .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
6231	{ .id = 0x1106e710, .name = "VT1709 10-Ch",
6232	  .patch = patch_vt1709_10ch},
6233	{ .id = 0x1106e711, .name = "VT1709 10-Ch",
6234	  .patch = patch_vt1709_10ch},
6235	{ .id = 0x1106e712, .name = "VT1709 10-Ch",
6236	  .patch = patch_vt1709_10ch},
6237	{ .id = 0x1106e713, .name = "VT1709 10-Ch",
6238	  .patch = patch_vt1709_10ch},
6239	{ .id = 0x1106e714, .name = "VT1709 6-Ch",
6240	  .patch = patch_vt1709_6ch},
6241	{ .id = 0x1106e715, .name = "VT1709 6-Ch",
6242	  .patch = patch_vt1709_6ch},
6243	{ .id = 0x1106e716, .name = "VT1709 6-Ch",
6244	  .patch = patch_vt1709_6ch},
6245	{ .id = 0x1106e717, .name = "VT1709 6-Ch",
6246	  .patch = patch_vt1709_6ch},
6247	{ .id = 0x1106e720, .name = "VT1708B 8-Ch",
6248	  .patch = patch_vt1708B_8ch},
6249	{ .id = 0x1106e721, .name = "VT1708B 8-Ch",
6250	  .patch = patch_vt1708B_8ch},
6251	{ .id = 0x1106e722, .name = "VT1708B 8-Ch",
6252	  .patch = patch_vt1708B_8ch},
6253	{ .id = 0x1106e723, .name = "VT1708B 8-Ch",
6254	  .patch = patch_vt1708B_8ch},
6255	{ .id = 0x1106e724, .name = "VT1708B 4-Ch",
6256	  .patch = patch_vt1708B_4ch},
6257	{ .id = 0x1106e725, .name = "VT1708B 4-Ch",
6258	  .patch = patch_vt1708B_4ch},
6259	{ .id = 0x1106e726, .name = "VT1708B 4-Ch",
6260	  .patch = patch_vt1708B_4ch},
6261	{ .id = 0x1106e727, .name = "VT1708B 4-Ch",
6262	  .patch = patch_vt1708B_4ch},
6263	{ .id = 0x11060397, .name = "VT1708S",
6264	  .patch = patch_vt1708S},
6265	{ .id = 0x11061397, .name = "VT1708S",
6266	  .patch = patch_vt1708S},
6267	{ .id = 0x11062397, .name = "VT1708S",
6268	  .patch = patch_vt1708S},
6269	{ .id = 0x11063397, .name = "VT1708S",
6270	  .patch = patch_vt1708S},
6271	{ .id = 0x11064397, .name = "VT1708S",
6272	  .patch = patch_vt1708S},
6273	{ .id = 0x11065397, .name = "VT1708S",
6274	  .patch = patch_vt1708S},
6275	{ .id = 0x11066397, .name = "VT1708S",
6276	  .patch = patch_vt1708S},
6277	{ .id = 0x11067397, .name = "VT1708S",
6278	  .patch = patch_vt1708S},
6279	{ .id = 0x11060398, .name = "VT1702",
6280	  .patch = patch_vt1702},
6281	{ .id = 0x11061398, .name = "VT1702",
6282	  .patch = patch_vt1702},
6283	{ .id = 0x11062398, .name = "VT1702",
6284	  .patch = patch_vt1702},
6285	{ .id = 0x11063398, .name = "VT1702",
6286	  .patch = patch_vt1702},
6287	{ .id = 0x11064398, .name = "VT1702",
6288	  .patch = patch_vt1702},
6289	{ .id = 0x11065398, .name = "VT1702",
6290	  .patch = patch_vt1702},
6291	{ .id = 0x11066398, .name = "VT1702",
6292	  .patch = patch_vt1702},
6293	{ .id = 0x11067398, .name = "VT1702",
6294	  .patch = patch_vt1702},
6295	{ .id = 0x11060428, .name = "VT1718S",
6296	  .patch = patch_vt1718S},
6297	{ .id = 0x11064428, .name = "VT1718S",
6298	  .patch = patch_vt1718S},
6299	{ .id = 0x11060441, .name = "VT2020",
6300	  .patch = patch_vt1718S},
6301	{ .id = 0x11064441, .name = "VT1828S",
6302	  .patch = patch_vt1718S},
6303	{ .id = 0x11060433, .name = "VT1716S",
6304	  .patch = patch_vt1716S},
6305	{ .id = 0x1106a721, .name = "VT1716S",
6306	  .patch = patch_vt1716S},
6307	{ .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
6308	{ .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
6309	{ .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
6310	{ .id = 0x11060440, .name = "VT1818S",
6311	  .patch = patch_vt1708S},
6312	{} /* terminator */
6313};
6314
6315MODULE_ALIAS("snd-hda-codec-id:1106*");
6316
6317static struct hda_codec_preset_list via_list = {
6318	.preset = snd_hda_preset_via,
6319	.owner = THIS_MODULE,
6320};
6321
6322MODULE_LICENSE("GPL");
6323MODULE_DESCRIPTION("VIA HD-audio codec");
6324
6325static int __init patch_via_init(void)
6326{
6327	return snd_hda_add_codec_preset(&via_list);
6328}
6329
6330static void __exit patch_via_exit(void)
6331{
6332	snd_hda_delete_codec_preset(&via_list);
6333}
6334
6335module_init(patch_via_init)
6336module_exit(patch_via_exit)
6337