xref: /openbmc/linux/sound/pci/hda/patch_via.c (revision 22246614)
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for VIA VT1708 codec
5  *
6  * Copyright (c) 2006 Lydia Wang <lydiawang@viatech.com>
7  *                    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 /*                                                                           */
33 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
34 
35 
36 #include <linux/init.h>
37 #include <linux/delay.h>
38 #include <linux/slab.h>
39 #include <sound/core.h>
40 #include "hda_codec.h"
41 #include "hda_local.h"
42 #include "hda_patch.h"
43 
44 /* amp values */
45 #define AMP_VAL_IDX_SHIFT	19
46 #define AMP_VAL_IDX_MASK	(0x0f<<19)
47 
48 #define NUM_CONTROL_ALLOC	32
49 #define NUM_VERB_ALLOC		32
50 
51 /* Pin Widget NID */
52 #define VT1708_HP_NID		0x13
53 #define VT1708_DIGOUT_NID	0x14
54 #define VT1708_DIGIN_NID	0x16
55 #define VT1708_DIGIN_PIN	0x26
56 
57 #define VT1709_HP_DAC_NID	0x28
58 #define VT1709_DIGOUT_NID	0x13
59 #define VT1709_DIGIN_NID	0x17
60 #define VT1709_DIGIN_PIN	0x25
61 
62 #define VT1708B_HP_NID		0x25
63 #define VT1708B_DIGOUT_NID	0x12
64 #define VT1708B_DIGIN_NID	0x15
65 #define VT1708B_DIGIN_PIN	0x21
66 
67 #define IS_VT1708_VENDORID(x)		((x) >= 0x11061708 && (x) <= 0x1106170b)
68 #define IS_VT1709_10CH_VENDORID(x)	((x) >= 0x1106e710 && (x) <= 0x1106e713)
69 #define IS_VT1709_6CH_VENDORID(x)	((x) >= 0x1106e714 && (x) <= 0x1106e717)
70 #define IS_VT1708B_8CH_VENDORID(x)	((x) >= 0x1106e720 && (x) <= 0x1106e723)
71 #define IS_VT1708B_4CH_VENDORID(x)	((x) >= 0x1106e724 && (x) <= 0x1106e727)
72 
73 
74 enum {
75 	VIA_CTL_WIDGET_VOL,
76 	VIA_CTL_WIDGET_MUTE,
77 };
78 
79 enum {
80 	AUTO_SEQ_FRONT,
81 	AUTO_SEQ_SURROUND,
82 	AUTO_SEQ_CENLFE,
83 	AUTO_SEQ_SIDE
84 };
85 
86 static struct snd_kcontrol_new vt1708_control_templates[] = {
87 	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
88 	HDA_CODEC_MUTE(NULL, 0, 0, 0),
89 };
90 
91 
92 struct via_spec {
93 	/* codec parameterization */
94 	struct snd_kcontrol_new *mixers[3];
95 	unsigned int num_mixers;
96 
97 	struct hda_verb *init_verbs;
98 
99 	char *stream_name_analog;
100 	struct hda_pcm_stream *stream_analog_playback;
101 	struct hda_pcm_stream *stream_analog_capture;
102 
103 	char *stream_name_digital;
104 	struct hda_pcm_stream *stream_digital_playback;
105 	struct hda_pcm_stream *stream_digital_capture;
106 
107 	/* playback */
108 	struct hda_multi_out multiout;
109 
110 	/* capture */
111 	unsigned int num_adc_nids;
112 	hda_nid_t *adc_nids;
113 	hda_nid_t dig_in_nid;
114 
115 	/* capture source */
116 	const struct hda_input_mux *input_mux;
117 	unsigned int cur_mux[3];
118 
119 	/* PCM information */
120 	struct hda_pcm pcm_rec[2];
121 
122 	/* dynamic controls, init_verbs and input_mux */
123 	struct auto_pin_cfg autocfg;
124 	unsigned int num_kctl_alloc, num_kctl_used;
125 	struct snd_kcontrol_new *kctl_alloc;
126 	struct hda_input_mux private_imux;
127 	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
128 
129 #ifdef CONFIG_SND_HDA_POWER_SAVE
130 	struct hda_loopback_check loopback;
131 #endif
132 };
133 
134 static hda_nid_t vt1708_adc_nids[2] = {
135 	/* ADC1-2 */
136 	0x15, 0x27
137 };
138 
139 static hda_nid_t vt1709_adc_nids[3] = {
140 	/* ADC1-2 */
141 	0x14, 0x15, 0x16
142 };
143 
144 static hda_nid_t vt1708B_adc_nids[2] = {
145 	/* ADC1-2 */
146 	0x13, 0x14
147 };
148 
149 /* add dynamic controls */
150 static int via_add_control(struct via_spec *spec, int type, const char *name,
151 			   unsigned long val)
152 {
153 	struct snd_kcontrol_new *knew;
154 
155 	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
156 		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
157 
158 		/* array + terminator */
159 		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
160 		if (!knew)
161 			return -ENOMEM;
162 		if (spec->kctl_alloc) {
163 			memcpy(knew, spec->kctl_alloc,
164 			       sizeof(*knew) * spec->num_kctl_alloc);
165 			kfree(spec->kctl_alloc);
166 		}
167 		spec->kctl_alloc = knew;
168 		spec->num_kctl_alloc = num;
169 	}
170 
171 	knew = &spec->kctl_alloc[spec->num_kctl_used];
172 	*knew = vt1708_control_templates[type];
173 	knew->name = kstrdup(name, GFP_KERNEL);
174 
175 	if (!knew->name)
176 		return -ENOMEM;
177 	knew->private_value = val;
178 	spec->num_kctl_used++;
179 	return 0;
180 }
181 
182 /* create input playback/capture controls for the given pin */
183 static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
184 				const char *ctlname, int idx, int mix_nid)
185 {
186 	char name[32];
187 	int err;
188 
189 	sprintf(name, "%s Playback Volume", ctlname);
190 	err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
191 			      HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
192 	if (err < 0)
193 		return err;
194 	sprintf(name, "%s Playback Switch", ctlname);
195 	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
196 			      HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
197 	if (err < 0)
198 		return err;
199 	return 0;
200 }
201 
202 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
203 					   hda_nid_t nid, int pin_type,
204 					   int dac_idx)
205 {
206 	/* set as output */
207 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
208 			    pin_type);
209 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
210 			    AMP_OUT_UNMUTE);
211 }
212 
213 
214 static void via_auto_init_multi_out(struct hda_codec *codec)
215 {
216 	struct via_spec *spec = codec->spec;
217 	int i;
218 
219 	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
220 		hda_nid_t nid = spec->autocfg.line_out_pins[i];
221 		if (nid)
222 			via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
223 	}
224 }
225 
226 static void via_auto_init_hp_out(struct hda_codec *codec)
227 {
228 	struct via_spec *spec = codec->spec;
229 	hda_nid_t pin;
230 
231 	pin = spec->autocfg.hp_pins[0];
232 	if (pin) /* connect to front */
233 		via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
234 }
235 
236 static void via_auto_init_analog_input(struct hda_codec *codec)
237 {
238 	struct via_spec *spec = codec->spec;
239 	int i;
240 
241 	for (i = 0; i < AUTO_PIN_LAST; i++) {
242 		hda_nid_t nid = spec->autocfg.input_pins[i];
243 
244 		snd_hda_codec_write(codec, nid, 0,
245 				    AC_VERB_SET_PIN_WIDGET_CONTROL,
246 				    (i <= AUTO_PIN_FRONT_MIC ?
247 				     PIN_VREF50 : PIN_IN));
248 
249 	}
250 }
251 /*
252  * input MUX handling
253  */
254 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
255 			     struct snd_ctl_elem_info *uinfo)
256 {
257 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
258 	struct via_spec *spec = codec->spec;
259 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
260 }
261 
262 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
263 			    struct snd_ctl_elem_value *ucontrol)
264 {
265 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
266 	struct via_spec *spec = codec->spec;
267 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
268 
269 	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
270 	return 0;
271 }
272 
273 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
274 			    struct snd_ctl_elem_value *ucontrol)
275 {
276 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
277 	struct via_spec *spec = codec->spec;
278 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
279 	unsigned int vendor_id = codec->vendor_id;
280 
281 	/* AIW0  lydia 060801 add for correct sw0 input select */
282 	if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0))
283 		return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
284 					     0x18, &spec->cur_mux[adc_idx]);
285 	else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
286 		  IS_VT1709_6CH_VENDORID(vendor_id)) && adc_idx == 0)
287 		return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
288 					     0x19, &spec->cur_mux[adc_idx]);
289 	else if ((IS_VT1708B_8CH_VENDORID(vendor_id) ||
290 		  IS_VT1708B_4CH_VENDORID(vendor_id)) && adc_idx == 0)
291 		return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
292 					     0x17, &spec->cur_mux[adc_idx]);
293 	else
294 		return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
295 					     spec->adc_nids[adc_idx],
296 					     &spec->cur_mux[adc_idx]);
297 }
298 
299 /* capture mixer elements */
300 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
301 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
302 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
303 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
304 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
305 	{
306 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
307 		/* The multiple "Capture Source" controls confuse alsamixer
308 		 * So call somewhat different..
309 		 */
310 		/* .name = "Capture Source", */
311 		.name = "Input Source",
312 		.count = 1,
313 		.info = via_mux_enum_info,
314 		.get = via_mux_enum_get,
315 		.put = via_mux_enum_put,
316 	},
317 	{ } /* end */
318 };
319 /*
320  * generic initialization of ADC, input mixers and output mixers
321  */
322 static struct hda_verb vt1708_volume_init_verbs[] = {
323 	/*
324 	 * Unmute ADC0-1 and set the default input to mic-in
325 	 */
326 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
327 	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
328 
329 
330 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
331 	 * mixer widget
332 	 */
333 	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
334 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
335 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
336 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
337 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
338 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
339 
340 	/*
341 	 * Set up output mixers (0x19 - 0x1b)
342 	 */
343 	/* set vol=0 to output mixers */
344 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
345 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
346 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
347 
348 	/* Setup default input to PW4 */
349 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
350 	/* PW9 Output enable */
351 	{0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
352 	{ }
353 };
354 
355 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
356 				 struct hda_codec *codec,
357 				 struct snd_pcm_substream *substream)
358 {
359 	struct via_spec *spec = codec->spec;
360 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
361 					     hinfo);
362 }
363 
364 static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
365 				    struct hda_codec *codec,
366 				    unsigned int stream_tag,
367 				    unsigned int format,
368 				    struct snd_pcm_substream *substream)
369 {
370 	struct via_spec *spec = codec->spec;
371 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
372 						stream_tag, format, substream);
373 }
374 
375 static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
376 				    struct hda_codec *codec,
377 				    struct snd_pcm_substream *substream)
378 {
379 	struct via_spec *spec = codec->spec;
380 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
381 }
382 
383 /*
384  * Digital out
385  */
386 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
387 				     struct hda_codec *codec,
388 				     struct snd_pcm_substream *substream)
389 {
390 	struct via_spec *spec = codec->spec;
391 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
392 }
393 
394 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
395 				      struct hda_codec *codec,
396 				      struct snd_pcm_substream *substream)
397 {
398 	struct via_spec *spec = codec->spec;
399 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
400 }
401 
402 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
403 					struct hda_codec *codec,
404 					unsigned int stream_tag,
405 					unsigned int format,
406 					struct snd_pcm_substream *substream)
407 {
408 	struct via_spec *spec = codec->spec;
409 	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
410 					     stream_tag, format, substream);
411 }
412 
413 /*
414  * Analog capture
415  */
416 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
417 				   struct hda_codec *codec,
418 				   unsigned int stream_tag,
419 				   unsigned int format,
420 				   struct snd_pcm_substream *substream)
421 {
422 	struct via_spec *spec = codec->spec;
423 
424 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
425 				   stream_tag, 0, format);
426 	return 0;
427 }
428 
429 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
430 				   struct hda_codec *codec,
431 				   struct snd_pcm_substream *substream)
432 {
433 	struct via_spec *spec = codec->spec;
434 	snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
435 	return 0;
436 }
437 
438 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
439 	.substreams = 1,
440 	.channels_min = 2,
441 	.channels_max = 8,
442 	.nid = 0x10, /* NID to query formats and rates */
443 	.ops = {
444 		.open = via_playback_pcm_open,
445 		.prepare = via_playback_pcm_prepare,
446 		.cleanup = via_playback_pcm_cleanup
447 	},
448 };
449 
450 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
451 	.substreams = 2,
452 	.channels_min = 2,
453 	.channels_max = 2,
454 	.nid = 0x15, /* NID to query formats and rates */
455 	.ops = {
456 		.prepare = via_capture_pcm_prepare,
457 		.cleanup = via_capture_pcm_cleanup
458 	},
459 };
460 
461 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
462 	.substreams = 1,
463 	.channels_min = 2,
464 	.channels_max = 2,
465 	/* NID is set in via_build_pcms */
466 	.ops = {
467 		.open = via_dig_playback_pcm_open,
468 		.close = via_dig_playback_pcm_close,
469 		.prepare = via_dig_playback_pcm_prepare
470 	},
471 };
472 
473 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
474 	.substreams = 1,
475 	.channels_min = 2,
476 	.channels_max = 2,
477 };
478 
479 static int via_build_controls(struct hda_codec *codec)
480 {
481 	struct via_spec *spec = codec->spec;
482 	int err;
483 	int i;
484 
485 	for (i = 0; i < spec->num_mixers; i++) {
486 		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
487 		if (err < 0)
488 			return err;
489 	}
490 
491 	if (spec->multiout.dig_out_nid) {
492 		err = snd_hda_create_spdif_out_ctls(codec,
493 						    spec->multiout.dig_out_nid);
494 		if (err < 0)
495 			return err;
496 		err = snd_hda_create_spdif_share_sw(codec,
497 						    &spec->multiout);
498 		if (err < 0)
499 			return err;
500 		spec->multiout.share_spdif = 1;
501 	}
502 	if (spec->dig_in_nid) {
503 		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
504 		if (err < 0)
505 			return err;
506 	}
507 	return 0;
508 }
509 
510 static int via_build_pcms(struct hda_codec *codec)
511 {
512 	struct via_spec *spec = codec->spec;
513 	struct hda_pcm *info = spec->pcm_rec;
514 
515 	codec->num_pcms = 1;
516 	codec->pcm_info = info;
517 
518 	info->name = spec->stream_name_analog;
519 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
520 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
521 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
522 	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
523 
524 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
525 		spec->multiout.max_channels;
526 
527 	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
528 		codec->num_pcms++;
529 		info++;
530 		info->name = spec->stream_name_digital;
531 		info->pcm_type = HDA_PCM_TYPE_SPDIF;
532 		if (spec->multiout.dig_out_nid) {
533 			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
534 				*(spec->stream_digital_playback);
535 			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
536 				spec->multiout.dig_out_nid;
537 		}
538 		if (spec->dig_in_nid) {
539 			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
540 				*(spec->stream_digital_capture);
541 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
542 				spec->dig_in_nid;
543 		}
544 	}
545 
546 	return 0;
547 }
548 
549 static void via_free(struct hda_codec *codec)
550 {
551 	struct via_spec *spec = codec->spec;
552 	unsigned int i;
553 
554 	if (!spec)
555 		return;
556 
557 	if (spec->kctl_alloc) {
558 		for (i = 0; i < spec->num_kctl_used; i++)
559 			kfree(spec->kctl_alloc[i].name);
560 		kfree(spec->kctl_alloc);
561 	}
562 
563 	kfree(codec->spec);
564 }
565 
566 static int via_init(struct hda_codec *codec)
567 {
568 	struct via_spec *spec = codec->spec;
569 	snd_hda_sequence_write(codec, spec->init_verbs);
570 	/* Lydia Add for EAPD enable */
571 	if (!spec->dig_in_nid) { /* No Digital In connection */
572 		if (IS_VT1708_VENDORID(codec->vendor_id)) {
573 			snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
574 					    AC_VERB_SET_PIN_WIDGET_CONTROL,
575 					    PIN_OUT);
576 			snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
577 					    AC_VERB_SET_EAPD_BTLENABLE, 0x02);
578 		} else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) ||
579 			   IS_VT1709_6CH_VENDORID(codec->vendor_id)) {
580 			snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
581 					    AC_VERB_SET_PIN_WIDGET_CONTROL,
582 					    PIN_OUT);
583 			snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
584 					    AC_VERB_SET_EAPD_BTLENABLE, 0x02);
585 		} else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) ||
586 			   IS_VT1708B_4CH_VENDORID(codec->vendor_id)) {
587 			snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
588 					    AC_VERB_SET_PIN_WIDGET_CONTROL,
589 					    PIN_OUT);
590 			snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
591 					    AC_VERB_SET_EAPD_BTLENABLE, 0x02);
592 		}
593 	} else /* enable SPDIF-input pin */
594 		snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
595 				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
596 
597  	return 0;
598 }
599 
600 #ifdef CONFIG_SND_HDA_POWER_SAVE
601 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
602 {
603 	struct via_spec *spec = codec->spec;
604 	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
605 }
606 #endif
607 
608 /*
609  */
610 static struct hda_codec_ops via_patch_ops = {
611 	.build_controls = via_build_controls,
612 	.build_pcms = via_build_pcms,
613 	.init = via_init,
614 	.free = via_free,
615 #ifdef CONFIG_SND_HDA_POWER_SAVE
616 	.check_power_status = via_check_power_status,
617 #endif
618 };
619 
620 /* fill in the dac_nids table from the parsed pin configuration */
621 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
622 				     const struct auto_pin_cfg *cfg)
623 {
624 	int i;
625 	hda_nid_t nid;
626 
627 	spec->multiout.num_dacs = cfg->line_outs;
628 
629 	spec->multiout.dac_nids = spec->private_dac_nids;
630 
631 	for(i = 0; i < 4; i++) {
632 		nid = cfg->line_out_pins[i];
633 		if (nid) {
634 			/* config dac list */
635 			switch (i) {
636 			case AUTO_SEQ_FRONT:
637 				spec->multiout.dac_nids[i] = 0x10;
638 				break;
639 			case AUTO_SEQ_CENLFE:
640 				spec->multiout.dac_nids[i] = 0x12;
641 				break;
642 			case AUTO_SEQ_SURROUND:
643 				spec->multiout.dac_nids[i] = 0x13;
644 				break;
645 			case AUTO_SEQ_SIDE:
646 				spec->multiout.dac_nids[i] = 0x11;
647 				break;
648 			}
649 		}
650 	}
651 
652 	return 0;
653 }
654 
655 /* add playback controls from the parsed DAC table */
656 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
657 					     const struct auto_pin_cfg *cfg)
658 {
659 	char name[32];
660 	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
661 	hda_nid_t nid, nid_vol = 0;
662 	int i, err;
663 
664 	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
665 		nid = cfg->line_out_pins[i];
666 
667 		if (!nid)
668 			continue;
669 
670 		if (i != AUTO_SEQ_FRONT)
671 			nid_vol = 0x1b - i + 1;
672 
673 		if (i == AUTO_SEQ_CENLFE) {
674 			/* Center/LFE */
675 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
676 					"Center Playback Volume",
677 					HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
678 							    HDA_OUTPUT));
679 			if (err < 0)
680 				return err;
681 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
682 					      "LFE Playback Volume",
683 					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
684 								  HDA_OUTPUT));
685 			if (err < 0)
686 				return err;
687 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
688 					      "Center Playback Switch",
689 					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
690 								  HDA_OUTPUT));
691 			if (err < 0)
692 				return err;
693 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
694 					      "LFE Playback Switch",
695 					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
696 								  HDA_OUTPUT));
697 			if (err < 0)
698 				return err;
699 		} else if (i == AUTO_SEQ_FRONT){
700 			/* add control to mixer index 0 */
701 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
702 					      "Master Front Playback Volume",
703 					      HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
704 								  HDA_INPUT));
705 			if (err < 0)
706 				return err;
707 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
708 					      "Master Front Playback Switch",
709 					      HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
710 								  HDA_INPUT));
711 			if (err < 0)
712 				return err;
713 
714 			/* add control to PW3 */
715 			sprintf(name, "%s Playback Volume", chname[i]);
716 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
717 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
718 								  HDA_OUTPUT));
719 			if (err < 0)
720 				return err;
721 			sprintf(name, "%s Playback Switch", chname[i]);
722 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
723 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
724 								  HDA_OUTPUT));
725 			if (err < 0)
726 				return err;
727 		} else {
728 			sprintf(name, "%s Playback Volume", chname[i]);
729 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
730 					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
731 								  HDA_OUTPUT));
732 			if (err < 0)
733 				return err;
734 			sprintf(name, "%s Playback Switch", chname[i]);
735 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
736 					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
737 								  HDA_OUTPUT));
738 			if (err < 0)
739 				return err;
740 		}
741 	}
742 
743 	return 0;
744 }
745 
746 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
747 {
748 	int err;
749 
750 	if (!pin)
751 		return 0;
752 
753 	spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
754 
755 	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
756 			      "Headphone Playback Volume",
757 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
758 	if (err < 0)
759 		return err;
760 	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
761 			      "Headphone Playback Switch",
762 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
763 	if (err < 0)
764 		return err;
765 
766 	return 0;
767 }
768 
769 /* create playback/capture controls for input pins */
770 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
771 						const struct auto_pin_cfg *cfg)
772 {
773 	static char *labels[] = {
774 		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
775 	};
776 	struct hda_input_mux *imux = &spec->private_imux;
777 	int i, err, idx = 0;
778 
779 	/* for internal loopback recording select */
780 	imux->items[imux->num_items].label = "Stereo Mixer";
781 	imux->items[imux->num_items].index = idx;
782 	imux->num_items++;
783 
784 	for (i = 0; i < AUTO_PIN_LAST; i++) {
785 		if (!cfg->input_pins[i])
786 			continue;
787 
788 		switch (cfg->input_pins[i]) {
789 		case 0x1d: /* Mic */
790 			idx = 2;
791 			break;
792 
793 		case 0x1e: /* Line In */
794 			idx = 3;
795 			break;
796 
797 		case 0x21: /* Front Mic */
798 			idx = 4;
799 			break;
800 
801 		case 0x24: /* CD */
802 			idx = 1;
803 			break;
804 		}
805 		err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
806 					   idx, 0x17);
807 		if (err < 0)
808 			return err;
809 		imux->items[imux->num_items].label = labels[i];
810 		imux->items[imux->num_items].index = idx;
811 		imux->num_items++;
812 	}
813 	return 0;
814 }
815 
816 #ifdef CONFIG_SND_HDA_POWER_SAVE
817 static struct hda_amp_list vt1708_loopbacks[] = {
818 	{ 0x17, HDA_INPUT, 1 },
819 	{ 0x17, HDA_INPUT, 2 },
820 	{ 0x17, HDA_INPUT, 3 },
821 	{ 0x17, HDA_INPUT, 4 },
822 	{ } /* end */
823 };
824 #endif
825 
826 static int vt1708_parse_auto_config(struct hda_codec *codec)
827 {
828 	struct via_spec *spec = codec->spec;
829 	int err;
830 
831 	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
832 	if (err < 0)
833 		return err;
834 	err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
835 	if (err < 0)
836 		return err;
837 	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
838 		return 0; /* can't find valid BIOS pin config */
839 
840 	err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
841 	if (err < 0)
842 		return err;
843 	err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
844 	if (err < 0)
845 		return err;
846 	err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
847 	if (err < 0)
848 		return err;
849 
850 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
851 
852 	if (spec->autocfg.dig_out_pin)
853 		spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
854 	if (spec->autocfg.dig_in_pin)
855 		spec->dig_in_nid = VT1708_DIGIN_NID;
856 
857 	if (spec->kctl_alloc)
858 		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
859 
860 	spec->init_verbs = vt1708_volume_init_verbs;
861 
862 	spec->input_mux = &spec->private_imux;
863 
864 	return 1;
865 }
866 
867 /* init callback for auto-configuration model -- overriding the default init */
868 static int via_auto_init(struct hda_codec *codec)
869 {
870 	via_init(codec);
871 	via_auto_init_multi_out(codec);
872 	via_auto_init_hp_out(codec);
873 	via_auto_init_analog_input(codec);
874 	return 0;
875 }
876 
877 static int patch_vt1708(struct hda_codec *codec)
878 {
879 	struct via_spec *spec;
880 	int err;
881 
882 	/* create a codec specific record */
883 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
884 	if (spec == NULL)
885 		return -ENOMEM;
886 
887 	codec->spec = spec;
888 
889 	/* automatic parse from the BIOS config */
890 	err = vt1708_parse_auto_config(codec);
891 	if (err < 0) {
892 		via_free(codec);
893 		return err;
894 	} else if (!err) {
895 		printk(KERN_INFO "hda_codec: Cannot set up configuration "
896 		       "from BIOS.  Using genenic mode...\n");
897 	}
898 
899 
900 	spec->stream_name_analog = "VT1708 Analog";
901 	spec->stream_analog_playback = &vt1708_pcm_analog_playback;
902 	spec->stream_analog_capture = &vt1708_pcm_analog_capture;
903 
904 	spec->stream_name_digital = "VT1708 Digital";
905 	spec->stream_digital_playback = &vt1708_pcm_digital_playback;
906 	spec->stream_digital_capture = &vt1708_pcm_digital_capture;
907 
908 
909 	if (!spec->adc_nids && spec->input_mux) {
910 		spec->adc_nids = vt1708_adc_nids;
911 		spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
912 		spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
913 		spec->num_mixers++;
914 	}
915 
916 	codec->patch_ops = via_patch_ops;
917 
918 	codec->patch_ops.init = via_auto_init;
919 #ifdef CONFIG_SND_HDA_POWER_SAVE
920 	spec->loopback.amplist = vt1708_loopbacks;
921 #endif
922 
923 	return 0;
924 }
925 
926 /* capture mixer elements */
927 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
928 	HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
929 	HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
930 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
931 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
932 	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
933 	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
934 	{
935 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
936 		/* The multiple "Capture Source" controls confuse alsamixer
937 		 * So call somewhat different..
938 		 */
939 		/* .name = "Capture Source", */
940 		.name = "Input Source",
941 		.count = 1,
942 		.info = via_mux_enum_info,
943 		.get = via_mux_enum_get,
944 		.put = via_mux_enum_put,
945 	},
946 	{ } /* end */
947 };
948 
949 /*
950  * generic initialization of ADC, input mixers and output mixers
951  */
952 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
953 	/*
954 	 * Unmute ADC0-2 and set the default input to mic-in
955 	 */
956 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
957 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
958 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
959 
960 
961 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
962 	 * mixer widget
963 	 */
964 	/* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
965 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
966 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
967 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
968 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
969 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
970 
971 	/*
972 	 * Set up output selector (0x1a, 0x1b, 0x29)
973 	 */
974 	/* set vol=0 to output mixers */
975 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
976 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
977 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
978 
979 	/*
980 	 *  Unmute PW3 and PW4
981 	 */
982 	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
983 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
984 
985 	/* Set input of PW4 as AOW4 */
986 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
987 	/* PW9 Output enable */
988 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
989 	{ }
990 };
991 
992 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
993 	.substreams = 1,
994 	.channels_min = 2,
995 	.channels_max = 10,
996 	.nid = 0x10, /* NID to query formats and rates */
997 	.ops = {
998 		.open = via_playback_pcm_open,
999 		.prepare = via_playback_pcm_prepare,
1000 		.cleanup = via_playback_pcm_cleanup
1001 	},
1002 };
1003 
1004 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
1005 	.substreams = 1,
1006 	.channels_min = 2,
1007 	.channels_max = 6,
1008 	.nid = 0x10, /* NID to query formats and rates */
1009 	.ops = {
1010 		.open = via_playback_pcm_open,
1011 		.prepare = via_playback_pcm_prepare,
1012 		.cleanup = via_playback_pcm_cleanup
1013 	},
1014 };
1015 
1016 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
1017 	.substreams = 2,
1018 	.channels_min = 2,
1019 	.channels_max = 2,
1020 	.nid = 0x14, /* NID to query formats and rates */
1021 	.ops = {
1022 		.prepare = via_capture_pcm_prepare,
1023 		.cleanup = via_capture_pcm_cleanup
1024 	},
1025 };
1026 
1027 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
1028 	.substreams = 1,
1029 	.channels_min = 2,
1030 	.channels_max = 2,
1031 	/* NID is set in via_build_pcms */
1032 	.ops = {
1033 		.open = via_dig_playback_pcm_open,
1034 		.close = via_dig_playback_pcm_close
1035 	},
1036 };
1037 
1038 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
1039 	.substreams = 1,
1040 	.channels_min = 2,
1041 	.channels_max = 2,
1042 };
1043 
1044 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
1045 				     const struct auto_pin_cfg *cfg)
1046 {
1047 	int i;
1048 	hda_nid_t nid;
1049 
1050 	if (cfg->line_outs == 4)  /* 10 channels */
1051 		spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
1052 	else if (cfg->line_outs == 3) /* 6 channels */
1053 		spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
1054 
1055 	spec->multiout.dac_nids = spec->private_dac_nids;
1056 
1057 	if (cfg->line_outs == 4) { /* 10 channels */
1058 		for (i = 0; i < cfg->line_outs; i++) {
1059 			nid = cfg->line_out_pins[i];
1060 			if (nid) {
1061 				/* config dac list */
1062 				switch (i) {
1063 				case AUTO_SEQ_FRONT:
1064 					/* AOW0 */
1065 					spec->multiout.dac_nids[i] = 0x10;
1066 					break;
1067 				case AUTO_SEQ_CENLFE:
1068 					/* AOW2 */
1069 					spec->multiout.dac_nids[i] = 0x12;
1070 					break;
1071 				case AUTO_SEQ_SURROUND:
1072 					/* AOW3 */
1073 					spec->multiout.dac_nids[i] = 0x27;
1074 					break;
1075 				case AUTO_SEQ_SIDE:
1076 					/* AOW1 */
1077 					spec->multiout.dac_nids[i] = 0x11;
1078 					break;
1079 				default:
1080 					break;
1081 				}
1082 			}
1083 		}
1084 		spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1085 
1086 	} else if (cfg->line_outs == 3) { /* 6 channels */
1087 		for(i = 0; i < cfg->line_outs; i++) {
1088 			nid = cfg->line_out_pins[i];
1089 			if (nid) {
1090 				/* config dac list */
1091 				switch(i) {
1092 				case AUTO_SEQ_FRONT:
1093 					/* AOW0 */
1094 					spec->multiout.dac_nids[i] = 0x10;
1095 					break;
1096 				case AUTO_SEQ_CENLFE:
1097 					/* AOW2 */
1098 					spec->multiout.dac_nids[i] = 0x12;
1099 					break;
1100 				case AUTO_SEQ_SURROUND:
1101 					/* AOW1 */
1102 					spec->multiout.dac_nids[i] = 0x11;
1103 					break;
1104 				default:
1105 					break;
1106 				}
1107 			}
1108 		}
1109 	}
1110 
1111 	return 0;
1112 }
1113 
1114 /* add playback controls from the parsed DAC table */
1115 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1116 					     const struct auto_pin_cfg *cfg)
1117 {
1118 	char name[32];
1119 	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1120 	hda_nid_t nid = 0;
1121 	int i, err;
1122 
1123 	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1124 		nid = cfg->line_out_pins[i];
1125 
1126 		if (!nid)
1127 			continue;
1128 
1129 		if (i == AUTO_SEQ_CENLFE) {
1130 			/* Center/LFE */
1131 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1132 					      "Center Playback Volume",
1133 					      HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1134 								  HDA_OUTPUT));
1135 			if (err < 0)
1136 				return err;
1137 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1138 					      "LFE Playback Volume",
1139 					      HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1140 								  HDA_OUTPUT));
1141 			if (err < 0)
1142 				return err;
1143 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1144 					      "Center Playback Switch",
1145 					      HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1146 								  HDA_OUTPUT));
1147 			if (err < 0)
1148 				return err;
1149 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1150 					      "LFE Playback Switch",
1151 					      HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1152 								  HDA_OUTPUT));
1153 			if (err < 0)
1154 				return err;
1155 		} else if (i == AUTO_SEQ_FRONT){
1156 			/* add control to mixer index 0 */
1157 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1158 					      "Master Front Playback Volume",
1159 					      HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1160 								  HDA_INPUT));
1161 			if (err < 0)
1162 				return err;
1163 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1164 					      "Master Front Playback Switch",
1165 					      HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1166 								  HDA_INPUT));
1167 			if (err < 0)
1168 				return err;
1169 
1170 			/* add control to PW3 */
1171 			sprintf(name, "%s Playback Volume", chname[i]);
1172 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1173 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1174 								  HDA_OUTPUT));
1175 			if (err < 0)
1176 				return err;
1177 			sprintf(name, "%s Playback Switch", chname[i]);
1178 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1179 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1180 								  HDA_OUTPUT));
1181 			if (err < 0)
1182 				return err;
1183 		} else if (i == AUTO_SEQ_SURROUND) {
1184 			sprintf(name, "%s Playback Volume", chname[i]);
1185 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1186 					      HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1187 								  HDA_OUTPUT));
1188 			if (err < 0)
1189 				return err;
1190 			sprintf(name, "%s Playback Switch", chname[i]);
1191 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1192 					      HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1193 								  HDA_OUTPUT));
1194 			if (err < 0)
1195 				return err;
1196 		} else if (i == AUTO_SEQ_SIDE) {
1197 			sprintf(name, "%s Playback Volume", chname[i]);
1198 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1199 					      HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1200 								  HDA_OUTPUT));
1201 			if (err < 0)
1202 				return err;
1203 			sprintf(name, "%s Playback Switch", chname[i]);
1204 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1205 					      HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1206 								  HDA_OUTPUT));
1207 			if (err < 0)
1208 				return err;
1209 		}
1210 	}
1211 
1212 	return 0;
1213 }
1214 
1215 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1216 {
1217 	int err;
1218 
1219 	if (!pin)
1220 		return 0;
1221 
1222 	if (spec->multiout.num_dacs == 5) /* 10 channels */
1223 		spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1224 	else if (spec->multiout.num_dacs == 3) /* 6 channels */
1225 		spec->multiout.hp_nid = 0;
1226 
1227 	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1228 			      "Headphone Playback Volume",
1229 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1230 	if (err < 0)
1231 		return err;
1232 	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1233 			      "Headphone Playback Switch",
1234 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1235 	if (err < 0)
1236 		return err;
1237 
1238 	return 0;
1239 }
1240 
1241 /* create playback/capture controls for input pins */
1242 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1243 						const struct auto_pin_cfg *cfg)
1244 {
1245 	static char *labels[] = {
1246 		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1247 	};
1248 	struct hda_input_mux *imux = &spec->private_imux;
1249 	int i, err, idx = 0;
1250 
1251 	/* for internal loopback recording select */
1252 	imux->items[imux->num_items].label = "Stereo Mixer";
1253 	imux->items[imux->num_items].index = idx;
1254 	imux->num_items++;
1255 
1256 	for (i = 0; i < AUTO_PIN_LAST; i++) {
1257 		if (!cfg->input_pins[i])
1258 			continue;
1259 
1260 		switch (cfg->input_pins[i]) {
1261 		case 0x1d: /* Mic */
1262 			idx = 2;
1263 			break;
1264 
1265 		case 0x1e: /* Line In */
1266 			idx = 3;
1267 			break;
1268 
1269 		case 0x21: /* Front Mic */
1270 			idx = 4;
1271 			break;
1272 
1273 		case 0x23: /* CD */
1274 			idx = 1;
1275 			break;
1276 		}
1277 		err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1278 					   idx, 0x18);
1279 		if (err < 0)
1280 			return err;
1281 		imux->items[imux->num_items].label = labels[i];
1282 		imux->items[imux->num_items].index = idx;
1283 		imux->num_items++;
1284 	}
1285 	return 0;
1286 }
1287 
1288 static int vt1709_parse_auto_config(struct hda_codec *codec)
1289 {
1290 	struct via_spec *spec = codec->spec;
1291 	int err;
1292 
1293 	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1294 	if (err < 0)
1295 		return err;
1296 	err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
1297 	if (err < 0)
1298 		return err;
1299 	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1300 		return 0; /* can't find valid BIOS pin config */
1301 
1302 	err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
1303 	if (err < 0)
1304 		return err;
1305 	err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1306 	if (err < 0)
1307 		return err;
1308 	err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
1309 	if (err < 0)
1310 		return err;
1311 
1312 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1313 
1314 	if (spec->autocfg.dig_out_pin)
1315 		spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
1316 	if (spec->autocfg.dig_in_pin)
1317 		spec->dig_in_nid = VT1709_DIGIN_NID;
1318 
1319 	if (spec->kctl_alloc)
1320 		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1321 
1322 	spec->input_mux = &spec->private_imux;
1323 
1324 	return 1;
1325 }
1326 
1327 #ifdef CONFIG_SND_HDA_POWER_SAVE
1328 static struct hda_amp_list vt1709_loopbacks[] = {
1329 	{ 0x18, HDA_INPUT, 1 },
1330 	{ 0x18, HDA_INPUT, 2 },
1331 	{ 0x18, HDA_INPUT, 3 },
1332 	{ 0x18, HDA_INPUT, 4 },
1333 	{ } /* end */
1334 };
1335 #endif
1336 
1337 static int patch_vt1709_10ch(struct hda_codec *codec)
1338 {
1339 	struct via_spec *spec;
1340 	int err;
1341 
1342 	/* create a codec specific record */
1343 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1344 	if (spec == NULL)
1345 		return -ENOMEM;
1346 
1347 	codec->spec = spec;
1348 
1349 	err = vt1709_parse_auto_config(codec);
1350 	if (err < 0) {
1351 		via_free(codec);
1352 		return err;
1353 	} else if (!err) {
1354 		printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1355 		       "Using genenic mode...\n");
1356 	}
1357 
1358 	spec->init_verbs = vt1709_10ch_volume_init_verbs;
1359 
1360 	spec->stream_name_analog = "VT1709 Analog";
1361 	spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
1362 	spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1363 
1364 	spec->stream_name_digital = "VT1709 Digital";
1365 	spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1366 	spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1367 
1368 
1369 	if (!spec->adc_nids && spec->input_mux) {
1370 		spec->adc_nids = vt1709_adc_nids;
1371 		spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1372 		spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1373 		spec->num_mixers++;
1374 	}
1375 
1376 	codec->patch_ops = via_patch_ops;
1377 
1378 	codec->patch_ops.init = via_auto_init;
1379 #ifdef CONFIG_SND_HDA_POWER_SAVE
1380 	spec->loopback.amplist = vt1709_loopbacks;
1381 #endif
1382 
1383 	return 0;
1384 }
1385 /*
1386  * generic initialization of ADC, input mixers and output mixers
1387  */
1388 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
1389 	/*
1390 	 * Unmute ADC0-2 and set the default input to mic-in
1391 	 */
1392 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1393 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1394 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1395 
1396 
1397 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1398 	 * mixer widget
1399 	 */
1400 	/* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1401 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1402 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1403 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1404 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1405 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1406 
1407 	/*
1408 	 * Set up output selector (0x1a, 0x1b, 0x29)
1409 	 */
1410 	/* set vol=0 to output mixers */
1411 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1412 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1413 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1414 
1415 	/*
1416 	 *  Unmute PW3 and PW4
1417 	 */
1418 	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1419 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1420 
1421 	/* Set input of PW4 as MW0 */
1422 	{0x20, AC_VERB_SET_CONNECT_SEL, 0},
1423 	/* PW9 Output enable */
1424 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1425 	{ }
1426 };
1427 
1428 static int patch_vt1709_6ch(struct hda_codec *codec)
1429 {
1430 	struct via_spec *spec;
1431 	int err;
1432 
1433 	/* create a codec specific record */
1434 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1435 	if (spec == NULL)
1436 		return -ENOMEM;
1437 
1438 	codec->spec = spec;
1439 
1440 	err = vt1709_parse_auto_config(codec);
1441 	if (err < 0) {
1442 		via_free(codec);
1443 		return err;
1444 	} else if (!err) {
1445 		printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1446 		       "Using genenic mode...\n");
1447 	}
1448 
1449 	spec->init_verbs = vt1709_6ch_volume_init_verbs;
1450 
1451 	spec->stream_name_analog = "VT1709 Analog";
1452 	spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
1453 	spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1454 
1455 	spec->stream_name_digital = "VT1709 Digital";
1456 	spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1457 	spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1458 
1459 
1460 	if (!spec->adc_nids && spec->input_mux) {
1461 		spec->adc_nids = vt1709_adc_nids;
1462 		spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1463 		spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1464 		spec->num_mixers++;
1465 	}
1466 
1467 	codec->patch_ops = via_patch_ops;
1468 
1469 	codec->patch_ops.init = via_auto_init;
1470 #ifdef CONFIG_SND_HDA_POWER_SAVE
1471 	spec->loopback.amplist = vt1709_loopbacks;
1472 #endif
1473 	return 0;
1474 }
1475 
1476 /* capture mixer elements */
1477 static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
1478 	HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
1479 	HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
1480 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
1481 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
1482 	{
1483 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1484 		/* The multiple "Capture Source" controls confuse alsamixer
1485 		 * So call somewhat different..
1486 		 */
1487 		/* .name = "Capture Source", */
1488 		.name = "Input Source",
1489 		.count = 1,
1490 		.info = via_mux_enum_info,
1491 		.get = via_mux_enum_get,
1492 		.put = via_mux_enum_put,
1493 	},
1494 	{ } /* end */
1495 };
1496 /*
1497  * generic initialization of ADC, input mixers and output mixers
1498  */
1499 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
1500 	/*
1501 	 * Unmute ADC0-1 and set the default input to mic-in
1502 	 */
1503 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1504 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1505 
1506 
1507 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1508 	 * mixer widget
1509 	 */
1510 	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1511 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1512 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1513 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1514 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1515 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1516 
1517 	/*
1518 	 * Set up output mixers
1519 	 */
1520 	/* set vol=0 to output mixers */
1521 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1522 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1523 	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1524 
1525 	/* Setup default input to PW4 */
1526 	{0x1d, AC_VERB_SET_CONNECT_SEL, 0x1},
1527 	/* PW9 Output enable */
1528 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1529 	/* PW10 Input enable */
1530 	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1531 	{ }
1532 };
1533 
1534 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
1535 	/*
1536 	 * Unmute ADC0-1 and set the default input to mic-in
1537 	 */
1538 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1539 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1540 
1541 
1542 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1543 	 * mixer widget
1544 	 */
1545 	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1546 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1547 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1548 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1549 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1550 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1551 
1552 	/*
1553 	 * Set up output mixers
1554 	 */
1555 	/* set vol=0 to output mixers */
1556 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1557 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1558 	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1559 
1560 	/* Setup default input of PW4 to MW0 */
1561 	{0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
1562 	/* PW9 Output enable */
1563 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1564 	/* PW10 Input enable */
1565 	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1566 	{ }
1567 };
1568 
1569 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
1570 	.substreams = 1,
1571 	.channels_min = 2,
1572 	.channels_max = 8,
1573 	.nid = 0x10, /* NID to query formats and rates */
1574 	.ops = {
1575 		.open = via_playback_pcm_open,
1576 		.prepare = via_playback_pcm_prepare,
1577 		.cleanup = via_playback_pcm_cleanup
1578 	},
1579 };
1580 
1581 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
1582 	.substreams = 1,
1583 	.channels_min = 2,
1584 	.channels_max = 4,
1585 	.nid = 0x10, /* NID to query formats and rates */
1586 	.ops = {
1587 		.open = via_playback_pcm_open,
1588 		.prepare = via_playback_pcm_prepare,
1589 		.cleanup = via_playback_pcm_cleanup
1590 	},
1591 };
1592 
1593 static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
1594 	.substreams = 2,
1595 	.channels_min = 2,
1596 	.channels_max = 2,
1597 	.nid = 0x13, /* NID to query formats and rates */
1598 	.ops = {
1599 		.prepare = via_capture_pcm_prepare,
1600 		.cleanup = via_capture_pcm_cleanup
1601 	},
1602 };
1603 
1604 static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
1605 	.substreams = 1,
1606 	.channels_min = 2,
1607 	.channels_max = 2,
1608 	/* NID is set in via_build_pcms */
1609 	.ops = {
1610 		.open = via_dig_playback_pcm_open,
1611 		.close = via_dig_playback_pcm_close,
1612 		.prepare = via_dig_playback_pcm_prepare
1613 	},
1614 };
1615 
1616 static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
1617 	.substreams = 1,
1618 	.channels_min = 2,
1619 	.channels_max = 2,
1620 };
1621 
1622 /* fill in the dac_nids table from the parsed pin configuration */
1623 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
1624 				     const struct auto_pin_cfg *cfg)
1625 {
1626 	int i;
1627 	hda_nid_t nid;
1628 
1629 	spec->multiout.num_dacs = cfg->line_outs;
1630 
1631 	spec->multiout.dac_nids = spec->private_dac_nids;
1632 
1633 	for (i = 0; i < 4; i++) {
1634 		nid = cfg->line_out_pins[i];
1635 		if (nid) {
1636 			/* config dac list */
1637 			switch (i) {
1638 			case AUTO_SEQ_FRONT:
1639 				spec->multiout.dac_nids[i] = 0x10;
1640 				break;
1641 			case AUTO_SEQ_CENLFE:
1642 				spec->multiout.dac_nids[i] = 0x24;
1643 				break;
1644 			case AUTO_SEQ_SURROUND:
1645 				spec->multiout.dac_nids[i] = 0x25;
1646 				break;
1647 			case AUTO_SEQ_SIDE:
1648 				spec->multiout.dac_nids[i] = 0x11;
1649 				break;
1650 			}
1651 		}
1652 	}
1653 
1654 	return 0;
1655 }
1656 
1657 /* add playback controls from the parsed DAC table */
1658 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
1659 					     const struct auto_pin_cfg *cfg)
1660 {
1661 	char name[32];
1662 	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1663 	hda_nid_t nid_vols[] = {0x16, 0x27, 0x26, 0x18};
1664 	hda_nid_t nid, nid_vol = 0;
1665 	int i, err;
1666 
1667 	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1668 		nid = cfg->line_out_pins[i];
1669 
1670 		if (!nid)
1671 			continue;
1672 
1673 		nid_vol = nid_vols[i];
1674 
1675 		if (i == AUTO_SEQ_CENLFE) {
1676 			/* Center/LFE */
1677 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1678 					      "Center Playback Volume",
1679 					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1680 								  HDA_OUTPUT));
1681 			if (err < 0)
1682 				return err;
1683 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1684 					      "LFE Playback Volume",
1685 					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1686 								  HDA_OUTPUT));
1687 			if (err < 0)
1688 				return err;
1689 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1690 					      "Center Playback Switch",
1691 					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1692 								  HDA_OUTPUT));
1693 			if (err < 0)
1694 				return err;
1695 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1696 					      "LFE Playback Switch",
1697 					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1698 								  HDA_OUTPUT));
1699 			if (err < 0)
1700 				return err;
1701 		} else if (i == AUTO_SEQ_FRONT) {
1702 			/* add control to mixer index 0 */
1703 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1704 					      "Master Front Playback Volume",
1705 					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1706 								  HDA_INPUT));
1707 			if (err < 0)
1708 				return err;
1709 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1710 					      "Master Front Playback Switch",
1711 					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1712 								  HDA_INPUT));
1713 			if (err < 0)
1714 				return err;
1715 
1716 			/* add control to PW3 */
1717 			sprintf(name, "%s Playback Volume", chname[i]);
1718 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1719 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1720 								  HDA_OUTPUT));
1721 			if (err < 0)
1722 				return err;
1723 			sprintf(name, "%s Playback Switch", chname[i]);
1724 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1725 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1726 								  HDA_OUTPUT));
1727 			if (err < 0)
1728 				return err;
1729 		} else {
1730 			sprintf(name, "%s Playback Volume", chname[i]);
1731 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1732 					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1733 								  HDA_OUTPUT));
1734 			if (err < 0)
1735 				return err;
1736 			sprintf(name, "%s Playback Switch", chname[i]);
1737 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1738 					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1739 								  HDA_OUTPUT));
1740 			if (err < 0)
1741 				return err;
1742 		}
1743 	}
1744 
1745 	return 0;
1746 }
1747 
1748 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1749 {
1750 	int err;
1751 
1752 	if (!pin)
1753 		return 0;
1754 
1755 	spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
1756 
1757 	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1758 			      "Headphone Playback Volume",
1759 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1760 	if (err < 0)
1761 		return err;
1762 	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1763 			      "Headphone Playback Switch",
1764 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1765 	if (err < 0)
1766 		return err;
1767 
1768 	return 0;
1769 }
1770 
1771 /* create playback/capture controls for input pins */
1772 static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
1773 						const struct auto_pin_cfg *cfg)
1774 {
1775 	static char *labels[] = {
1776 		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1777 	};
1778 	struct hda_input_mux *imux = &spec->private_imux;
1779 	int i, err, idx = 0;
1780 
1781 	/* for internal loopback recording select */
1782 	imux->items[imux->num_items].label = "Stereo Mixer";
1783 	imux->items[imux->num_items].index = idx;
1784 	imux->num_items++;
1785 
1786 	for (i = 0; i < AUTO_PIN_LAST; i++) {
1787 		if (!cfg->input_pins[i])
1788 			continue;
1789 
1790 		switch (cfg->input_pins[i]) {
1791 		case 0x1a: /* Mic */
1792 			idx = 2;
1793 			break;
1794 
1795 		case 0x1b: /* Line In */
1796 			idx = 3;
1797 			break;
1798 
1799 		case 0x1e: /* Front Mic */
1800 			idx = 4;
1801 			break;
1802 
1803 		case 0x1f: /* CD */
1804 			idx = 1;
1805 			break;
1806 		}
1807 		err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1808 					   idx, 0x16);
1809 		if (err < 0)
1810 			return err;
1811 		imux->items[imux->num_items].label = labels[i];
1812 		imux->items[imux->num_items].index = idx;
1813 		imux->num_items++;
1814 	}
1815 	return 0;
1816 }
1817 
1818 static int vt1708B_parse_auto_config(struct hda_codec *codec)
1819 {
1820 	struct via_spec *spec = codec->spec;
1821 	int err;
1822 
1823 	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1824 	if (err < 0)
1825 		return err;
1826 	err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
1827 	if (err < 0)
1828 		return err;
1829 	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1830 		return 0; /* can't find valid BIOS pin config */
1831 
1832 	err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
1833 	if (err < 0)
1834 		return err;
1835 	err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1836 	if (err < 0)
1837 		return err;
1838 	err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
1839 	if (err < 0)
1840 		return err;
1841 
1842 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1843 
1844 	if (spec->autocfg.dig_out_pin)
1845 		spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
1846 	if (spec->autocfg.dig_in_pin)
1847 		spec->dig_in_nid = VT1708B_DIGIN_NID;
1848 
1849 	if (spec->kctl_alloc)
1850 		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1851 
1852 	spec->input_mux = &spec->private_imux;
1853 
1854 	return 1;
1855 }
1856 
1857 #ifdef CONFIG_SND_HDA_POWER_SAVE
1858 static struct hda_amp_list vt1708B_loopbacks[] = {
1859 	{ 0x16, HDA_INPUT, 1 },
1860 	{ 0x16, HDA_INPUT, 2 },
1861 	{ 0x16, HDA_INPUT, 3 },
1862 	{ 0x16, HDA_INPUT, 4 },
1863 	{ } /* end */
1864 };
1865 #endif
1866 
1867 static int patch_vt1708B_8ch(struct hda_codec *codec)
1868 {
1869 	struct via_spec *spec;
1870 	int err;
1871 
1872 	/* create a codec specific record */
1873 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1874 	if (spec == NULL)
1875 		return -ENOMEM;
1876 
1877 	codec->spec = spec;
1878 
1879 	/* automatic parse from the BIOS config */
1880 	err = vt1708B_parse_auto_config(codec);
1881 	if (err < 0) {
1882 		via_free(codec);
1883 		return err;
1884 	} else if (!err) {
1885 		printk(KERN_INFO "hda_codec: Cannot set up configuration "
1886 		       "from BIOS.  Using genenic mode...\n");
1887 	}
1888 
1889 	spec->init_verbs = vt1708B_8ch_volume_init_verbs;
1890 
1891 	spec->stream_name_analog = "VT1708B Analog";
1892 	spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
1893 	spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
1894 
1895 	spec->stream_name_digital = "VT1708B Digital";
1896 	spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
1897 	spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
1898 
1899 	if (!spec->adc_nids && spec->input_mux) {
1900 		spec->adc_nids = vt1708B_adc_nids;
1901 		spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
1902 		spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
1903 		spec->num_mixers++;
1904 	}
1905 
1906 	codec->patch_ops = via_patch_ops;
1907 
1908 	codec->patch_ops.init = via_auto_init;
1909 #ifdef CONFIG_SND_HDA_POWER_SAVE
1910 	spec->loopback.amplist = vt1708B_loopbacks;
1911 #endif
1912 
1913 	return 0;
1914 }
1915 
1916 static int patch_vt1708B_4ch(struct hda_codec *codec)
1917 {
1918 	struct via_spec *spec;
1919 	int err;
1920 
1921 	/* create a codec specific record */
1922 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1923 	if (spec == NULL)
1924 		return -ENOMEM;
1925 
1926 	codec->spec = spec;
1927 
1928 	/* automatic parse from the BIOS config */
1929 	err = vt1708B_parse_auto_config(codec);
1930 	if (err < 0) {
1931 		via_free(codec);
1932 		return err;
1933 	} else if (!err) {
1934 		printk(KERN_INFO "hda_codec: Cannot set up configuration "
1935 		       "from BIOS.  Using genenic mode...\n");
1936 	}
1937 
1938 	spec->init_verbs = vt1708B_4ch_volume_init_verbs;
1939 
1940 	spec->stream_name_analog = "VT1708B Analog";
1941 	spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
1942 	spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
1943 
1944 	spec->stream_name_digital = "VT1708B Digital";
1945 	spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
1946 	spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
1947 
1948 	if (!spec->adc_nids && spec->input_mux) {
1949 		spec->adc_nids = vt1708B_adc_nids;
1950 		spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
1951 		spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
1952 		spec->num_mixers++;
1953 	}
1954 
1955 	codec->patch_ops = via_patch_ops;
1956 
1957 	codec->patch_ops.init = via_auto_init;
1958 #ifdef CONFIG_SND_HDA_POWER_SAVE
1959 	spec->loopback.amplist = vt1708B_loopbacks;
1960 #endif
1961 
1962 	return 0;
1963 }
1964 
1965 /*
1966  * patch entries
1967  */
1968 struct hda_codec_preset snd_hda_preset_via[] = {
1969 	{ .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708},
1970 	{ .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708},
1971 	{ .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708},
1972 	{ .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708},
1973 	{ .id = 0x1106E710, .name = "VIA VT1709 10-Ch",
1974 	  .patch = patch_vt1709_10ch},
1975 	{ .id = 0x1106E711, .name = "VIA VT1709 10-Ch",
1976 	  .patch = patch_vt1709_10ch},
1977 	{ .id = 0x1106E712, .name = "VIA VT1709 10-Ch",
1978 	  .patch = patch_vt1709_10ch},
1979 	{ .id = 0x1106E713, .name = "VIA VT1709 10-Ch",
1980 	  .patch = patch_vt1709_10ch},
1981 	{ .id = 0x1106E714, .name = "VIA VT1709 6-Ch",
1982 	  .patch = patch_vt1709_6ch},
1983 	{ .id = 0x1106E715, .name = "VIA VT1709 6-Ch",
1984 	  .patch = patch_vt1709_6ch},
1985 	{ .id = 0x1106E716, .name = "VIA VT1709 6-Ch",
1986 	  .patch = patch_vt1709_6ch},
1987 	{ .id = 0x1106E717, .name = "VIA VT1709 6-Ch",
1988 	  .patch = patch_vt1709_6ch},
1989 	{ .id = 0x1106E720, .name = "VIA VT1708B 8-Ch",
1990 	  .patch = patch_vt1708B_8ch},
1991 	{ .id = 0x1106E721, .name = "VIA VT1708B 8-Ch",
1992 	  .patch = patch_vt1708B_8ch},
1993 	{ .id = 0x1106E722, .name = "VIA VT1708B 8-Ch",
1994 	  .patch = patch_vt1708B_8ch},
1995 	{ .id = 0x1106E723, .name = "VIA VT1708B 8-Ch",
1996 	  .patch = patch_vt1708B_8ch},
1997 	{ .id = 0x1106E724, .name = "VIA VT1708B 4-Ch",
1998 	  .patch = patch_vt1708B_4ch},
1999 	{ .id = 0x1106E725, .name = "VIA VT1708B 4-Ch",
2000 	  .patch = patch_vt1708B_4ch},
2001 	{ .id = 0x1106E726, .name = "VIA VT1708B 4-Ch",
2002 	  .patch = patch_vt1708B_4ch},
2003 	{ .id = 0x1106E727, .name = "VIA VT1708B 4-Ch",
2004 	  .patch = patch_vt1708B_4ch},
2005 	{} /* terminator */
2006 };
2007