xref: /openbmc/linux/sound/pci/hda/patch_via.c (revision 96de0e252cedffad61b3cb5e05662c591898e69a)
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 /*                                                                           */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
33 
34 #include <sound/driver.h>
35 #include <linux/init.h>
36 #include <linux/delay.h>
37 #include <linux/slab.h>
38 #include <sound/core.h>
39 #include "hda_codec.h"
40 #include "hda_local.h"
41 
42 
43 /* amp values */
44 #define AMP_VAL_IDX_SHIFT	19
45 #define AMP_VAL_IDX_MASK	(0x0f<<19)
46 
47 #define NUM_CONTROL_ALLOC	32
48 #define NUM_VERB_ALLOC		32
49 
50 /* Pin Widget NID */
51 #define VT1708_HP_NID		0x13
52 #define VT1708_DIGOUT_NID	0x14
53 #define VT1708_DIGIN_NID	0x16
54 
55 #define VT1709_HP_DAC_NID	0x28
56 #define VT1709_DIGOUT_NID	0x13
57 #define VT1709_DIGIN_NID	0x17
58 
59 #define IS_VT1708_VENDORID(x)		((x) >= 0x11061708 && (x) <= 0x1106170b)
60 #define IS_VT1709_10CH_VENDORID(x)	((x) >= 0x1106e710 && (x) <= 0x1106e713)
61 #define IS_VT1709_6CH_VENDORID(x)	((x) >= 0x1106e714 && (x) <= 0x1106e717)
62 
63 
64 enum {
65 	VIA_CTL_WIDGET_VOL,
66 	VIA_CTL_WIDGET_MUTE,
67 };
68 
69 enum {
70 	AUTO_SEQ_FRONT,
71 	AUTO_SEQ_SURROUND,
72 	AUTO_SEQ_CENLFE,
73 	AUTO_SEQ_SIDE
74 };
75 
76 static struct snd_kcontrol_new vt1708_control_templates[] = {
77 	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
78 	HDA_CODEC_MUTE(NULL, 0, 0, 0),
79 };
80 
81 
82 struct via_spec {
83 	/* codec parameterization */
84 	struct snd_kcontrol_new *mixers[3];
85 	unsigned int num_mixers;
86 
87 	struct hda_verb *init_verbs;
88 
89 	char *stream_name_analog;
90 	struct hda_pcm_stream *stream_analog_playback;
91 	struct hda_pcm_stream *stream_analog_capture;
92 
93 	char *stream_name_digital;
94 	struct hda_pcm_stream *stream_digital_playback;
95 	struct hda_pcm_stream *stream_digital_capture;
96 
97 	/* playback */
98 	struct hda_multi_out multiout;
99 
100 	/* capture */
101 	unsigned int num_adc_nids;
102 	hda_nid_t *adc_nids;
103 	hda_nid_t dig_in_nid;
104 
105 	/* capture source */
106 	const struct hda_input_mux *input_mux;
107 	unsigned int cur_mux[3];
108 
109 	/* PCM information */
110 	struct hda_pcm pcm_rec[2];
111 
112 	/* dynamic controls, init_verbs and input_mux */
113 	struct auto_pin_cfg autocfg;
114 	unsigned int num_kctl_alloc, num_kctl_used;
115 	struct snd_kcontrol_new *kctl_alloc;
116 	struct hda_input_mux private_imux;
117 	hda_nid_t private_dac_nids[4];
118 
119 #ifdef CONFIG_SND_HDA_POWER_SAVE
120 	struct hda_loopback_check loopback;
121 #endif
122 };
123 
124 static hda_nid_t vt1708_adc_nids[2] = {
125 	/* ADC1-2 */
126 	0x15, 0x27
127 };
128 
129 static hda_nid_t vt1709_adc_nids[3] = {
130 	/* ADC1-2 */
131 	0x14, 0x15, 0x16
132 };
133 
134 /* add dynamic controls */
135 static int via_add_control(struct via_spec *spec, int type, const char *name,
136 			   unsigned long val)
137 {
138 	struct snd_kcontrol_new *knew;
139 
140 	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
141 		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
142 
143 		/* array + terminator */
144 		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
145 		if (!knew)
146 			return -ENOMEM;
147 		if (spec->kctl_alloc) {
148 			memcpy(knew, spec->kctl_alloc,
149 			       sizeof(*knew) * spec->num_kctl_alloc);
150 			kfree(spec->kctl_alloc);
151 		}
152 		spec->kctl_alloc = knew;
153 		spec->num_kctl_alloc = num;
154 	}
155 
156 	knew = &spec->kctl_alloc[spec->num_kctl_used];
157 	*knew = vt1708_control_templates[type];
158 	knew->name = kstrdup(name, GFP_KERNEL);
159 
160 	if (!knew->name)
161 		return -ENOMEM;
162 	knew->private_value = val;
163 	spec->num_kctl_used++;
164 	return 0;
165 }
166 
167 /* create input playback/capture controls for the given pin */
168 static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
169 				const char *ctlname, int idx, int mix_nid)
170 {
171 	char name[32];
172 	int err;
173 
174 	sprintf(name, "%s Playback Volume", ctlname);
175 	err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
176 			      HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
177 	if (err < 0)
178 		return err;
179 	sprintf(name, "%s Playback Switch", ctlname);
180 	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
181 			      HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
182 	if (err < 0)
183 		return err;
184 	return 0;
185 }
186 
187 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
188 					   hda_nid_t nid, int pin_type,
189 					   int dac_idx)
190 {
191 	/* set as output */
192 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
193 			    pin_type);
194 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
195 			    AMP_OUT_UNMUTE);
196 }
197 
198 
199 static void via_auto_init_multi_out(struct hda_codec *codec)
200 {
201 	struct via_spec *spec = codec->spec;
202 	int i;
203 
204 	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
205 		hda_nid_t nid = spec->autocfg.line_out_pins[i];
206 		if (nid)
207 			via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
208 	}
209 }
210 
211 static void via_auto_init_hp_out(struct hda_codec *codec)
212 {
213 	struct via_spec *spec = codec->spec;
214 	hda_nid_t pin;
215 
216 	pin = spec->autocfg.hp_pins[0];
217 	if (pin) /* connect to front */
218 		via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
219 }
220 
221 static void via_auto_init_analog_input(struct hda_codec *codec)
222 {
223 	struct via_spec *spec = codec->spec;
224 	int i;
225 
226 	for (i = 0; i < AUTO_PIN_LAST; i++) {
227 		hda_nid_t nid = spec->autocfg.input_pins[i];
228 
229 		snd_hda_codec_write(codec, nid, 0,
230 				    AC_VERB_SET_PIN_WIDGET_CONTROL,
231 				    (i <= AUTO_PIN_FRONT_MIC ?
232 				     PIN_VREF50 : PIN_IN));
233 
234 	}
235 }
236 /*
237  * input MUX handling
238  */
239 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
240 			     struct snd_ctl_elem_info *uinfo)
241 {
242 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
243 	struct via_spec *spec = codec->spec;
244 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
245 }
246 
247 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
248 			    struct snd_ctl_elem_value *ucontrol)
249 {
250 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
251 	struct via_spec *spec = codec->spec;
252 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
253 
254 	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
255 	return 0;
256 }
257 
258 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
259 			    struct snd_ctl_elem_value *ucontrol)
260 {
261 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
262 	struct via_spec *spec = codec->spec;
263 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
264 	unsigned int vendor_id = codec->vendor_id;
265 
266 	/* AIW0  lydia 060801 add for correct sw0 input select */
267 	if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0))
268 		return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
269 					     0x18, &spec->cur_mux[adc_idx]);
270 	else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
271 		  IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0) )
272 		return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
273 					     0x19, &spec->cur_mux[adc_idx]);
274 	else
275 		return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
276 					     spec->adc_nids[adc_idx],
277 					     &spec->cur_mux[adc_idx]);
278 }
279 
280 /* capture mixer elements */
281 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
282 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
283 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
284 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
285 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
286 	{
287 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
288 		/* The multiple "Capture Source" controls confuse alsamixer
289 		 * So call somewhat different..
290 		 * FIXME: the controls appear in the "playback" view!
291 		 */
292 		/* .name = "Capture Source", */
293 		.name = "Input Source",
294 		.count = 1,
295 		.info = via_mux_enum_info,
296 		.get = via_mux_enum_get,
297 		.put = via_mux_enum_put,
298 	},
299 	{ } /* end */
300 };
301 /*
302  * generic initialization of ADC, input mixers and output mixers
303  */
304 static struct hda_verb vt1708_volume_init_verbs[] = {
305 	/*
306 	 * Unmute ADC0-1 and set the default input to mic-in
307 	 */
308 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
309 	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
310 
311 
312 	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
313 	 * mixer widget
314 	 */
315 	/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
316 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* master */
317 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
318 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
319 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
320 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
321 
322 	/*
323 	 * Set up output mixers (0x19 - 0x1b)
324 	 */
325 	/* set vol=0 to output mixers */
326 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
327 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
328 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
329 
330 	/* Setup default input to PW4 */
331 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
332 	/* Set mic as default input of sw0 */
333 	{0x18, AC_VERB_SET_CONNECT_SEL, 0x2},
334 	/* PW9 Output enable */
335 	{0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
336 };
337 
338 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
339 				 struct hda_codec *codec,
340 				 struct snd_pcm_substream *substream)
341 {
342 	struct via_spec *spec = codec->spec;
343 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
344 }
345 
346 static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
347 				    struct hda_codec *codec,
348 				    unsigned int stream_tag,
349 				    unsigned int format,
350 				    struct snd_pcm_substream *substream)
351 {
352 	struct via_spec *spec = codec->spec;
353 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
354 						stream_tag, format, substream);
355 }
356 
357 static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
358 				    struct hda_codec *codec,
359 				    struct snd_pcm_substream *substream)
360 {
361 	struct via_spec *spec = codec->spec;
362 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
363 }
364 
365 /*
366  * Digital out
367  */
368 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
369 				     struct hda_codec *codec,
370 				     struct snd_pcm_substream *substream)
371 {
372 	struct via_spec *spec = codec->spec;
373 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
374 }
375 
376 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
377 				      struct hda_codec *codec,
378 				      struct snd_pcm_substream *substream)
379 {
380 	struct via_spec *spec = codec->spec;
381 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
382 }
383 
384 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
385 					struct hda_codec *codec,
386 					unsigned int stream_tag,
387 					unsigned int format,
388 					struct snd_pcm_substream *substream)
389 {
390 	struct via_spec *spec = codec->spec;
391 	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
392 					     stream_tag, format, substream);
393 }
394 
395 /*
396  * Analog capture
397  */
398 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
399 				   struct hda_codec *codec,
400 				   unsigned int stream_tag,
401 				   unsigned int format,
402 				   struct snd_pcm_substream *substream)
403 {
404 	struct via_spec *spec = codec->spec;
405 
406 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
407 				   stream_tag, 0, format);
408 	return 0;
409 }
410 
411 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
412 				   struct hda_codec *codec,
413 				   struct snd_pcm_substream *substream)
414 {
415 	struct via_spec *spec = codec->spec;
416 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
417 				   0, 0, 0);
418 	return 0;
419 }
420 
421 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
422 	.substreams = 1,
423 	.channels_min = 2,
424 	.channels_max = 8,
425 	.nid = 0x10, /* NID to query formats and rates */
426 	.ops = {
427 		.open = via_playback_pcm_open,
428 		.prepare = via_playback_pcm_prepare,
429 		.cleanup = via_playback_pcm_cleanup
430 	},
431 };
432 
433 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
434 	.substreams = 2,
435 	.channels_min = 2,
436 	.channels_max = 2,
437 	.nid = 0x15, /* NID to query formats and rates */
438 	.ops = {
439 		.prepare = via_capture_pcm_prepare,
440 		.cleanup = via_capture_pcm_cleanup
441 	},
442 };
443 
444 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
445 	.substreams = 1,
446 	.channels_min = 2,
447 	.channels_max = 2,
448 	/* NID is set in via_build_pcms */
449 	.ops = {
450 		.open = via_dig_playback_pcm_open,
451 		.close = via_dig_playback_pcm_close,
452 		.prepare = via_dig_playback_pcm_prepare
453 	},
454 };
455 
456 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
457 	.substreams = 1,
458 	.channels_min = 2,
459 	.channels_max = 2,
460 };
461 
462 static int via_build_controls(struct hda_codec *codec)
463 {
464 	struct via_spec *spec = codec->spec;
465 	int err;
466 	int i;
467 
468 	for (i = 0; i < spec->num_mixers; i++) {
469 		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
470 		if (err < 0)
471 			return err;
472 	}
473 
474 	if (spec->multiout.dig_out_nid) {
475 		err = snd_hda_create_spdif_out_ctls(codec,
476 						    spec->multiout.dig_out_nid);
477 		if (err < 0)
478 			return err;
479 	}
480 	if (spec->dig_in_nid) {
481 		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
482 		if (err < 0)
483 			return err;
484 	}
485 	return 0;
486 }
487 
488 static int via_build_pcms(struct hda_codec *codec)
489 {
490 	struct via_spec *spec = codec->spec;
491 	struct hda_pcm *info = spec->pcm_rec;
492 
493 	codec->num_pcms = 1;
494 	codec->pcm_info = info;
495 
496 	info->name = spec->stream_name_analog;
497 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
498 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
499 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
500 	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
501 
502 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
503 		spec->multiout.max_channels;
504 
505 	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
506 		codec->num_pcms++;
507 		info++;
508 		info->name = spec->stream_name_digital;
509 		if (spec->multiout.dig_out_nid) {
510 			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
511 				*(spec->stream_digital_playback);
512 			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
513 				spec->multiout.dig_out_nid;
514 		}
515 		if (spec->dig_in_nid) {
516 			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
517 				*(spec->stream_digital_capture);
518 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
519 				spec->dig_in_nid;
520 		}
521 	}
522 
523 	return 0;
524 }
525 
526 static void via_free(struct hda_codec *codec)
527 {
528 	struct via_spec *spec = codec->spec;
529 	unsigned int i;
530 
531 	if (!spec)
532 		return;
533 
534 	if (spec->kctl_alloc) {
535 		for (i = 0; i < spec->num_kctl_used; i++)
536 			kfree(spec->kctl_alloc[i].name);
537 		kfree(spec->kctl_alloc);
538 	}
539 
540 	kfree(codec->spec);
541 }
542 
543 static int via_init(struct hda_codec *codec)
544 {
545 	struct via_spec *spec = codec->spec;
546 	snd_hda_sequence_write(codec, spec->init_verbs);
547  	return 0;
548 }
549 
550 #ifdef CONFIG_SND_HDA_POWER_SAVE
551 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
552 {
553 	struct via_spec *spec = codec->spec;
554 	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
555 }
556 #endif
557 
558 /*
559  */
560 static struct hda_codec_ops via_patch_ops = {
561 	.build_controls = via_build_controls,
562 	.build_pcms = via_build_pcms,
563 	.init = via_init,
564 	.free = via_free,
565 #ifdef CONFIG_SND_HDA_POWER_SAVE
566 	.check_power_status = via_check_power_status,
567 #endif
568 };
569 
570 /* fill in the dac_nids table from the parsed pin configuration */
571 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
572 				     const struct auto_pin_cfg *cfg)
573 {
574 	int i;
575 	hda_nid_t nid;
576 
577 	spec->multiout.num_dacs = cfg->line_outs;
578 
579 	spec->multiout.dac_nids = spec->private_dac_nids;
580 
581 	for(i = 0; i < 4; i++) {
582 		nid = cfg->line_out_pins[i];
583 		if (nid) {
584 			/* config dac list */
585 			switch (i) {
586 			case AUTO_SEQ_FRONT:
587 				spec->multiout.dac_nids[i] = 0x10;
588 				break;
589 			case AUTO_SEQ_CENLFE:
590 				spec->multiout.dac_nids[i] = 0x12;
591 				break;
592 			case AUTO_SEQ_SURROUND:
593 				spec->multiout.dac_nids[i] = 0x13;
594 				break;
595 			case AUTO_SEQ_SIDE:
596 				spec->multiout.dac_nids[i] = 0x11;
597 				break;
598 			}
599 		}
600 	}
601 
602 	return 0;
603 }
604 
605 /* add playback controls from the parsed DAC table */
606 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
607 					     const struct auto_pin_cfg *cfg)
608 {
609 	char name[32];
610 	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
611 	hda_nid_t nid, nid_vol = 0;
612 	int i, err;
613 
614 	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
615 		nid = cfg->line_out_pins[i];
616 
617 		if (!nid)
618 			continue;
619 
620 		if (i != AUTO_SEQ_FRONT)
621 			nid_vol = 0x1b - i + 1;
622 
623 		if (i == AUTO_SEQ_CENLFE) {
624 			/* Center/LFE */
625 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
626 					      "Center Playback Volume",
627 					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
628 			if (err < 0)
629 				return err;
630 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
631 					      "LFE Playback Volume",
632 					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
633 			if (err < 0)
634 				return err;
635 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
636 					      "Center Playback Switch",
637 					      HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
638 			if (err < 0)
639 				return err;
640 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
641 					      "LFE Playback Switch",
642 					      HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
643 			if (err < 0)
644 				return err;
645 		} else if (i == AUTO_SEQ_FRONT){
646 			/* add control to mixer index 0 */
647 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
648 					      "Master Front Playback Volume",
649 					      HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT));
650 			if (err < 0)
651 				return err;
652 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
653 					      "Master Front Playback Switch",
654 					      HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT));
655 			if (err < 0)
656 				return err;
657 
658 			/* add control to PW3 */
659 			sprintf(name, "%s Playback Volume", chname[i]);
660 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
661 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
662 			if (err < 0)
663 				return err;
664 			sprintf(name, "%s Playback Switch", chname[i]);
665 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
666 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
667 			if (err < 0)
668 				return err;
669 		} else {
670 			sprintf(name, "%s Playback Volume", chname[i]);
671 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
672 					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
673 			if (err < 0)
674 				return err;
675 			sprintf(name, "%s Playback Switch", chname[i]);
676 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
677 					      HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
678 			if (err < 0)
679 				return err;
680 		}
681 	}
682 
683 	return 0;
684 }
685 
686 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
687 {
688 	int err;
689 
690 	if (!pin)
691 		return 0;
692 
693 	spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
694 
695 	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
696 			      "Headphone Playback Volume",
697 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
698 	if (err < 0)
699 		return err;
700 	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
701 			      "Headphone Playback Switch",
702 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
703 	if (err < 0)
704 		return err;
705 
706 	return 0;
707 }
708 
709 /* create playback/capture controls for input pins */
710 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
711 						const struct auto_pin_cfg *cfg)
712 {
713 	static char *labels[] = {
714 		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
715 	};
716 	struct hda_input_mux *imux = &spec->private_imux;
717 	int i, err, idx = 0;
718 
719 	/* for internal loopback recording select */
720 	imux->items[imux->num_items].label = "Stereo Mixer";
721 	imux->items[imux->num_items].index = idx;
722 	imux->num_items++;
723 
724 	for (i = 0; i < AUTO_PIN_LAST; i++) {
725 		if (!cfg->input_pins[i])
726 			continue;
727 
728 		switch (cfg->input_pins[i]) {
729 		case 0x1d: /* Mic */
730 			idx = 2;
731 			break;
732 
733 		case 0x1e: /* Line In */
734 			idx = 3;
735 			break;
736 
737 		case 0x21: /* Front Mic */
738 			idx = 4;
739 			break;
740 
741 		case 0x24: /* CD */
742 			idx = 1;
743 			break;
744 		}
745 		err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
746 					   idx, 0x17);
747 		if (err < 0)
748 			return err;
749 		imux->items[imux->num_items].label = labels[i];
750 		imux->items[imux->num_items].index = idx;
751 		imux->num_items++;
752 	}
753 	return 0;
754 }
755 
756 #ifdef CONFIG_SND_HDA_POWER_SAVE
757 static struct hda_amp_list vt1708_loopbacks[] = {
758 	{ 0x17, HDA_INPUT, 1 },
759 	{ 0x17, HDA_INPUT, 2 },
760 	{ 0x17, HDA_INPUT, 3 },
761 	{ 0x17, HDA_INPUT, 4 },
762 	{ } /* end */
763 };
764 #endif
765 
766 static int vt1708_parse_auto_config(struct hda_codec *codec)
767 {
768 	struct via_spec *spec = codec->spec;
769 	int err;
770 
771 	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
772 	if (err < 0)
773 		return err;
774 	err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
775 	if (err < 0)
776 		return err;
777 	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
778 		return 0; /* can't find valid BIOS pin config */
779 
780 	err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
781 	if (err < 0)
782 		return err;
783 	err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
784 	if (err < 0)
785 		return err;
786 	err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
787 	if (err < 0)
788 		return err;
789 
790 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
791 
792 	if (spec->autocfg.dig_out_pin)
793 		spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
794 	if (spec->autocfg.dig_in_pin)
795 		spec->dig_in_nid = VT1708_DIGIN_NID;
796 
797 	if (spec->kctl_alloc)
798 		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
799 
800 	spec->init_verbs = vt1708_volume_init_verbs;
801 
802 	spec->input_mux = &spec->private_imux;
803 
804 	return 1;
805 }
806 
807 /* init callback for auto-configuration model -- overriding the default init */
808 static int via_auto_init(struct hda_codec *codec)
809 {
810 	via_init(codec);
811 	via_auto_init_multi_out(codec);
812 	via_auto_init_hp_out(codec);
813 	via_auto_init_analog_input(codec);
814 	return 0;
815 }
816 
817 static int patch_vt1708(struct hda_codec *codec)
818 {
819 	struct via_spec *spec;
820 	int err;
821 
822 	/* create a codec specific record */
823 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
824 	if (spec == NULL)
825 		return -ENOMEM;
826 
827 	codec->spec = spec;
828 
829 	/* automatic parse from the BIOS config */
830 	err = vt1708_parse_auto_config(codec);
831 	if (err < 0) {
832 		via_free(codec);
833 		return err;
834 	} else if (!err) {
835 		printk(KERN_INFO "hda_codec: Cannot set up configuration "
836 		       "from BIOS.  Using genenic mode...\n");
837 	}
838 
839 
840 	spec->stream_name_analog = "VT1708 Analog";
841 	spec->stream_analog_playback = &vt1708_pcm_analog_playback;
842 	spec->stream_analog_capture = &vt1708_pcm_analog_capture;
843 
844 	spec->stream_name_digital = "VT1708 Digital";
845 	spec->stream_digital_playback = &vt1708_pcm_digital_playback;
846 	spec->stream_digital_capture = &vt1708_pcm_digital_capture;
847 
848 
849 	if (!spec->adc_nids && spec->input_mux) {
850 		spec->adc_nids = vt1708_adc_nids;
851 		spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
852 		spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
853 		spec->num_mixers++;
854 	}
855 
856 	codec->patch_ops = via_patch_ops;
857 
858 	codec->patch_ops.init = via_auto_init;
859 #ifdef CONFIG_SND_HDA_POWER_SAVE
860 	spec->loopback.amplist = vt1708_loopbacks;
861 #endif
862 
863 	return 0;
864 }
865 
866 /* capture mixer elements */
867 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
868 	HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
869 	HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
870 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
871 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
872 	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
873 	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
874 	{
875 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
876 		/* The multiple "Capture Source" controls confuse alsamixer
877 		 * So call somewhat different..
878 		 * FIXME: the controls appear in the "playback" view!
879 		 */
880 		/* .name = "Capture Source", */
881 		.name = "Input Source",
882 		.count = 1,
883 		.info = via_mux_enum_info,
884 		.get = via_mux_enum_get,
885 		.put = via_mux_enum_put,
886 	},
887 	{ } /* end */
888 };
889 
890 /*
891  * generic initialization of ADC, input mixers and output mixers
892  */
893 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
894 	/*
895 	 * Unmute ADC0-2 and set the default input to mic-in
896 	 */
897 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
898 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
899 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
900 
901 
902 	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
903 	 * mixer widget
904 	 */
905 	/* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
906 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* unmute master */
907 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
908 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
909 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
910 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
911 
912 	/*
913 	 * Set up output selector (0x1a, 0x1b, 0x29)
914 	 */
915 	/* set vol=0 to output mixers */
916 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
917 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
918 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
919 
920 	/*
921 	 *  Unmute PW3 and PW4
922 	 */
923 	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
924 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
925 
926 	/* Set input of PW4 as AOW4 */
927 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
928 	/* Set mic as default input of sw0 */
929 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x2},
930 	/* PW9 Output enable */
931 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
932 	{ }
933 };
934 
935 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
936 	.substreams = 1,
937 	.channels_min = 2,
938 	.channels_max = 10,
939 	.nid = 0x10, /* NID to query formats and rates */
940 	.ops = {
941 		.open = via_playback_pcm_open,
942 		.prepare = via_playback_pcm_prepare,
943 		.cleanup = via_playback_pcm_cleanup
944 	},
945 };
946 
947 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
948 	.substreams = 1,
949 	.channels_min = 2,
950 	.channels_max = 6,
951 	.nid = 0x10, /* NID to query formats and rates */
952 	.ops = {
953 		.open = via_playback_pcm_open,
954 		.prepare = via_playback_pcm_prepare,
955 		.cleanup = via_playback_pcm_cleanup
956 	},
957 };
958 
959 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
960 	.substreams = 2,
961 	.channels_min = 2,
962 	.channels_max = 2,
963 	.nid = 0x14, /* NID to query formats and rates */
964 	.ops = {
965 		.prepare = via_capture_pcm_prepare,
966 		.cleanup = via_capture_pcm_cleanup
967 	},
968 };
969 
970 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
971 	.substreams = 1,
972 	.channels_min = 2,
973 	.channels_max = 2,
974 	/* NID is set in via_build_pcms */
975 	.ops = {
976 		.open = via_dig_playback_pcm_open,
977 		.close = via_dig_playback_pcm_close
978 	},
979 };
980 
981 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
982 	.substreams = 1,
983 	.channels_min = 2,
984 	.channels_max = 2,
985 };
986 
987 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
988 				     const struct auto_pin_cfg *cfg)
989 {
990 	int i;
991 	hda_nid_t nid;
992 
993 	if (cfg->line_outs == 4)  /* 10 channels */
994 		spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
995 	else if (cfg->line_outs == 3) /* 6 channels */
996 		spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
997 
998 	spec->multiout.dac_nids = spec->private_dac_nids;
999 
1000 	if (cfg->line_outs == 4) { /* 10 channels */
1001 		for (i = 0; i < cfg->line_outs; i++) {
1002 			nid = cfg->line_out_pins[i];
1003 			if (nid) {
1004 				/* config dac list */
1005 				switch (i) {
1006 				case AUTO_SEQ_FRONT:
1007 					/* AOW0 */
1008 					spec->multiout.dac_nids[i] = 0x10;
1009 					break;
1010 				case AUTO_SEQ_CENLFE:
1011 					/* AOW2 */
1012 					spec->multiout.dac_nids[i] = 0x12;
1013 					break;
1014 				case AUTO_SEQ_SURROUND:
1015 					/* AOW3 */
1016 					spec->multiout.dac_nids[i] = 0x27;
1017 					break;
1018 				case AUTO_SEQ_SIDE:
1019 					/* AOW1 */
1020 					spec->multiout.dac_nids[i] = 0x11;
1021 					break;
1022 				default:
1023 					break;
1024 				}
1025 			}
1026 		}
1027 		spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1028 
1029 	} else if (cfg->line_outs == 3) { /* 6 channels */
1030 		for(i = 0; i < cfg->line_outs; i++) {
1031 			nid = cfg->line_out_pins[i];
1032 			if (nid) {
1033 				/* config dac list */
1034 				switch(i) {
1035 				case AUTO_SEQ_FRONT:
1036 					/* AOW0 */
1037 					spec->multiout.dac_nids[i] = 0x10;
1038 					break;
1039 				case AUTO_SEQ_CENLFE:
1040 					/* AOW2 */
1041 					spec->multiout.dac_nids[i] = 0x12;
1042 					break;
1043 				case AUTO_SEQ_SURROUND:
1044 					/* AOW1 */
1045 					spec->multiout.dac_nids[i] = 0x11;
1046 					break;
1047 				default:
1048 					break;
1049 				}
1050 			}
1051 		}
1052 	}
1053 
1054 	return 0;
1055 }
1056 
1057 /* add playback controls from the parsed DAC table */
1058 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1059 					     const struct auto_pin_cfg *cfg)
1060 {
1061 	char name[32];
1062 	static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1063 	hda_nid_t nid = 0;
1064 	int i, err;
1065 
1066 	for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1067 		nid = cfg->line_out_pins[i];
1068 
1069 		if (!nid)
1070 			continue;
1071 
1072 		if (i == AUTO_SEQ_CENLFE) {
1073 			/* Center/LFE */
1074 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1075 					      "Center Playback Volume",
1076 					      HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT));
1077 			if (err < 0)
1078 				return err;
1079 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1080 					      "LFE Playback Volume",
1081 					      HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT));
1082 			if (err < 0)
1083 				return err;
1084 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1085 					      "Center Playback Switch",
1086 					      HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT));
1087 			if (err < 0)
1088 				return err;
1089 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1090 					      "LFE Playback Switch",
1091 					      HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT));
1092 			if (err < 0)
1093 				return err;
1094 		} else if (i == AUTO_SEQ_FRONT){
1095 			/* add control to mixer index 0 */
1096 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1097 					      "Master Front Playback Volume",
1098 					      HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT));
1099 			if (err < 0)
1100 				return err;
1101 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1102 					      "Master Front Playback Switch",
1103 					      HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT));
1104 			if (err < 0)
1105 				return err;
1106 
1107 			/* add control to PW3 */
1108 			sprintf(name, "%s Playback Volume", chname[i]);
1109 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1110 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
1111 			if (err < 0)
1112 				return err;
1113 			sprintf(name, "%s Playback Switch", chname[i]);
1114 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1115 					      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
1116 			if (err < 0)
1117 				return err;
1118 		} else if (i == AUTO_SEQ_SURROUND) {
1119 			sprintf(name, "%s Playback Volume", chname[i]);
1120 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1121 					      HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT));
1122 			if (err < 0)
1123 				return err;
1124 			sprintf(name, "%s Playback Switch", chname[i]);
1125 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1126 					      HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT));
1127 			if (err < 0)
1128 				return err;
1129 		} else if (i == AUTO_SEQ_SIDE) {
1130 			sprintf(name, "%s Playback Volume", chname[i]);
1131 			err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1132 					      HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT));
1133 			if (err < 0)
1134 				return err;
1135 			sprintf(name, "%s Playback Switch", chname[i]);
1136 			err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1137 					      HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT));
1138 			if (err < 0)
1139 				return err;
1140 		}
1141 	}
1142 
1143 	return 0;
1144 }
1145 
1146 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1147 {
1148 	int err;
1149 
1150 	if (!pin)
1151 		return 0;
1152 
1153 	if (spec->multiout.num_dacs == 5) /* 10 channels */
1154 		spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1155 	else if (spec->multiout.num_dacs == 3) /* 6 channels */
1156 		spec->multiout.hp_nid = 0;
1157 
1158 	err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1159 			      "Headphone Playback Volume",
1160 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1161 	if (err < 0)
1162 		return err;
1163 	err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1164 			      "Headphone Playback Switch",
1165 			      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1166 	if (err < 0)
1167 		return err;
1168 
1169 	return 0;
1170 }
1171 
1172 /* create playback/capture controls for input pins */
1173 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1174 						const struct auto_pin_cfg *cfg)
1175 {
1176 	static char *labels[] = {
1177 		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1178 	};
1179 	struct hda_input_mux *imux = &spec->private_imux;
1180 	int i, err, idx = 0;
1181 
1182 	/* for internal loopback recording select */
1183 	imux->items[imux->num_items].label = "Stereo Mixer";
1184 	imux->items[imux->num_items].index = idx;
1185 	imux->num_items++;
1186 
1187 	for (i = 0; i < AUTO_PIN_LAST; i++) {
1188 		if (!cfg->input_pins[i])
1189 			continue;
1190 
1191 		switch (cfg->input_pins[i]) {
1192 		case 0x1d: /* Mic */
1193 			idx = 2;
1194 			break;
1195 
1196 		case 0x1e: /* Line In */
1197 			idx = 3;
1198 			break;
1199 
1200 		case 0x21: /* Front Mic */
1201 			idx = 4;
1202 			break;
1203 
1204 		case 0x23: /* CD */
1205 			idx = 1;
1206 			break;
1207 		}
1208 		err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1209 					   idx, 0x18);
1210 		if (err < 0)
1211 			return err;
1212 		imux->items[imux->num_items].label = labels[i];
1213 		imux->items[imux->num_items].index = idx;
1214 		imux->num_items++;
1215 	}
1216 	return 0;
1217 }
1218 
1219 static int vt1709_parse_auto_config(struct hda_codec *codec)
1220 {
1221 	struct via_spec *spec = codec->spec;
1222 	int err;
1223 
1224 	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1225 	if (err < 0)
1226 		return err;
1227 	err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
1228 	if (err < 0)
1229 		return err;
1230 	if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1231 		return 0; /* can't find valid BIOS pin config */
1232 
1233 	err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
1234 	if (err < 0)
1235 		return err;
1236 	err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1237 	if (err < 0)
1238 		return err;
1239 	err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
1240 	if (err < 0)
1241 		return err;
1242 
1243 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1244 
1245 	if (spec->autocfg.dig_out_pin)
1246 		spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
1247 	if (spec->autocfg.dig_in_pin)
1248 		spec->dig_in_nid = VT1709_DIGIN_NID;
1249 
1250 	if (spec->kctl_alloc)
1251 		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1252 
1253 	spec->input_mux = &spec->private_imux;
1254 
1255 	return 1;
1256 }
1257 
1258 #ifdef CONFIG_SND_HDA_POWER_SAVE
1259 static struct hda_amp_list vt1709_loopbacks[] = {
1260 	{ 0x18, HDA_INPUT, 1 },
1261 	{ 0x18, HDA_INPUT, 2 },
1262 	{ 0x18, HDA_INPUT, 3 },
1263 	{ 0x18, HDA_INPUT, 4 },
1264 	{ } /* end */
1265 };
1266 #endif
1267 
1268 static int patch_vt1709_10ch(struct hda_codec *codec)
1269 {
1270 	struct via_spec *spec;
1271 	int err;
1272 
1273 	/* create a codec specific record */
1274 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1275 	if (spec == NULL)
1276 		return -ENOMEM;
1277 
1278 	codec->spec = spec;
1279 
1280 	err = vt1709_parse_auto_config(codec);
1281 	if (err < 0) {
1282 		via_free(codec);
1283 		return err;
1284 	} else if (!err) {
1285 		printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1286 		       "Using genenic mode...\n");
1287 	}
1288 
1289 	spec->init_verbs = vt1709_10ch_volume_init_verbs;
1290 
1291 	spec->stream_name_analog = "VT1709 Analog";
1292 	spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
1293 	spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1294 
1295 	spec->stream_name_digital = "VT1709 Digital";
1296 	spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1297 	spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1298 
1299 
1300 	if (!spec->adc_nids && spec->input_mux) {
1301 		spec->adc_nids = vt1709_adc_nids;
1302 		spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1303 		spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1304 		spec->num_mixers++;
1305 	}
1306 
1307 	codec->patch_ops = via_patch_ops;
1308 
1309 	codec->patch_ops.init = via_auto_init;
1310 #ifdef CONFIG_SND_HDA_POWER_SAVE
1311 	spec->loopback.amplist = vt1709_loopbacks;
1312 #endif
1313 
1314 	return 0;
1315 }
1316 /*
1317  * generic initialization of ADC, input mixers and output mixers
1318  */
1319 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
1320 	/*
1321 	 * Unmute ADC0-2 and set the default input to mic-in
1322 	 */
1323 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1324 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1325 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1326 
1327 
1328 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1329 	 * mixer widget
1330 	 */
1331 	/* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1332 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1333 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1334 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1335 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1336 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1337 
1338 	/*
1339 	 * Set up output selector (0x1a, 0x1b, 0x29)
1340 	 */
1341 	/* set vol=0 to output mixers */
1342 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1343 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1344 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1345 
1346 	/*
1347 	 *  Unmute PW3 and PW4
1348 	 */
1349 	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1350 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1351 
1352 	/* Set input of PW4 as MW0 */
1353 	{0x20, AC_VERB_SET_CONNECT_SEL, 0},
1354 	/* Set mic as default input of sw0 */
1355 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x2},
1356 	/* PW9 Output enable */
1357 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1358 	{ }
1359 };
1360 
1361 static int patch_vt1709_6ch(struct hda_codec *codec)
1362 {
1363 	struct via_spec *spec;
1364 	int err;
1365 
1366 	/* create a codec specific record */
1367 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1368 	if (spec == NULL)
1369 		return -ENOMEM;
1370 
1371 	codec->spec = spec;
1372 
1373 	err = vt1709_parse_auto_config(codec);
1374 	if (err < 0) {
1375 		via_free(codec);
1376 		return err;
1377 	} else if (!err) {
1378 		printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1379 		       "Using genenic mode...\n");
1380 	}
1381 
1382 	spec->init_verbs = vt1709_6ch_volume_init_verbs;
1383 
1384 	spec->stream_name_analog = "VT1709 Analog";
1385 	spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
1386 	spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1387 
1388 	spec->stream_name_digital = "VT1709 Digital";
1389 	spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1390 	spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1391 
1392 
1393 	if (!spec->adc_nids && spec->input_mux) {
1394 		spec->adc_nids = vt1709_adc_nids;
1395 		spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1396 		spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1397 		spec->num_mixers++;
1398 	}
1399 
1400 	codec->patch_ops = via_patch_ops;
1401 
1402 	codec->patch_ops.init = via_auto_init;
1403 #ifdef CONFIG_SND_HDA_POWER_SAVE
1404 	spec->loopback.amplist = vt1709_loopbacks;
1405 #endif
1406 
1407 	return 0;
1408 }
1409 
1410 /*
1411  * patch entries
1412  */
1413 struct hda_codec_preset snd_hda_preset_via[] = {
1414 	{ .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708},
1415 	{ .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708},
1416 	{ .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708},
1417 	{ .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708},
1418 	{ .id = 0x1106E710, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1419 	{ .id = 0x1106E711, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1420 	{ .id = 0x1106E712, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1421 	{ .id = 0x1106E713, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1422 	{ .id = 0x1106E714, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1423 	{ .id = 0x1106E715, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1424 	{ .id = 0x1106E716, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1425 	{ .id = 0x1106E717, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1426 	{} /* terminator */
1427 };
1428