Merge branch 'topic/fix/hda' into topic/hda
[linux-2.6] / sound / pci / hda / patch_via.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for VIA VT1702/VT1708/VT1709 codec
5  *
6  * Copyright (c) 2006-2008 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 /* 2007-11-14  Lydia Wang  Add VT1708A codec HP and CD pin connect config    */
33 /* 2008-02-03  Lydia Wang  Fix Rear channels and Back channels inverse issue */
34 /* 2008-03-06  Lydia Wang  Add VT1702 codec and VT1708S codec support        */
35 /* 2008-04-09  Lydia Wang  Add mute front speaker when HP plugin             */
36 /* 2008-04-09  Lydia Wang  Add Independent HP feature                        */
37 /* 2008-05-28  Lydia Wang  Add second S/PDIF Out support for VT1702          */
38 /* 2008-09-15  Logan Li    Add VT1708S Mic Boost workaround/backdoor         */
39 /*                                                                           */
40 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
41
42
43 #include <linux/init.h>
44 #include <linux/delay.h>
45 #include <linux/slab.h>
46 #include <sound/core.h>
47 #include <sound/asoundef.h>
48 #include "hda_codec.h"
49 #include "hda_local.h"
50 #include "hda_patch.h"
51
52 /* amp values */
53 #define AMP_VAL_IDX_SHIFT       19
54 #define AMP_VAL_IDX_MASK        (0x0f<<19)
55
56 /* Pin Widget NID */
57 #define VT1708_HP_NID           0x13
58 #define VT1708_DIGOUT_NID       0x14
59 #define VT1708_DIGIN_NID        0x16
60 #define VT1708_DIGIN_PIN        0x26
61 #define VT1708_HP_PIN_NID       0x20
62 #define VT1708_CD_PIN_NID       0x24
63
64 #define VT1709_HP_DAC_NID       0x28
65 #define VT1709_DIGOUT_NID       0x13
66 #define VT1709_DIGIN_NID        0x17
67 #define VT1709_DIGIN_PIN        0x25
68
69 #define VT1708B_HP_NID          0x25
70 #define VT1708B_DIGOUT_NID      0x12
71 #define VT1708B_DIGIN_NID       0x15
72 #define VT1708B_DIGIN_PIN       0x21
73
74 #define VT1708S_HP_NID          0x25
75 #define VT1708S_DIGOUT_NID      0x12
76
77 #define VT1702_HP_NID           0x17
78 #define VT1702_DIGOUT_NID       0x11
79
80 #define IS_VT1708_VENDORID(x)           ((x) >= 0x11061708 && (x) <= 0x1106170b)
81 #define IS_VT1709_10CH_VENDORID(x)      ((x) >= 0x1106e710 && (x) <= 0x1106e713)
82 #define IS_VT1709_6CH_VENDORID(x)       ((x) >= 0x1106e714 && (x) <= 0x1106e717)
83 #define IS_VT1708B_8CH_VENDORID(x)      ((x) >= 0x1106e720 && (x) <= 0x1106e723)
84 #define IS_VT1708B_4CH_VENDORID(x)      ((x) >= 0x1106e724 && (x) <= 0x1106e727)
85 #define IS_VT1708S_VENDORID(x)          ((x) >= 0x11060397 && (x) <= 0x11067397)
86 #define IS_VT1702_VENDORID(x)           ((x) >= 0x11060398 && (x) <= 0x11067398)
87
88 enum VIA_HDA_CODEC {
89         UNKNOWN = -1,
90         VT1708,
91         VT1709_10CH,
92         VT1709_6CH,
93         VT1708B_8CH,
94         VT1708B_4CH,
95         VT1708S,
96         VT1702,
97         CODEC_TYPES,
98 };
99
100 static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id)
101 {
102         u16 ven_id = vendor_id >> 16;
103         u16 dev_id = vendor_id & 0xffff;
104         enum VIA_HDA_CODEC codec_type;
105
106         /* get codec type */
107         if (ven_id != 0x1106)
108                 codec_type = UNKNOWN;
109         else if (dev_id >= 0x1708 && dev_id <= 0x170b)
110                 codec_type = VT1708;
111         else if (dev_id >= 0xe710 && dev_id <= 0xe713)
112                 codec_type = VT1709_10CH;
113         else if (dev_id >= 0xe714 && dev_id <= 0xe717)
114                 codec_type = VT1709_6CH;
115         else if (dev_id >= 0xe720 && dev_id <= 0xe723)
116                 codec_type = VT1708B_8CH;
117         else if (dev_id >= 0xe724 && dev_id <= 0xe727)
118                 codec_type = VT1708B_4CH;
119         else if ((dev_id & 0xfff) == 0x397
120                  && (dev_id >> 12) < 8)
121                 codec_type = VT1708S;
122         else if ((dev_id & 0xfff) == 0x398
123                  && (dev_id >> 12) < 8)
124                 codec_type = VT1702;
125         else
126                 codec_type = UNKNOWN;
127         return codec_type;
128 };
129
130 #define VIA_HP_EVENT            0x01
131 #define VIA_GPIO_EVENT          0x02
132
133 enum {
134         VIA_CTL_WIDGET_VOL,
135         VIA_CTL_WIDGET_MUTE,
136 };
137
138 enum {
139         AUTO_SEQ_FRONT = 0,
140         AUTO_SEQ_SURROUND,
141         AUTO_SEQ_CENLFE,
142         AUTO_SEQ_SIDE
143 };
144
145 /* Some VT1708S based boards gets the micboost setting wrong, so we have
146  * to apply some brute-force and re-write the TLV's by software. */
147 static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag,
148                          unsigned int size, unsigned int __user *_tlv)
149 {
150         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
151         hda_nid_t nid = get_amp_nid(kcontrol);
152
153         if (get_codec_type(codec->vendor_id) == VT1708S
154             && (nid == 0x1a || nid == 0x1e)) {
155                 if (size < 4 * sizeof(unsigned int))
156                         return -ENOMEM;
157                 if (put_user(1, _tlv))  /* SNDRV_CTL_TLVT_DB_SCALE */
158                         return -EFAULT;
159                 if (put_user(2 * sizeof(unsigned int), _tlv + 1))
160                         return -EFAULT;
161                 if (put_user(0, _tlv + 2)) /* offset = 0 */
162                         return -EFAULT;
163                 if (put_user(1000, _tlv + 3)) /* step size = 10 dB */
164                         return -EFAULT;
165         }
166         return 0;
167 }
168
169 static int mic_boost_volume_info(struct snd_kcontrol *kcontrol,
170                                  struct snd_ctl_elem_info *uinfo)
171 {
172         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
173         hda_nid_t nid = get_amp_nid(kcontrol);
174
175         if (get_codec_type(codec->vendor_id) == VT1708S
176             && (nid == 0x1a || nid == 0x1e)) {
177                 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
178                 uinfo->count = 2;
179                 uinfo->value.integer.min = 0;
180                 uinfo->value.integer.max = 3;
181         }
182         return 0;
183 }
184
185 static struct snd_kcontrol_new vt1708_control_templates[] = {
186         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
187         HDA_CODEC_MUTE(NULL, 0, 0, 0),
188 };
189
190
191 struct via_spec {
192         /* codec parameterization */
193         struct snd_kcontrol_new *mixers[3];
194         unsigned int num_mixers;
195
196         struct hda_verb *init_verbs[5];
197         unsigned int num_iverbs;
198
199         char *stream_name_analog;
200         struct hda_pcm_stream *stream_analog_playback;
201         struct hda_pcm_stream *stream_analog_capture;
202
203         char *stream_name_digital;
204         struct hda_pcm_stream *stream_digital_playback;
205         struct hda_pcm_stream *stream_digital_capture;
206
207         /* playback */
208         struct hda_multi_out multiout;
209         hda_nid_t extra_dig_out_nid;
210
211         /* capture */
212         unsigned int num_adc_nids;
213         hda_nid_t *adc_nids;
214         hda_nid_t dig_in_nid;
215
216         /* capture source */
217         const struct hda_input_mux *input_mux;
218         unsigned int cur_mux[3];
219
220         /* PCM information */
221         struct hda_pcm pcm_rec[3];
222
223         /* dynamic controls, init_verbs and input_mux */
224         struct auto_pin_cfg autocfg;
225         struct snd_array kctls;
226         struct hda_input_mux private_imux[2];
227         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
228
229         /* HP mode source */
230         const struct hda_input_mux *hp_mux;
231         unsigned int hp_independent_mode;
232
233 #ifdef CONFIG_SND_HDA_POWER_SAVE
234         struct hda_loopback_check loopback;
235 #endif
236 };
237
238 static hda_nid_t vt1708_adc_nids[2] = {
239         /* ADC1-2 */
240         0x15, 0x27
241 };
242
243 static hda_nid_t vt1709_adc_nids[3] = {
244         /* ADC1-2 */
245         0x14, 0x15, 0x16
246 };
247
248 static hda_nid_t vt1708B_adc_nids[2] = {
249         /* ADC1-2 */
250         0x13, 0x14
251 };
252
253 static hda_nid_t vt1708S_adc_nids[2] = {
254         /* ADC1-2 */
255         0x13, 0x14
256 };
257
258 static hda_nid_t vt1702_adc_nids[3] = {
259         /* ADC1-2 */
260         0x12, 0x20, 0x1F
261 };
262
263 /* add dynamic controls */
264 static int via_add_control(struct via_spec *spec, int type, const char *name,
265                            unsigned long val)
266 {
267         struct snd_kcontrol_new *knew;
268
269         snd_array_init(&spec->kctls, sizeof(*knew), 32);
270         knew = snd_array_new(&spec->kctls);
271         if (!knew)
272                 return -ENOMEM;
273         *knew = vt1708_control_templates[type];
274         knew->name = kstrdup(name, GFP_KERNEL);
275         if (!knew->name)
276                 return -ENOMEM;
277         knew->private_value = val;
278         return 0;
279 }
280
281 static void via_free_kctls(struct hda_codec *codec)
282 {
283         struct via_spec *spec = codec->spec;
284
285         if (spec->kctls.list) {
286                 struct snd_kcontrol_new *kctl = spec->kctls.list;
287                 int i;
288                 for (i = 0; i < spec->kctls.used; i++)
289                         kfree(kctl[i].name);
290         }
291         snd_array_free(&spec->kctls);
292 }
293
294 /* create input playback/capture controls for the given pin */
295 static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
296                                 const char *ctlname, int idx, int mix_nid)
297 {
298         char name[32];
299         int err;
300
301         sprintf(name, "%s Playback Volume", ctlname);
302         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
303                               HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
304         if (err < 0)
305                 return err;
306         sprintf(name, "%s Playback Switch", ctlname);
307         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
308                               HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
309         if (err < 0)
310                 return err;
311         return 0;
312 }
313
314 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
315                                            hda_nid_t nid, int pin_type,
316                                            int dac_idx)
317 {
318         /* set as output */
319         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
320                             pin_type);
321         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
322                             AMP_OUT_UNMUTE);
323 }
324
325
326 static void via_auto_init_multi_out(struct hda_codec *codec)
327 {
328         struct via_spec *spec = codec->spec;
329         int i;
330
331         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
332                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
333                 if (nid)
334                         via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
335         }
336 }
337
338 static void via_auto_init_hp_out(struct hda_codec *codec)
339 {
340         struct via_spec *spec = codec->spec;
341         hda_nid_t pin;
342
343         pin = spec->autocfg.hp_pins[0];
344         if (pin) /* connect to front */
345                 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
346 }
347
348 static void via_auto_init_analog_input(struct hda_codec *codec)
349 {
350         struct via_spec *spec = codec->spec;
351         int i;
352
353         for (i = 0; i < AUTO_PIN_LAST; i++) {
354                 hda_nid_t nid = spec->autocfg.input_pins[i];
355
356                 snd_hda_codec_write(codec, nid, 0,
357                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
358                                     (i <= AUTO_PIN_FRONT_MIC ?
359                                      PIN_VREF50 : PIN_IN));
360
361         }
362 }
363 /*
364  * input MUX handling
365  */
366 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
367                              struct snd_ctl_elem_info *uinfo)
368 {
369         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
370         struct via_spec *spec = codec->spec;
371         return snd_hda_input_mux_info(spec->input_mux, uinfo);
372 }
373
374 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
375                             struct snd_ctl_elem_value *ucontrol)
376 {
377         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
378         struct via_spec *spec = codec->spec;
379         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
380
381         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
382         return 0;
383 }
384
385 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
386                             struct snd_ctl_elem_value *ucontrol)
387 {
388         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
389         struct via_spec *spec = codec->spec;
390         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
391         unsigned int vendor_id = codec->vendor_id;
392
393         /* AIW0  lydia 060801 add for correct sw0 input select */
394         if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0))
395                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
396                                              0x18, &spec->cur_mux[adc_idx]);
397         else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
398                   IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0))
399                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
400                                              0x19, &spec->cur_mux[adc_idx]);
401         else if ((IS_VT1708B_8CH_VENDORID(vendor_id) ||
402                   IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0))
403                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
404                                              0x17, &spec->cur_mux[adc_idx]);
405         else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0))
406                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
407                                              0x13, &spec->cur_mux[adc_idx]);
408         else
409                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
410                                              spec->adc_nids[adc_idx],
411                                              &spec->cur_mux[adc_idx]);
412 }
413
414 static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
415                                    struct snd_ctl_elem_info *uinfo)
416 {
417         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
418         struct via_spec *spec = codec->spec;
419         return snd_hda_input_mux_info(spec->hp_mux, uinfo);
420 }
421
422 static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
423                                   struct snd_ctl_elem_value *ucontrol)
424 {
425         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
426         struct via_spec *spec = codec->spec;
427         hda_nid_t nid = spec->autocfg.hp_pins[0];
428         unsigned int pinsel = snd_hda_codec_read(codec, nid, 0,
429                                                  AC_VERB_GET_CONNECT_SEL,
430                                                  0x00);
431
432         ucontrol->value.enumerated.item[0] = pinsel;
433
434         return 0;
435 }
436
437 static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
438                                   struct snd_ctl_elem_value *ucontrol)
439 {
440         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
441         struct via_spec *spec = codec->spec;
442         hda_nid_t nid = spec->autocfg.hp_pins[0];
443         unsigned int pinsel = ucontrol->value.enumerated.item[0];
444         unsigned int con_nid = snd_hda_codec_read(codec, nid, 0,
445                                          AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
446
447         if (con_nid == spec->multiout.hp_nid) {
448                 if (pinsel == 0) {
449                         if (!spec->hp_independent_mode) {
450                                 if (spec->multiout.num_dacs > 1)
451                                         spec->multiout.num_dacs -= 1;
452                                 spec->hp_independent_mode = 1;
453                         }
454                 } else if (pinsel == 1) {
455                        if (spec->hp_independent_mode) {
456                                 if (spec->multiout.num_dacs > 1)
457                                         spec->multiout.num_dacs += 1;
458                                 spec->hp_independent_mode = 0;
459                        }
460                 }
461         } else {
462                 if (pinsel == 0) {
463                         if (spec->hp_independent_mode) {
464                                 if (spec->multiout.num_dacs > 1)
465                                         spec->multiout.num_dacs += 1;
466                                 spec->hp_independent_mode = 0;
467                         }
468                 } else if (pinsel == 1) {
469                        if (!spec->hp_independent_mode) {
470                                 if (spec->multiout.num_dacs > 1)
471                                         spec->multiout.num_dacs -= 1;
472                                 spec->hp_independent_mode = 1;
473                        }
474                 }
475         }
476         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
477                             pinsel);
478
479         if (spec->multiout.hp_nid &&
480             spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT])
481                         snd_hda_codec_setup_stream(codec,
482                                                    spec->multiout.hp_nid,
483                                                    0, 0, 0);
484
485         return 0;
486 }
487
488 static struct snd_kcontrol_new via_hp_mixer[] = {
489         {
490                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
491                 .name = "Independent HP",
492                 .count = 1,
493                 .info = via_independent_hp_info,
494                 .get = via_independent_hp_get,
495                 .put = via_independent_hp_put,
496         },
497         { } /* end */
498 };
499
500 /* capture mixer elements */
501 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
502         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
503         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
504         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
505         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
506         {
507                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
508                 /* The multiple "Capture Source" controls confuse alsamixer
509                  * So call somewhat different..
510                  */
511                 /* .name = "Capture Source", */
512                 .name = "Input Source",
513                 .count = 1,
514                 .info = via_mux_enum_info,
515                 .get = via_mux_enum_get,
516                 .put = via_mux_enum_put,
517         },
518         { } /* end */
519 };
520 /*
521  * generic initialization of ADC, input mixers and output mixers
522  */
523 static struct hda_verb vt1708_volume_init_verbs[] = {
524         /*
525          * Unmute ADC0-1 and set the default input to mic-in
526          */
527         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
528         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
529
530
531         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
532          * mixer widget
533          */
534         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
535         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
536         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
537         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
538         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
539         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
540
541         /*
542          * Set up output mixers (0x19 - 0x1b)
543          */
544         /* set vol=0 to output mixers */
545         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
546         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
547         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
548         
549         /* Setup default input to PW4 */
550         {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
551         /* PW9 Output enable */
552         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
553         { }
554 };
555
556 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
557                                  struct hda_codec *codec,
558                                  struct snd_pcm_substream *substream)
559 {
560         struct via_spec *spec = codec->spec;
561         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
562                                              hinfo);
563 }
564
565 static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
566                                     struct hda_codec *codec,
567                                     unsigned int stream_tag,
568                                     unsigned int format,
569                                     struct snd_pcm_substream *substream)
570 {
571         struct via_spec *spec = codec->spec;
572         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
573                                                 stream_tag, format, substream);
574 }
575
576 static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
577                                     struct hda_codec *codec,
578                                     struct snd_pcm_substream *substream)
579 {
580         struct via_spec *spec = codec->spec;
581         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
582 }
583
584
585 static void playback_multi_pcm_prep_0(struct hda_codec *codec,
586                                       unsigned int stream_tag,
587                                       unsigned int format,
588                                       struct snd_pcm_substream *substream)
589 {
590         struct via_spec *spec = codec->spec;
591         struct hda_multi_out *mout = &spec->multiout;
592         hda_nid_t *nids = mout->dac_nids;
593         int chs = substream->runtime->channels;
594         int i;
595
596         mutex_lock(&codec->spdif_mutex);
597         if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
598                 if (chs == 2 &&
599                     snd_hda_is_supported_format(codec, mout->dig_out_nid,
600                                                 format) &&
601                     !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
602                         mout->dig_out_used = HDA_DIG_ANALOG_DUP;
603                         /* turn off SPDIF once; otherwise the IEC958 bits won't
604                          * be updated */
605                         if (codec->spdif_ctls & AC_DIG1_ENABLE)
606                                 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
607                                                     AC_VERB_SET_DIGI_CONVERT_1,
608                                                     codec->spdif_ctls &
609                                                         ~AC_DIG1_ENABLE & 0xff);
610                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
611                                                    stream_tag, 0, format);
612                         /* turn on again (if needed) */
613                         if (codec->spdif_ctls & AC_DIG1_ENABLE)
614                                 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
615                                                     AC_VERB_SET_DIGI_CONVERT_1,
616                                                     codec->spdif_ctls & 0xff);
617                 } else {
618                         mout->dig_out_used = 0;
619                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
620                                                    0, 0, 0);
621                 }
622         }
623         mutex_unlock(&codec->spdif_mutex);
624
625         /* front */
626         snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
627                                    0, format);
628
629         if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
630             !spec->hp_independent_mode)
631                 /* headphone out will just decode front left/right (stereo) */
632                 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
633                                            0, format);
634
635         /* extra outputs copied from front */
636         for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
637                 if (mout->extra_out_nid[i])
638                         snd_hda_codec_setup_stream(codec,
639                                                    mout->extra_out_nid[i],
640                                                    stream_tag, 0, format);
641
642         /* surrounds */
643         for (i = 1; i < mout->num_dacs; i++) {
644                 if (chs >= (i + 1) * 2) /* independent out */
645                         snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
646                                                    i * 2, format);
647                 else /* copy front */
648                         snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
649                                                    0, format);
650         }
651 }
652
653 static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
654                                           struct hda_codec *codec,
655                                           unsigned int stream_tag,
656                                           unsigned int format,
657                                           struct snd_pcm_substream *substream)
658 {
659         struct via_spec *spec = codec->spec;
660         struct hda_multi_out *mout = &spec->multiout;
661         hda_nid_t *nids = mout->dac_nids;
662
663         if (substream->number == 0)
664                 playback_multi_pcm_prep_0(codec, stream_tag, format,
665                                           substream);
666         else {
667                 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
668                     spec->hp_independent_mode)
669                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
670                                                    stream_tag, 0, format);
671         }
672
673         return 0;
674 }
675
676 static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
677                                     struct hda_codec *codec,
678                                     struct snd_pcm_substream *substream)
679 {
680         struct via_spec *spec = codec->spec;
681         struct hda_multi_out *mout = &spec->multiout;
682         hda_nid_t *nids = mout->dac_nids;
683         int i;
684
685         if (substream->number == 0) {
686                 for (i = 0; i < mout->num_dacs; i++)
687                         snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
688
689                 if (mout->hp_nid && !spec->hp_independent_mode)
690                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
691                                                    0, 0, 0);
692
693                 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
694                         if (mout->extra_out_nid[i])
695                                 snd_hda_codec_setup_stream(codec,
696                                                         mout->extra_out_nid[i],
697                                                         0, 0, 0);
698                 mutex_lock(&codec->spdif_mutex);
699                 if (mout->dig_out_nid &&
700                     mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
701                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
702                                                    0, 0, 0);
703                         mout->dig_out_used = 0;
704                 }
705                 mutex_unlock(&codec->spdif_mutex);
706         } else {
707                 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
708                     spec->hp_independent_mode)
709                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
710                                                    0, 0, 0);
711         }
712
713         return 0;
714 }
715
716 /*
717  * Digital out
718  */
719 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
720                                      struct hda_codec *codec,
721                                      struct snd_pcm_substream *substream)
722 {
723         struct via_spec *spec = codec->spec;
724         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
725 }
726
727 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
728                                       struct hda_codec *codec,
729                                       struct snd_pcm_substream *substream)
730 {
731         struct via_spec *spec = codec->spec;
732         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
733 }
734
735 /* setup SPDIF output stream */
736 static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid,
737                                  unsigned int stream_tag, unsigned int format)
738 {
739         /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
740         if (codec->spdif_ctls & AC_DIG1_ENABLE)
741                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
742                                     codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
743         snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
744         /* turn on again (if needed) */
745         if (codec->spdif_ctls & AC_DIG1_ENABLE)
746                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
747                                     codec->spdif_ctls & 0xff);
748 }
749
750 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
751                                         struct hda_codec *codec,
752                                         unsigned int stream_tag,
753                                         unsigned int format,
754                                         struct snd_pcm_substream *substream)
755 {
756         struct via_spec *spec = codec->spec;
757         hda_nid_t nid;
758
759         /* 1st or 2nd S/PDIF */
760         if (substream->number == 0)
761                 nid = spec->multiout.dig_out_nid;
762         else if (substream->number == 1)
763                 nid = spec->extra_dig_out_nid;
764         else
765                 return -1;
766
767         mutex_lock(&codec->spdif_mutex);
768         setup_dig_playback_stream(codec, nid, stream_tag, format);
769         mutex_unlock(&codec->spdif_mutex);
770         return 0;
771 }
772
773 /*
774  * Analog capture
775  */
776 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
777                                    struct hda_codec *codec,
778                                    unsigned int stream_tag,
779                                    unsigned int format,
780                                    struct snd_pcm_substream *substream)
781 {
782         struct via_spec *spec = codec->spec;
783
784         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
785                                    stream_tag, 0, format);
786         return 0;
787 }
788
789 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
790                                    struct hda_codec *codec,
791                                    struct snd_pcm_substream *substream)
792 {
793         struct via_spec *spec = codec->spec;
794         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
795         return 0;
796 }
797
798 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
799         .substreams = 2,
800         .channels_min = 2,
801         .channels_max = 8,
802         .nid = 0x10, /* NID to query formats and rates */
803         .ops = {
804                 .open = via_playback_pcm_open,
805                 .prepare = via_playback_multi_pcm_prepare,
806                 .cleanup = via_playback_multi_pcm_cleanup
807         },
808 };
809
810 static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
811         .substreams = 1,
812         .channels_min = 2,
813         .channels_max = 8,
814         .nid = 0x10, /* NID to query formats and rates */
815         /* We got noisy outputs on the right channel on VT1708 when
816          * 24bit samples are used.  Until any workaround is found,
817          * disable the 24bit format, so far.
818          */
819         .formats = SNDRV_PCM_FMTBIT_S16_LE,
820         .ops = {
821                 .open = via_playback_pcm_open,
822                 .prepare = via_playback_pcm_prepare,
823                 .cleanup = via_playback_pcm_cleanup
824         },
825 };
826
827 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
828         .substreams = 2,
829         .channels_min = 2,
830         .channels_max = 2,
831         .nid = 0x15, /* NID to query formats and rates */
832         .ops = {
833                 .prepare = via_capture_pcm_prepare,
834                 .cleanup = via_capture_pcm_cleanup
835         },
836 };
837
838 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
839         .substreams = 1,
840         .channels_min = 2,
841         .channels_max = 2,
842         /* NID is set in via_build_pcms */
843         .ops = {
844                 .open = via_dig_playback_pcm_open,
845                 .close = via_dig_playback_pcm_close,
846                 .prepare = via_dig_playback_pcm_prepare
847         },
848 };
849
850 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
851         .substreams = 1,
852         .channels_min = 2,
853         .channels_max = 2,
854 };
855
856 static int via_build_controls(struct hda_codec *codec)
857 {
858         struct via_spec *spec = codec->spec;
859         int err;
860         int i;
861
862         for (i = 0; i < spec->num_mixers; i++) {
863                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
864                 if (err < 0)
865                         return err;
866         }
867
868         if (spec->multiout.dig_out_nid) {
869                 err = snd_hda_create_spdif_out_ctls(codec,
870                                                     spec->multiout.dig_out_nid);
871                 if (err < 0)
872                         return err;
873                 err = snd_hda_create_spdif_share_sw(codec,
874                                                     &spec->multiout);
875                 if (err < 0)
876                         return err;
877                 spec->multiout.share_spdif = 1;
878
879                 if (spec->extra_dig_out_nid) {
880                         err = snd_hda_create_spdif_out_ctls(codec,
881                                                     spec->extra_dig_out_nid);
882                         if (err < 0)
883                                 return err;
884                 }
885         }
886         if (spec->dig_in_nid) {
887                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
888                 if (err < 0)
889                         return err;
890         }
891         via_free_kctls(codec); /* no longer needed */
892         return 0;
893 }
894
895 static int via_build_pcms(struct hda_codec *codec)
896 {
897         struct via_spec *spec = codec->spec;
898         struct hda_pcm *info = spec->pcm_rec;
899
900         codec->num_pcms = 1;
901         codec->pcm_info = info;
902
903         info->name = spec->stream_name_analog;
904         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
905         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
906         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
907         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
908
909         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
910                 spec->multiout.max_channels;
911
912         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
913                 codec->num_pcms++;
914                 info++;
915                 info->name = spec->stream_name_digital;
916                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
917                 if (spec->multiout.dig_out_nid) {
918                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
919                                 *(spec->stream_digital_playback);
920                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
921                                 spec->multiout.dig_out_nid;
922                 }
923                 if (spec->dig_in_nid) {
924                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
925                                 *(spec->stream_digital_capture);
926                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
927                                 spec->dig_in_nid;
928                 }
929         }
930
931         return 0;
932 }
933
934 static void via_free(struct hda_codec *codec)
935 {
936         struct via_spec *spec = codec->spec;
937
938         if (!spec)
939                 return;
940
941         via_free_kctls(codec);
942         kfree(codec->spec);
943 }
944
945 /* mute internal speaker if HP is plugged */
946 static void via_hp_automute(struct hda_codec *codec)
947 {
948         unsigned int present;
949         struct via_spec *spec = codec->spec;
950
951         present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0,
952                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
953         snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
954                                  HDA_OUTPUT, 0, HDA_AMP_MUTE,
955                                  present ? HDA_AMP_MUTE : 0);
956 }
957
958 static void via_gpio_control(struct hda_codec *codec)
959 {
960         unsigned int gpio_data;
961         unsigned int vol_counter;
962         unsigned int vol;
963         unsigned int master_vol;
964
965         struct via_spec *spec = codec->spec;
966
967         gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
968                                        AC_VERB_GET_GPIO_DATA, 0) & 0x03;
969
970         vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
971                                           0xF84, 0) & 0x3F0000) >> 16;
972
973         vol = vol_counter & 0x1F;
974         master_vol = snd_hda_codec_read(codec, 0x1A, 0,
975                                         AC_VERB_GET_AMP_GAIN_MUTE,
976                                         AC_AMP_GET_INPUT);
977
978         if (gpio_data == 0x02) {
979                 /* unmute line out */
980                 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
981                                          HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
982
983                 if (vol_counter & 0x20) {
984                         /* decrease volume */
985                         if (vol > master_vol)
986                                 vol = master_vol;
987                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
988                                                  0, HDA_AMP_VOLMASK,
989                                                  master_vol-vol);
990                 } else {
991                         /* increase volume */
992                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
993                                          HDA_AMP_VOLMASK,
994                                          ((master_vol+vol) > 0x2A) ? 0x2A :
995                                           (master_vol+vol));
996                 }
997         } else if (!(gpio_data & 0x02)) {
998                 /* mute line out */
999                 snd_hda_codec_amp_stereo(codec,
1000                                          spec->autocfg.line_out_pins[0],
1001                                          HDA_OUTPUT, 0, HDA_AMP_MUTE,
1002                                          HDA_AMP_MUTE);
1003         }
1004 }
1005
1006 /* unsolicited event for jack sensing */
1007 static void via_unsol_event(struct hda_codec *codec,
1008                                   unsigned int res)
1009 {
1010         res >>= 26;
1011         if (res == VIA_HP_EVENT)
1012                 via_hp_automute(codec);
1013         else if (res == VIA_GPIO_EVENT)
1014                 via_gpio_control(codec);
1015 }
1016
1017 static hda_nid_t slave_dig_outs[] = {
1018         0,
1019 };
1020
1021 static int via_init(struct hda_codec *codec)
1022 {
1023         struct via_spec *spec = codec->spec;
1024         int i;
1025         for (i = 0; i < spec->num_iverbs; i++)
1026                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1027
1028         /* Lydia Add for EAPD enable */
1029         if (!spec->dig_in_nid) { /* No Digital In connection */
1030                 if (IS_VT1708_VENDORID(codec->vendor_id)) {
1031                         snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
1032                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1033                                             PIN_OUT);
1034                         snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
1035                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1036                 } else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) ||
1037                            IS_VT1709_6CH_VENDORID(codec->vendor_id)) {
1038                         snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
1039                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1040                                             PIN_OUT);
1041                         snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
1042                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1043                 } else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) ||
1044                            IS_VT1708B_4CH_VENDORID(codec->vendor_id)) {
1045                         snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
1046                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1047                                             PIN_OUT);
1048                         snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
1049                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1050                 }
1051         } else /* enable SPDIF-input pin */
1052                 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
1053                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
1054
1055         /* no slave outs */
1056         codec->slave_dig_outs = slave_dig_outs;
1057
1058         return 0;
1059 }
1060
1061 #ifdef CONFIG_SND_HDA_POWER_SAVE
1062 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1063 {
1064         struct via_spec *spec = codec->spec;
1065         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
1066 }
1067 #endif
1068
1069 /*
1070  */
1071 static struct hda_codec_ops via_patch_ops = {
1072         .build_controls = via_build_controls,
1073         .build_pcms = via_build_pcms,
1074         .init = via_init,
1075         .free = via_free,
1076 #ifdef CONFIG_SND_HDA_POWER_SAVE
1077         .check_power_status = via_check_power_status,
1078 #endif
1079 };
1080
1081 /* fill in the dac_nids table from the parsed pin configuration */
1082 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
1083                                      const struct auto_pin_cfg *cfg)
1084 {
1085         int i;
1086         hda_nid_t nid;
1087
1088         spec->multiout.num_dacs = cfg->line_outs;
1089
1090         spec->multiout.dac_nids = spec->private_dac_nids;
1091         
1092         for(i = 0; i < 4; i++) {
1093                 nid = cfg->line_out_pins[i];
1094                 if (nid) {
1095                         /* config dac list */
1096                         switch (i) {
1097                         case AUTO_SEQ_FRONT:
1098                                 spec->multiout.dac_nids[i] = 0x10;
1099                                 break;
1100                         case AUTO_SEQ_CENLFE:
1101                                 spec->multiout.dac_nids[i] = 0x12;
1102                                 break;
1103                         case AUTO_SEQ_SURROUND:
1104                                 spec->multiout.dac_nids[i] = 0x11;
1105                                 break;
1106                         case AUTO_SEQ_SIDE:
1107                                 spec->multiout.dac_nids[i] = 0x13;
1108                                 break;
1109                         }
1110                 }
1111         }
1112
1113         return 0;
1114 }
1115
1116 /* add playback controls from the parsed DAC table */
1117 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
1118                                              const struct auto_pin_cfg *cfg)
1119 {
1120         char name[32];
1121         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1122         hda_nid_t nid, nid_vol = 0;
1123         int i, err;
1124
1125         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1126                 nid = cfg->line_out_pins[i];
1127
1128                 if (!nid)
1129                         continue;
1130                 
1131                 if (i != AUTO_SEQ_FRONT)
1132                         nid_vol = 0x18 + i;
1133
1134                 if (i == AUTO_SEQ_CENLFE) {
1135                         /* Center/LFE */
1136                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1137                                         "Center Playback Volume",
1138                                         HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1139                                                             HDA_OUTPUT));
1140                         if (err < 0)
1141                                 return err;
1142                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1143                                               "LFE Playback Volume",
1144                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1145                                                                   HDA_OUTPUT));
1146                         if (err < 0)
1147                                 return err;
1148                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1149                                               "Center Playback Switch",
1150                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1151                                                                   HDA_OUTPUT));
1152                         if (err < 0)
1153                                 return err;
1154                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1155                                               "LFE Playback Switch",
1156                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1157                                                                   HDA_OUTPUT));
1158                         if (err < 0)
1159                                 return err;
1160                 } else if (i == AUTO_SEQ_FRONT){
1161                         /* add control to mixer index 0 */
1162                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1163                                               "Master Front Playback Volume",
1164                                               HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
1165                                                                   HDA_INPUT));
1166                         if (err < 0)
1167                                 return err;
1168                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1169                                               "Master Front Playback Switch",
1170                                               HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
1171                                                                   HDA_INPUT));
1172                         if (err < 0)
1173                                 return err;
1174                         
1175                         /* add control to PW3 */
1176                         sprintf(name, "%s Playback Volume", chname[i]);
1177                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1178                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1179                                                                   HDA_OUTPUT));
1180                         if (err < 0)
1181                                 return err;
1182                         sprintf(name, "%s Playback Switch", chname[i]);
1183                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1184                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1185                                                                   HDA_OUTPUT));
1186                         if (err < 0)
1187                                 return err;
1188                 } else {
1189                         sprintf(name, "%s Playback Volume", chname[i]);
1190                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1191                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1192                                                                   HDA_OUTPUT));
1193                         if (err < 0)
1194                                 return err;
1195                         sprintf(name, "%s Playback Switch", chname[i]);
1196                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1197                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1198                                                                   HDA_OUTPUT));
1199                         if (err < 0)
1200                                 return err;
1201                 }
1202         }
1203
1204         return 0;
1205 }
1206
1207 static void create_hp_imux(struct via_spec *spec)
1208 {
1209         int i;
1210         struct hda_input_mux *imux = &spec->private_imux[1];
1211         static const char *texts[] = { "OFF", "ON", NULL};
1212
1213         /* for hp mode select */
1214         i = 0;
1215         while (texts[i] != NULL) {
1216                 imux->items[imux->num_items].label =  texts[i];
1217                 imux->items[imux->num_items].index = i;
1218                 imux->num_items++;
1219                 i++;
1220         }
1221
1222         spec->hp_mux = &spec->private_imux[1];
1223 }
1224
1225 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1226 {
1227         int err;
1228
1229         if (!pin)
1230                 return 0;
1231
1232         spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
1233
1234         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1235                               "Headphone Playback Volume",
1236                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1237         if (err < 0)
1238                 return err;
1239         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1240                               "Headphone Playback Switch",
1241                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1242         if (err < 0)
1243                 return err;
1244
1245         create_hp_imux(spec);
1246
1247         return 0;
1248 }
1249
1250 /* create playback/capture controls for input pins */
1251 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
1252                                                 const struct auto_pin_cfg *cfg)
1253 {
1254         static char *labels[] = {
1255                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1256         };
1257         struct hda_input_mux *imux = &spec->private_imux[0];
1258         int i, err, idx = 0;
1259
1260         /* for internal loopback recording select */
1261         imux->items[imux->num_items].label = "Stereo Mixer";
1262         imux->items[imux->num_items].index = idx;
1263         imux->num_items++;
1264
1265         for (i = 0; i < AUTO_PIN_LAST; i++) {
1266                 if (!cfg->input_pins[i])
1267                         continue;
1268
1269                 switch (cfg->input_pins[i]) {
1270                 case 0x1d: /* Mic */
1271                         idx = 2;
1272                         break;
1273                                 
1274                 case 0x1e: /* Line In */
1275                         idx = 3;
1276                         break;
1277
1278                 case 0x21: /* Front Mic */
1279                         idx = 4;
1280                         break;
1281
1282                 case 0x24: /* CD */
1283                         idx = 1;
1284                         break;
1285                 }
1286                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1287                                            idx, 0x17);
1288                 if (err < 0)
1289                         return err;
1290                 imux->items[imux->num_items].label = labels[i];
1291                 imux->items[imux->num_items].index = idx;
1292                 imux->num_items++;
1293         }
1294         return 0;
1295 }
1296
1297 #ifdef CONFIG_SND_HDA_POWER_SAVE
1298 static struct hda_amp_list vt1708_loopbacks[] = {
1299         { 0x17, HDA_INPUT, 1 },
1300         { 0x17, HDA_INPUT, 2 },
1301         { 0x17, HDA_INPUT, 3 },
1302         { 0x17, HDA_INPUT, 4 },
1303         { } /* end */
1304 };
1305 #endif
1306
1307 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
1308 {
1309         unsigned int def_conf;
1310         unsigned char seqassoc;
1311
1312         def_conf = snd_hda_codec_read(codec, nid, 0,
1313                                       AC_VERB_GET_CONFIG_DEFAULT, 0);
1314         seqassoc = (unsigned char) get_defcfg_association(def_conf);
1315         seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
1316         if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) {
1317                 if (seqassoc == 0xff) {
1318                         def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
1319                         snd_hda_codec_write(codec, nid, 0,
1320                                             AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
1321                                             def_conf >> 24);
1322                 }
1323         }
1324
1325         return;
1326 }
1327
1328 static int vt1708_parse_auto_config(struct hda_codec *codec)
1329 {
1330         struct via_spec *spec = codec->spec;
1331         int err;
1332
1333         /* Add HP and CD pin config connect bit re-config action */
1334         vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
1335         vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
1336
1337         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1338         if (err < 0)
1339                 return err;
1340         err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
1341         if (err < 0)
1342                 return err;
1343         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1344                 return 0; /* can't find valid BIOS pin config */
1345
1346         err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
1347         if (err < 0)
1348                 return err;
1349         err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1350         if (err < 0)
1351                 return err;
1352         err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
1353         if (err < 0)
1354                 return err;
1355
1356         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1357
1358         if (spec->autocfg.dig_out_pin)
1359                 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
1360         if (spec->autocfg.dig_in_pin)
1361                 spec->dig_in_nid = VT1708_DIGIN_NID;
1362
1363         if (spec->kctls.list)
1364                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1365
1366         spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
1367
1368         spec->input_mux = &spec->private_imux[0];
1369
1370         if (spec->hp_mux)
1371                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
1372
1373         return 1;
1374 }
1375
1376 /* init callback for auto-configuration model -- overriding the default init */
1377 static int via_auto_init(struct hda_codec *codec)
1378 {
1379         via_init(codec);
1380         via_auto_init_multi_out(codec);
1381         via_auto_init_hp_out(codec);
1382         via_auto_init_analog_input(codec);
1383         return 0;
1384 }
1385
1386 static int patch_vt1708(struct hda_codec *codec)
1387 {
1388         struct via_spec *spec;
1389         int err;
1390
1391         /* create a codec specific record */
1392         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1393         if (spec == NULL)
1394                 return -ENOMEM;
1395
1396         codec->spec = spec;
1397
1398         /* automatic parse from the BIOS config */
1399         err = vt1708_parse_auto_config(codec);
1400         if (err < 0) {
1401                 via_free(codec);
1402                 return err;
1403         } else if (!err) {
1404                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
1405                        "from BIOS.  Using genenic mode...\n");
1406         }
1407
1408         
1409         spec->stream_name_analog = "VT1708 Analog";
1410         spec->stream_analog_playback = &vt1708_pcm_analog_playback;
1411         /* disable 32bit format on VT1708 */
1412         if (codec->vendor_id == 0x11061708)
1413                 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
1414         spec->stream_analog_capture = &vt1708_pcm_analog_capture;
1415
1416         spec->stream_name_digital = "VT1708 Digital";
1417         spec->stream_digital_playback = &vt1708_pcm_digital_playback;
1418         spec->stream_digital_capture = &vt1708_pcm_digital_capture;
1419
1420         
1421         if (!spec->adc_nids && spec->input_mux) {
1422                 spec->adc_nids = vt1708_adc_nids;
1423                 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
1424                 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
1425                 spec->num_mixers++;
1426         }
1427
1428         codec->patch_ops = via_patch_ops;
1429
1430         codec->patch_ops.init = via_auto_init;
1431 #ifdef CONFIG_SND_HDA_POWER_SAVE
1432         spec->loopback.amplist = vt1708_loopbacks;
1433 #endif
1434
1435         return 0;
1436 }
1437
1438 /* capture mixer elements */
1439 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
1440         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
1441         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
1442         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
1443         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
1444         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
1445         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
1446         {
1447                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1448                 /* The multiple "Capture Source" controls confuse alsamixer
1449                  * So call somewhat different..
1450                  */
1451                 /* .name = "Capture Source", */
1452                 .name = "Input Source",
1453                 .count = 1,
1454                 .info = via_mux_enum_info,
1455                 .get = via_mux_enum_get,
1456                 .put = via_mux_enum_put,
1457         },
1458         { } /* end */
1459 };
1460
1461 static struct hda_verb vt1709_uniwill_init_verbs[] = {
1462         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
1463         { }
1464 };
1465
1466 /*
1467  * generic initialization of ADC, input mixers and output mixers
1468  */
1469 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
1470         /*
1471          * Unmute ADC0-2 and set the default input to mic-in
1472          */
1473         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1474         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1475         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1476
1477
1478         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1479          * mixer widget
1480          */
1481         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1482         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1483         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1484         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1485         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1486         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1487
1488         /*
1489          * Set up output selector (0x1a, 0x1b, 0x29)
1490          */
1491         /* set vol=0 to output mixers */
1492         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1493         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1494         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1495
1496         /*
1497          *  Unmute PW3 and PW4
1498          */
1499         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1500         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1501
1502         /* Set input of PW4 as AOW4 */
1503         {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
1504         /* PW9 Output enable */
1505         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1506         { }
1507 };
1508
1509 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
1510         .substreams = 1,
1511         .channels_min = 2,
1512         .channels_max = 10,
1513         .nid = 0x10, /* NID to query formats and rates */
1514         .ops = {
1515                 .open = via_playback_pcm_open,
1516                 .prepare = via_playback_pcm_prepare,
1517                 .cleanup = via_playback_pcm_cleanup
1518         },
1519 };
1520
1521 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
1522         .substreams = 1,
1523         .channels_min = 2,
1524         .channels_max = 6,
1525         .nid = 0x10, /* NID to query formats and rates */
1526         .ops = {
1527                 .open = via_playback_pcm_open,
1528                 .prepare = via_playback_pcm_prepare,
1529                 .cleanup = via_playback_pcm_cleanup
1530         },
1531 };
1532
1533 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
1534         .substreams = 2,
1535         .channels_min = 2,
1536         .channels_max = 2,
1537         .nid = 0x14, /* NID to query formats and rates */
1538         .ops = {
1539                 .prepare = via_capture_pcm_prepare,
1540                 .cleanup = via_capture_pcm_cleanup
1541         },
1542 };
1543
1544 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
1545         .substreams = 1,
1546         .channels_min = 2,
1547         .channels_max = 2,
1548         /* NID is set in via_build_pcms */
1549         .ops = {
1550                 .open = via_dig_playback_pcm_open,
1551                 .close = via_dig_playback_pcm_close
1552         },
1553 };
1554
1555 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
1556         .substreams = 1,
1557         .channels_min = 2,
1558         .channels_max = 2,
1559 };
1560
1561 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
1562                                      const struct auto_pin_cfg *cfg)
1563 {
1564         int i;
1565         hda_nid_t nid;
1566
1567         if (cfg->line_outs == 4)  /* 10 channels */
1568                 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
1569         else if (cfg->line_outs == 3) /* 6 channels */
1570                 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
1571
1572         spec->multiout.dac_nids = spec->private_dac_nids;
1573
1574         if (cfg->line_outs == 4) { /* 10 channels */
1575                 for (i = 0; i < cfg->line_outs; i++) {
1576                         nid = cfg->line_out_pins[i];
1577                         if (nid) {
1578                                 /* config dac list */
1579                                 switch (i) {
1580                                 case AUTO_SEQ_FRONT:
1581                                         /* AOW0 */
1582                                         spec->multiout.dac_nids[i] = 0x10;
1583                                         break;
1584                                 case AUTO_SEQ_CENLFE:
1585                                         /* AOW2 */
1586                                         spec->multiout.dac_nids[i] = 0x12;
1587                                         break;
1588                                 case AUTO_SEQ_SURROUND:
1589                                         /* AOW3 */
1590                                         spec->multiout.dac_nids[i] = 0x11;
1591                                         break;
1592                                 case AUTO_SEQ_SIDE:
1593                                         /* AOW1 */
1594                                         spec->multiout.dac_nids[i] = 0x27;
1595                                         break;
1596                                 default:
1597                                         break;
1598                                 }
1599                         }
1600                 }
1601                 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1602
1603         } else if (cfg->line_outs == 3) { /* 6 channels */
1604                 for(i = 0; i < cfg->line_outs; i++) {
1605                         nid = cfg->line_out_pins[i];
1606                         if (nid) {
1607                                 /* config dac list */
1608                                 switch(i) {
1609                                 case AUTO_SEQ_FRONT:
1610                                         /* AOW0 */
1611                                         spec->multiout.dac_nids[i] = 0x10;
1612                                         break;
1613                                 case AUTO_SEQ_CENLFE:
1614                                         /* AOW2 */
1615                                         spec->multiout.dac_nids[i] = 0x12;
1616                                         break;
1617                                 case AUTO_SEQ_SURROUND:
1618                                         /* AOW1 */
1619                                         spec->multiout.dac_nids[i] = 0x11;
1620                                         break;
1621                                 default:
1622                                         break;
1623                                 }
1624                         }
1625                 }
1626         }
1627
1628         return 0;
1629 }
1630
1631 /* add playback controls from the parsed DAC table */
1632 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1633                                              const struct auto_pin_cfg *cfg)
1634 {
1635         char name[32];
1636         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1637         hda_nid_t nid = 0;
1638         int i, err;
1639
1640         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1641                 nid = cfg->line_out_pins[i];
1642
1643                 if (!nid)       
1644                         continue;
1645
1646                 if (i == AUTO_SEQ_CENLFE) {
1647                         /* Center/LFE */
1648                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1649                                               "Center Playback Volume",
1650                                               HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1651                                                                   HDA_OUTPUT));
1652                         if (err < 0)
1653                                 return err;
1654                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1655                                               "LFE Playback Volume",
1656                                               HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1657                                                                   HDA_OUTPUT));
1658                         if (err < 0)
1659                                 return err;
1660                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1661                                               "Center Playback Switch",
1662                                               HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1663                                                                   HDA_OUTPUT));
1664                         if (err < 0)
1665                                 return err;
1666                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1667                                               "LFE Playback Switch",
1668                                               HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1669                                                                   HDA_OUTPUT));
1670                         if (err < 0)
1671                                 return err;
1672                 } else if (i == AUTO_SEQ_FRONT){
1673                         /* add control to mixer index 0 */
1674                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1675                                               "Master Front Playback Volume",
1676                                               HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1677                                                                   HDA_INPUT));
1678                         if (err < 0)
1679                                 return err;
1680                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1681                                               "Master Front Playback Switch",
1682                                               HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1683                                                                   HDA_INPUT));
1684                         if (err < 0)
1685                                 return err;
1686                         
1687                         /* add control to PW3 */
1688                         sprintf(name, "%s Playback Volume", chname[i]);
1689                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1690                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1691                                                                   HDA_OUTPUT));
1692                         if (err < 0)
1693                                 return err;
1694                         sprintf(name, "%s Playback Switch", chname[i]);
1695                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1696                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1697                                                                   HDA_OUTPUT));
1698                         if (err < 0)
1699                                 return err;
1700                 } else if (i == AUTO_SEQ_SURROUND) {
1701                         sprintf(name, "%s Playback Volume", chname[i]);
1702                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1703                                               HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1704                                                                   HDA_OUTPUT));
1705                         if (err < 0)
1706                                 return err;
1707                         sprintf(name, "%s Playback Switch", chname[i]);
1708                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1709                                               HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1710                                                                   HDA_OUTPUT));
1711                         if (err < 0)
1712                                 return err;
1713                 } else if (i == AUTO_SEQ_SIDE) {
1714                         sprintf(name, "%s Playback Volume", chname[i]);
1715                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1716                                               HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1717                                                                   HDA_OUTPUT));
1718                         if (err < 0)
1719                                 return err;
1720                         sprintf(name, "%s Playback Switch", chname[i]);
1721                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1722                                               HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1723                                                                   HDA_OUTPUT));
1724                         if (err < 0)
1725                                 return err;
1726                 }
1727         }
1728
1729         return 0;
1730 }
1731
1732 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1733 {
1734         int err;
1735
1736         if (!pin)
1737                 return 0;
1738
1739         if (spec->multiout.num_dacs == 5) /* 10 channels */
1740                 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1741         else if (spec->multiout.num_dacs == 3) /* 6 channels */
1742                 spec->multiout.hp_nid = 0;
1743
1744         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1745                               "Headphone Playback Volume",
1746                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1747         if (err < 0)
1748                 return err;
1749         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1750                               "Headphone Playback Switch",
1751                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1752         if (err < 0)
1753                 return err;
1754
1755         return 0;
1756 }
1757
1758 /* create playback/capture controls for input pins */
1759 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1760                                                 const struct auto_pin_cfg *cfg)
1761 {
1762         static char *labels[] = {
1763                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1764         };
1765         struct hda_input_mux *imux = &spec->private_imux[0];
1766         int i, err, idx = 0;
1767
1768         /* for internal loopback recording select */
1769         imux->items[imux->num_items].label = "Stereo Mixer";
1770         imux->items[imux->num_items].index = idx;
1771         imux->num_items++;
1772
1773         for (i = 0; i < AUTO_PIN_LAST; i++) {
1774                 if (!cfg->input_pins[i])
1775                         continue;
1776
1777                 switch (cfg->input_pins[i]) {
1778                 case 0x1d: /* Mic */
1779                         idx = 2;
1780                         break;
1781                                 
1782                 case 0x1e: /* Line In */
1783                         idx = 3;
1784                         break;
1785
1786                 case 0x21: /* Front Mic */
1787                         idx = 4;
1788                         break;
1789
1790                 case 0x23: /* CD */
1791                         idx = 1;
1792                         break;
1793                 }
1794                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1795                                            idx, 0x18);
1796                 if (err < 0)
1797                         return err;
1798                 imux->items[imux->num_items].label = labels[i];
1799                 imux->items[imux->num_items].index = idx;
1800                 imux->num_items++;
1801         }
1802         return 0;
1803 }
1804
1805 static int vt1709_parse_auto_config(struct hda_codec *codec)
1806 {
1807         struct via_spec *spec = codec->spec;
1808         int err;
1809
1810         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1811         if (err < 0)
1812                 return err;
1813         err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
1814         if (err < 0)
1815                 return err;
1816         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1817                 return 0; /* can't find valid BIOS pin config */
1818
1819         err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
1820         if (err < 0)
1821                 return err;
1822         err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1823         if (err < 0)
1824                 return err;
1825         err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
1826         if (err < 0)
1827                 return err;
1828
1829         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1830
1831         if (spec->autocfg.dig_out_pin)
1832                 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
1833         if (spec->autocfg.dig_in_pin)
1834                 spec->dig_in_nid = VT1709_DIGIN_NID;
1835
1836         if (spec->kctls.list)
1837                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1838
1839         spec->input_mux = &spec->private_imux[0];
1840
1841         if (spec->hp_mux)
1842                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
1843
1844         return 1;
1845 }
1846
1847 #ifdef CONFIG_SND_HDA_POWER_SAVE
1848 static struct hda_amp_list vt1709_loopbacks[] = {
1849         { 0x18, HDA_INPUT, 1 },
1850         { 0x18, HDA_INPUT, 2 },
1851         { 0x18, HDA_INPUT, 3 },
1852         { 0x18, HDA_INPUT, 4 },
1853         { } /* end */
1854 };
1855 #endif
1856
1857 static int patch_vt1709_10ch(struct hda_codec *codec)
1858 {
1859         struct via_spec *spec;
1860         int err;
1861
1862         /* create a codec specific record */
1863         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1864         if (spec == NULL)
1865                 return -ENOMEM;
1866
1867         codec->spec = spec;
1868
1869         err = vt1709_parse_auto_config(codec);
1870         if (err < 0) {
1871                 via_free(codec);
1872                 return err;
1873         } else if (!err) {
1874                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1875                        "Using genenic mode...\n");
1876         }
1877
1878         spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
1879         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
1880
1881         spec->stream_name_analog = "VT1709 Analog";
1882         spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
1883         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1884
1885         spec->stream_name_digital = "VT1709 Digital";
1886         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1887         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1888
1889         
1890         if (!spec->adc_nids && spec->input_mux) {
1891                 spec->adc_nids = vt1709_adc_nids;
1892                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1893                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1894                 spec->num_mixers++;
1895         }
1896
1897         codec->patch_ops = via_patch_ops;
1898
1899         codec->patch_ops.init = via_auto_init;
1900         codec->patch_ops.unsol_event = via_unsol_event;
1901 #ifdef CONFIG_SND_HDA_POWER_SAVE
1902         spec->loopback.amplist = vt1709_loopbacks;
1903 #endif
1904
1905         return 0;
1906 }
1907 /*
1908  * generic initialization of ADC, input mixers and output mixers
1909  */
1910 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
1911         /*
1912          * Unmute ADC0-2 and set the default input to mic-in
1913          */
1914         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1915         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1916         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1917
1918
1919         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1920          * mixer widget
1921          */
1922         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1923         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1924         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1925         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1926         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1927         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1928
1929         /*
1930          * Set up output selector (0x1a, 0x1b, 0x29)
1931          */
1932         /* set vol=0 to output mixers */
1933         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1934         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1935         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1936
1937         /*
1938          *  Unmute PW3 and PW4
1939          */
1940         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1941         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1942
1943         /* Set input of PW4 as MW0 */
1944         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1945         /* PW9 Output enable */
1946         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1947         { }
1948 };
1949
1950 static int patch_vt1709_6ch(struct hda_codec *codec)
1951 {
1952         struct via_spec *spec;
1953         int err;
1954
1955         /* create a codec specific record */
1956         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1957         if (spec == NULL)
1958                 return -ENOMEM;
1959
1960         codec->spec = spec;
1961
1962         err = vt1709_parse_auto_config(codec);
1963         if (err < 0) {
1964                 via_free(codec);
1965                 return err;
1966         } else if (!err) {
1967                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1968                        "Using genenic mode...\n");
1969         }
1970
1971         spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
1972         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
1973
1974         spec->stream_name_analog = "VT1709 Analog";
1975         spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
1976         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1977
1978         spec->stream_name_digital = "VT1709 Digital";
1979         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1980         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1981
1982         
1983         if (!spec->adc_nids && spec->input_mux) {
1984                 spec->adc_nids = vt1709_adc_nids;
1985                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1986                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1987                 spec->num_mixers++;
1988         }
1989
1990         codec->patch_ops = via_patch_ops;
1991
1992         codec->patch_ops.init = via_auto_init;
1993         codec->patch_ops.unsol_event = via_unsol_event;
1994 #ifdef CONFIG_SND_HDA_POWER_SAVE
1995         spec->loopback.amplist = vt1709_loopbacks;
1996 #endif
1997         return 0;
1998 }
1999
2000 /* capture mixer elements */
2001 static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
2002         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2003         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2004         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2005         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2006         {
2007                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2008                 /* The multiple "Capture Source" controls confuse alsamixer
2009                  * So call somewhat different..
2010                  */
2011                 /* .name = "Capture Source", */
2012                 .name = "Input Source",
2013                 .count = 1,
2014                 .info = via_mux_enum_info,
2015                 .get = via_mux_enum_get,
2016                 .put = via_mux_enum_put,
2017         },
2018         { } /* end */
2019 };
2020 /*
2021  * generic initialization of ADC, input mixers and output mixers
2022  */
2023 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
2024         /*
2025          * Unmute ADC0-1 and set the default input to mic-in
2026          */
2027         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2028         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2029
2030
2031         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2032          * mixer widget
2033          */
2034         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2035         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2036         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2037         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2038         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2039         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2040
2041         /*
2042          * Set up output mixers
2043          */
2044         /* set vol=0 to output mixers */
2045         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2046         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2047         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2048
2049         /* Setup default input to PW4 */
2050         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1},
2051         /* PW9 Output enable */
2052         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2053         /* PW10 Input enable */
2054         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2055         { }
2056 };
2057
2058 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
2059         /*
2060          * Unmute ADC0-1 and set the default input to mic-in
2061          */
2062         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2063         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2064
2065
2066         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2067          * mixer widget
2068          */
2069         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2070         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2071         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2072         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2073         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2074         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2075
2076         /*
2077          * Set up output mixers
2078          */
2079         /* set vol=0 to output mixers */
2080         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2081         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2082         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2083
2084         /* Setup default input of PW4 to MW0 */
2085         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2086         /* PW9 Output enable */
2087         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2088         /* PW10 Input enable */
2089         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2090         { }
2091 };
2092
2093 static struct hda_verb vt1708B_uniwill_init_verbs[] = {
2094         {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2095         { }
2096 };
2097
2098 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
2099         .substreams = 2,
2100         .channels_min = 2,
2101         .channels_max = 8,
2102         .nid = 0x10, /* NID to query formats and rates */
2103         .ops = {
2104                 .open = via_playback_pcm_open,
2105                 .prepare = via_playback_multi_pcm_prepare,
2106                 .cleanup = via_playback_multi_pcm_cleanup
2107         },
2108 };
2109
2110 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
2111         .substreams = 2,
2112         .channels_min = 2,
2113         .channels_max = 4,
2114         .nid = 0x10, /* NID to query formats and rates */
2115         .ops = {
2116                 .open = via_playback_pcm_open,
2117                 .prepare = via_playback_multi_pcm_prepare,
2118                 .cleanup = via_playback_multi_pcm_cleanup
2119         },
2120 };
2121
2122 static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
2123         .substreams = 2,
2124         .channels_min = 2,
2125         .channels_max = 2,
2126         .nid = 0x13, /* NID to query formats and rates */
2127         .ops = {
2128                 .prepare = via_capture_pcm_prepare,
2129                 .cleanup = via_capture_pcm_cleanup
2130         },
2131 };
2132
2133 static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
2134         .substreams = 1,
2135         .channels_min = 2,
2136         .channels_max = 2,
2137         /* NID is set in via_build_pcms */
2138         .ops = {
2139                 .open = via_dig_playback_pcm_open,
2140                 .close = via_dig_playback_pcm_close,
2141                 .prepare = via_dig_playback_pcm_prepare
2142         },
2143 };
2144
2145 static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
2146         .substreams = 1,
2147         .channels_min = 2,
2148         .channels_max = 2,
2149 };
2150
2151 /* fill in the dac_nids table from the parsed pin configuration */
2152 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
2153                                      const struct auto_pin_cfg *cfg)
2154 {
2155         int i;
2156         hda_nid_t nid;
2157
2158         spec->multiout.num_dacs = cfg->line_outs;
2159
2160         spec->multiout.dac_nids = spec->private_dac_nids;
2161
2162         for (i = 0; i < 4; i++) {
2163                 nid = cfg->line_out_pins[i];
2164                 if (nid) {
2165                         /* config dac list */
2166                         switch (i) {
2167                         case AUTO_SEQ_FRONT:
2168                                 spec->multiout.dac_nids[i] = 0x10;
2169                                 break;
2170                         case AUTO_SEQ_CENLFE:
2171                                 spec->multiout.dac_nids[i] = 0x24;
2172                                 break;
2173                         case AUTO_SEQ_SURROUND:
2174                                 spec->multiout.dac_nids[i] = 0x11;
2175                                 break;
2176                         case AUTO_SEQ_SIDE:
2177                                 spec->multiout.dac_nids[i] = 0x25;
2178                                 break;
2179                         }
2180                 }
2181         }
2182
2183         return 0;
2184 }
2185
2186 /* add playback controls from the parsed DAC table */
2187 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
2188                                              const struct auto_pin_cfg *cfg)
2189 {
2190         char name[32];
2191         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2192         hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
2193         hda_nid_t nid, nid_vol = 0;
2194         int i, err;
2195
2196         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2197                 nid = cfg->line_out_pins[i];
2198
2199                 if (!nid)
2200                         continue;
2201
2202                 nid_vol = nid_vols[i];
2203
2204                 if (i == AUTO_SEQ_CENLFE) {
2205                         /* Center/LFE */
2206                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2207                                               "Center Playback Volume",
2208                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2209                                                                   HDA_OUTPUT));
2210                         if (err < 0)
2211                                 return err;
2212                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2213                                               "LFE Playback Volume",
2214                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2215                                                                   HDA_OUTPUT));
2216                         if (err < 0)
2217                                 return err;
2218                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2219                                               "Center Playback Switch",
2220                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2221                                                                   HDA_OUTPUT));
2222                         if (err < 0)
2223                                 return err;
2224                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2225                                               "LFE Playback Switch",
2226                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2227                                                                   HDA_OUTPUT));
2228                         if (err < 0)
2229                                 return err;
2230                 } else if (i == AUTO_SEQ_FRONT) {
2231                         /* add control to mixer index 0 */
2232                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2233                                               "Master Front Playback Volume",
2234                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2235                                                                   HDA_INPUT));
2236                         if (err < 0)
2237                                 return err;
2238                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2239                                               "Master Front Playback Switch",
2240                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2241                                                                   HDA_INPUT));
2242                         if (err < 0)
2243                                 return err;
2244
2245                         /* add control to PW3 */
2246                         sprintf(name, "%s Playback Volume", chname[i]);
2247                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2248                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2249                                                                   HDA_OUTPUT));
2250                         if (err < 0)
2251                                 return err;
2252                         sprintf(name, "%s Playback Switch", chname[i]);
2253                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2254                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2255                                                                   HDA_OUTPUT));
2256                         if (err < 0)
2257                                 return err;
2258                 } else {
2259                         sprintf(name, "%s Playback Volume", chname[i]);
2260                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2261                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2262                                                                   HDA_OUTPUT));
2263                         if (err < 0)
2264                                 return err;
2265                         sprintf(name, "%s Playback Switch", chname[i]);
2266                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2267                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2268                                                                   HDA_OUTPUT));
2269                         if (err < 0)
2270                                 return err;
2271                 }
2272         }
2273
2274         return 0;
2275 }
2276
2277 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2278 {
2279         int err;
2280
2281         if (!pin)
2282                 return 0;
2283
2284         spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
2285
2286         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2287                               "Headphone Playback Volume",
2288                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2289         if (err < 0)
2290                 return err;
2291         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2292                               "Headphone Playback Switch",
2293                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2294         if (err < 0)
2295                 return err;
2296
2297         create_hp_imux(spec);
2298
2299         return 0;
2300 }
2301
2302 /* create playback/capture controls for input pins */
2303 static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
2304                                                 const struct auto_pin_cfg *cfg)
2305 {
2306         static char *labels[] = {
2307                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2308         };
2309         struct hda_input_mux *imux = &spec->private_imux[0];
2310         int i, err, idx = 0;
2311
2312         /* for internal loopback recording select */
2313         imux->items[imux->num_items].label = "Stereo Mixer";
2314         imux->items[imux->num_items].index = idx;
2315         imux->num_items++;
2316
2317         for (i = 0; i < AUTO_PIN_LAST; i++) {
2318                 if (!cfg->input_pins[i])
2319                         continue;
2320
2321                 switch (cfg->input_pins[i]) {
2322                 case 0x1a: /* Mic */
2323                         idx = 2;
2324                         break;
2325
2326                 case 0x1b: /* Line In */
2327                         idx = 3;
2328                         break;
2329
2330                 case 0x1e: /* Front Mic */
2331                         idx = 4;
2332                         break;
2333
2334                 case 0x1f: /* CD */
2335                         idx = 1;
2336                         break;
2337                 }
2338                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
2339                                            idx, 0x16);
2340                 if (err < 0)
2341                         return err;
2342                 imux->items[imux->num_items].label = labels[i];
2343                 imux->items[imux->num_items].index = idx;
2344                 imux->num_items++;
2345         }
2346         return 0;
2347 }
2348
2349 static int vt1708B_parse_auto_config(struct hda_codec *codec)
2350 {
2351         struct via_spec *spec = codec->spec;
2352         int err;
2353
2354         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2355         if (err < 0)
2356                 return err;
2357         err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
2358         if (err < 0)
2359                 return err;
2360         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2361                 return 0; /* can't find valid BIOS pin config */
2362
2363         err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
2364         if (err < 0)
2365                 return err;
2366         err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2367         if (err < 0)
2368                 return err;
2369         err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
2370         if (err < 0)
2371                 return err;
2372
2373         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2374
2375         if (spec->autocfg.dig_out_pin)
2376                 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
2377         if (spec->autocfg.dig_in_pin)
2378                 spec->dig_in_nid = VT1708B_DIGIN_NID;
2379
2380         if (spec->kctls.list)
2381                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2382
2383         spec->input_mux = &spec->private_imux[0];
2384
2385         if (spec->hp_mux)
2386                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2387
2388         return 1;
2389 }
2390
2391 #ifdef CONFIG_SND_HDA_POWER_SAVE
2392 static struct hda_amp_list vt1708B_loopbacks[] = {
2393         { 0x16, HDA_INPUT, 1 },
2394         { 0x16, HDA_INPUT, 2 },
2395         { 0x16, HDA_INPUT, 3 },
2396         { 0x16, HDA_INPUT, 4 },
2397         { } /* end */
2398 };
2399 #endif
2400
2401 static int patch_vt1708B_8ch(struct hda_codec *codec)
2402 {
2403         struct via_spec *spec;
2404         int err;
2405
2406         /* create a codec specific record */
2407         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2408         if (spec == NULL)
2409                 return -ENOMEM;
2410
2411         codec->spec = spec;
2412
2413         /* automatic parse from the BIOS config */
2414         err = vt1708B_parse_auto_config(codec);
2415         if (err < 0) {
2416                 via_free(codec);
2417                 return err;
2418         } else if (!err) {
2419                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2420                        "from BIOS.  Using genenic mode...\n");
2421         }
2422
2423         spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
2424         spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
2425
2426         spec->stream_name_analog = "VT1708B Analog";
2427         spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
2428         spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
2429
2430         spec->stream_name_digital = "VT1708B Digital";
2431         spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
2432         spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
2433
2434         if (!spec->adc_nids && spec->input_mux) {
2435                 spec->adc_nids = vt1708B_adc_nids;
2436                 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
2437                 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
2438                 spec->num_mixers++;
2439         }
2440
2441         codec->patch_ops = via_patch_ops;
2442
2443         codec->patch_ops.init = via_auto_init;
2444         codec->patch_ops.unsol_event = via_unsol_event;
2445 #ifdef CONFIG_SND_HDA_POWER_SAVE
2446         spec->loopback.amplist = vt1708B_loopbacks;
2447 #endif
2448
2449         return 0;
2450 }
2451
2452 static int patch_vt1708B_4ch(struct hda_codec *codec)
2453 {
2454         struct via_spec *spec;
2455         int err;
2456
2457         /* create a codec specific record */
2458         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2459         if (spec == NULL)
2460                 return -ENOMEM;
2461
2462         codec->spec = spec;
2463
2464         /* automatic parse from the BIOS config */
2465         err = vt1708B_parse_auto_config(codec);
2466         if (err < 0) {
2467                 via_free(codec);
2468                 return err;
2469         } else if (!err) {
2470                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2471                        "from BIOS.  Using genenic mode...\n");
2472         }
2473
2474         spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
2475         spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
2476
2477         spec->stream_name_analog = "VT1708B Analog";
2478         spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
2479         spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
2480
2481         spec->stream_name_digital = "VT1708B Digital";
2482         spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
2483         spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
2484
2485         if (!spec->adc_nids && spec->input_mux) {
2486                 spec->adc_nids = vt1708B_adc_nids;
2487                 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
2488                 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
2489                 spec->num_mixers++;
2490         }
2491
2492         codec->patch_ops = via_patch_ops;
2493
2494         codec->patch_ops.init = via_auto_init;
2495         codec->patch_ops.unsol_event = via_unsol_event;
2496 #ifdef CONFIG_SND_HDA_POWER_SAVE
2497         spec->loopback.amplist = vt1708B_loopbacks;
2498 #endif
2499
2500         return 0;
2501 }
2502
2503 /* Patch for VT1708S */
2504
2505 /* VT1708S software backdoor based override for buggy hardware micboost
2506  * setting */
2507 #define MIC_BOOST_VOLUME(xname, nid) {                          \
2508         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
2509         .name = xname,                                  \
2510         .index = 0,                                     \
2511         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |     \
2512         SNDRV_CTL_ELEM_ACCESS_TLV_READ |                \
2513         SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,             \
2514         .info = mic_boost_volume_info,                  \
2515         .get = snd_hda_mixer_amp_volume_get,            \
2516         .put = snd_hda_mixer_amp_volume_put,            \
2517         .tlv = { .c = mic_boost_tlv },                  \
2518         .private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT) }
2519
2520 /* capture mixer elements */
2521 static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
2522         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2523         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2524         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2525         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2526         MIC_BOOST_VOLUME("Mic Boost Capture Volume", 0x1A),
2527         MIC_BOOST_VOLUME("Front Mic Boost Capture Volume", 0x1E),
2528         {
2529                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2530                 /* The multiple "Capture Source" controls confuse alsamixer
2531                  * So call somewhat different..
2532                  */
2533                 /* .name = "Capture Source", */
2534                 .name = "Input Source",
2535                 .count = 1,
2536                 .info = via_mux_enum_info,
2537                 .get = via_mux_enum_get,
2538                 .put = via_mux_enum_put,
2539         },
2540         { } /* end */
2541 };
2542
2543 static struct hda_verb vt1708S_volume_init_verbs[] = {
2544         /* Unmute ADC0-1 and set the default input to mic-in */
2545         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2546         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2547
2548         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
2549          * analog-loopback mixer widget */
2550         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2551         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2552         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2553         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2554         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2555         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2556
2557         /* Setup default input of PW4 to MW0 */
2558         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2559         /* PW9, PW10  Output enable */
2560         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2561         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2562         /* Enable Mic Boost Volume backdoor */
2563         {0x1, 0xf98, 0x1},
2564         { }
2565 };
2566
2567 static struct hda_verb vt1708S_uniwill_init_verbs[] = {
2568         {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2569         { }
2570 };
2571
2572 static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
2573         .substreams = 2,
2574         .channels_min = 2,
2575         .channels_max = 8,
2576         .nid = 0x10, /* NID to query formats and rates */
2577         .ops = {
2578                 .open = via_playback_pcm_open,
2579                 .prepare = via_playback_pcm_prepare,
2580                 .cleanup = via_playback_pcm_cleanup
2581         },
2582 };
2583
2584 static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
2585         .substreams = 2,
2586         .channels_min = 2,
2587         .channels_max = 2,
2588         .nid = 0x13, /* NID to query formats and rates */
2589         .ops = {
2590                 .prepare = via_capture_pcm_prepare,
2591                 .cleanup = via_capture_pcm_cleanup
2592         },
2593 };
2594
2595 static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
2596         .substreams = 2,
2597         .channels_min = 2,
2598         .channels_max = 2,
2599         /* NID is set in via_build_pcms */
2600         .ops = {
2601                 .open = via_dig_playback_pcm_open,
2602                 .close = via_dig_playback_pcm_close,
2603                 .prepare = via_dig_playback_pcm_prepare
2604         },
2605 };
2606
2607 /* fill in the dac_nids table from the parsed pin configuration */
2608 static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
2609                                      const struct auto_pin_cfg *cfg)
2610 {
2611         int i;
2612         hda_nid_t nid;
2613
2614         spec->multiout.num_dacs = cfg->line_outs;
2615
2616         spec->multiout.dac_nids = spec->private_dac_nids;
2617
2618         for (i = 0; i < 4; i++) {
2619                 nid = cfg->line_out_pins[i];
2620                 if (nid) {
2621                         /* config dac list */
2622                         switch (i) {
2623                         case AUTO_SEQ_FRONT:
2624                                 spec->multiout.dac_nids[i] = 0x10;
2625                                 break;
2626                         case AUTO_SEQ_CENLFE:
2627                                 spec->multiout.dac_nids[i] = 0x24;
2628                                 break;
2629                         case AUTO_SEQ_SURROUND:
2630                                 spec->multiout.dac_nids[i] = 0x11;
2631                                 break;
2632                         case AUTO_SEQ_SIDE:
2633                                 spec->multiout.dac_nids[i] = 0x25;
2634                                 break;
2635                         }
2636                 }
2637         }
2638
2639         return 0;
2640 }
2641
2642 /* add playback controls from the parsed DAC table */
2643 static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
2644                                              const struct auto_pin_cfg *cfg)
2645 {
2646         char name[32];
2647         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2648         hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
2649         hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
2650         hda_nid_t nid, nid_vol, nid_mute;
2651         int i, err;
2652
2653         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2654                 nid = cfg->line_out_pins[i];
2655
2656                 if (!nid)
2657                         continue;
2658
2659                 nid_vol = nid_vols[i];
2660                 nid_mute = nid_mutes[i];
2661
2662                 if (i == AUTO_SEQ_CENLFE) {
2663                         /* Center/LFE */
2664                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2665                                               "Center Playback Volume",
2666                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2667                                                                   HDA_OUTPUT));
2668                         if (err < 0)
2669                                 return err;
2670                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2671                                               "LFE Playback Volume",
2672                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2673                                                                   HDA_OUTPUT));
2674                         if (err < 0)
2675                                 return err;
2676                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2677                                               "Center Playback Switch",
2678                                               HDA_COMPOSE_AMP_VAL(nid_mute,
2679                                                                   1, 0,
2680                                                                   HDA_OUTPUT));
2681                         if (err < 0)
2682                                 return err;
2683                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2684                                               "LFE Playback Switch",
2685                                               HDA_COMPOSE_AMP_VAL(nid_mute,
2686                                                                   2, 0,
2687                                                                   HDA_OUTPUT));
2688                         if (err < 0)
2689                                 return err;
2690                 } else if (i == AUTO_SEQ_FRONT) {
2691                         /* add control to mixer index 0 */
2692                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2693                                               "Master Front Playback Volume",
2694                                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
2695                                                                   HDA_INPUT));
2696                         if (err < 0)
2697                                 return err;
2698                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2699                                               "Master Front Playback Switch",
2700                                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
2701                                                                   HDA_INPUT));
2702                         if (err < 0)
2703                                 return err;
2704
2705                         /* Front */
2706                         sprintf(name, "%s Playback Volume", chname[i]);
2707                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2708                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2709                                                                   HDA_OUTPUT));
2710                         if (err < 0)
2711                                 return err;
2712                         sprintf(name, "%s Playback Switch", chname[i]);
2713                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2714                                               HDA_COMPOSE_AMP_VAL(nid_mute,
2715                                                                   3, 0,
2716                                                                   HDA_OUTPUT));
2717                         if (err < 0)
2718                                 return err;
2719                 } else {
2720                         sprintf(name, "%s Playback Volume", chname[i]);
2721                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2722                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2723                                                                   HDA_OUTPUT));
2724                         if (err < 0)
2725                                 return err;
2726                         sprintf(name, "%s Playback Switch", chname[i]);
2727                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2728                                               HDA_COMPOSE_AMP_VAL(nid_mute,
2729                                                                   3, 0,
2730                                                                   HDA_OUTPUT));
2731                         if (err < 0)
2732                                 return err;
2733                 }
2734         }
2735
2736         return 0;
2737 }
2738
2739 static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2740 {
2741         int err;
2742
2743         if (!pin)
2744                 return 0;
2745
2746         spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
2747
2748         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2749                               "Headphone Playback Volume",
2750                               HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
2751         if (err < 0)
2752                 return err;
2753
2754         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2755                               "Headphone Playback Switch",
2756                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2757         if (err < 0)
2758                 return err;
2759
2760         create_hp_imux(spec);
2761
2762         return 0;
2763 }
2764
2765 /* create playback/capture controls for input pins */
2766 static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
2767                                                 const struct auto_pin_cfg *cfg)
2768 {
2769         static char *labels[] = {
2770                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2771         };
2772         struct hda_input_mux *imux = &spec->private_imux[0];
2773         int i, err, idx = 0;
2774
2775         /* for internal loopback recording select */
2776         imux->items[imux->num_items].label = "Stereo Mixer";
2777         imux->items[imux->num_items].index = 5;
2778         imux->num_items++;
2779
2780         for (i = 0; i < AUTO_PIN_LAST; i++) {
2781                 if (!cfg->input_pins[i])
2782                         continue;
2783
2784                 switch (cfg->input_pins[i]) {
2785                 case 0x1a: /* Mic */
2786                         idx = 2;
2787                         break;
2788
2789                 case 0x1b: /* Line In */
2790                         idx = 3;
2791                         break;
2792
2793                 case 0x1e: /* Front Mic */
2794                         idx = 4;
2795                         break;
2796
2797                 case 0x1f: /* CD */
2798                         idx = 1;
2799                         break;
2800                 }
2801                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
2802                                            idx, 0x16);
2803                 if (err < 0)
2804                         return err;
2805                 imux->items[imux->num_items].label = labels[i];
2806                 imux->items[imux->num_items].index = idx-1;
2807                 imux->num_items++;
2808         }
2809         return 0;
2810 }
2811
2812 static int vt1708S_parse_auto_config(struct hda_codec *codec)
2813 {
2814         struct via_spec *spec = codec->spec;
2815         int err;
2816         static hda_nid_t vt1708s_ignore[] = {0x21, 0};
2817
2818         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
2819                                            vt1708s_ignore);
2820         if (err < 0)
2821                 return err;
2822         err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
2823         if (err < 0)
2824                 return err;
2825         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2826                 return 0; /* can't find valid BIOS pin config */
2827
2828         err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
2829         if (err < 0)
2830                 return err;
2831         err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2832         if (err < 0)
2833                 return err;
2834         err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg);
2835         if (err < 0)
2836                 return err;
2837
2838         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2839
2840         if (spec->autocfg.dig_out_pin)
2841                 spec->multiout.dig_out_nid = VT1708S_DIGOUT_NID;
2842
2843         spec->extra_dig_out_nid = 0x15;
2844
2845         if (spec->kctls.list)
2846                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2847
2848         spec->input_mux = &spec->private_imux[0];
2849
2850         if (spec->hp_mux)
2851                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2852
2853         return 1;
2854 }
2855
2856 #ifdef CONFIG_SND_HDA_POWER_SAVE
2857 static struct hda_amp_list vt1708S_loopbacks[] = {
2858         { 0x16, HDA_INPUT, 1 },
2859         { 0x16, HDA_INPUT, 2 },
2860         { 0x16, HDA_INPUT, 3 },
2861         { 0x16, HDA_INPUT, 4 },
2862         { } /* end */
2863 };
2864 #endif
2865
2866 static int patch_vt1708S(struct hda_codec *codec)
2867 {
2868         struct via_spec *spec;
2869         int err;
2870
2871         /* create a codec specific record */
2872         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2873         if (spec == NULL)
2874                 return -ENOMEM;
2875
2876         codec->spec = spec;
2877
2878         /* automatic parse from the BIOS config */
2879         err = vt1708S_parse_auto_config(codec);
2880         if (err < 0) {
2881                 via_free(codec);
2882                 return err;
2883         } else if (!err) {
2884                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2885                        "from BIOS.  Using genenic mode...\n");
2886         }
2887
2888         spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
2889         spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
2890
2891         spec->stream_name_analog = "VT1708S Analog";
2892         spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
2893         spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
2894
2895         spec->stream_name_digital = "VT1708S Digital";
2896         spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
2897
2898         if (!spec->adc_nids && spec->input_mux) {
2899                 spec->adc_nids = vt1708S_adc_nids;
2900                 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
2901                 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
2902                 spec->num_mixers++;
2903         }
2904
2905         codec->patch_ops = via_patch_ops;
2906
2907         codec->patch_ops.init = via_auto_init;
2908         codec->patch_ops.unsol_event = via_unsol_event;
2909 #ifdef CONFIG_SND_HDA_POWER_SAVE
2910         spec->loopback.amplist = vt1708S_loopbacks;
2911 #endif
2912
2913         return 0;
2914 }
2915
2916 /* Patch for VT1702 */
2917
2918 /* capture mixer elements */
2919 static struct snd_kcontrol_new vt1702_capture_mixer[] = {
2920         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
2921         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
2922         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
2923         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
2924         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
2925         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
2926         HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
2927                          HDA_INPUT),
2928         {
2929                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2930                 /* The multiple "Capture Source" controls confuse alsamixer
2931                  * So call somewhat different..
2932                  */
2933                 /* .name = "Capture Source", */
2934                 .name = "Input Source",
2935                 .count = 1,
2936                 .info = via_mux_enum_info,
2937                 .get = via_mux_enum_get,
2938                 .put = via_mux_enum_put,
2939         },
2940         { } /* end */
2941 };
2942
2943 static struct hda_verb vt1702_volume_init_verbs[] = {
2944         /*
2945          * Unmute ADC0-1 and set the default input to mic-in
2946          */
2947         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2948         {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2949         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2950
2951
2952         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2953          * mixer widget
2954          */
2955         /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
2956         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2957         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2958         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2959         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2960         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2961
2962         /* Setup default input of PW4 to MW0 */
2963         {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
2964         /* PW6 PW7 Output enable */
2965         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2966         {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2967         { }
2968 };
2969
2970 static struct hda_verb vt1702_uniwill_init_verbs[] = {
2971         {0x01, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_GPIO_EVENT},
2972         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2973         { }
2974 };
2975
2976 static struct hda_pcm_stream vt1702_pcm_analog_playback = {
2977         .substreams = 2,
2978         .channels_min = 2,
2979         .channels_max = 2,
2980         .nid = 0x10, /* NID to query formats and rates */
2981         .ops = {
2982                 .open = via_playback_pcm_open,
2983                 .prepare = via_playback_multi_pcm_prepare,
2984                 .cleanup = via_playback_multi_pcm_cleanup
2985         },
2986 };
2987
2988 static struct hda_pcm_stream vt1702_pcm_analog_capture = {
2989         .substreams = 3,
2990         .channels_min = 2,
2991         .channels_max = 2,
2992         .nid = 0x12, /* NID to query formats and rates */
2993         .ops = {
2994                 .prepare = via_capture_pcm_prepare,
2995                 .cleanup = via_capture_pcm_cleanup
2996         },
2997 };
2998
2999 static struct hda_pcm_stream vt1702_pcm_digital_playback = {
3000         .substreams = 2,
3001         .channels_min = 2,
3002         .channels_max = 2,
3003         /* NID is set in via_build_pcms */
3004         .ops = {
3005                 .open = via_dig_playback_pcm_open,
3006                 .close = via_dig_playback_pcm_close,
3007                 .prepare = via_dig_playback_pcm_prepare
3008         },
3009 };
3010
3011 /* fill in the dac_nids table from the parsed pin configuration */
3012 static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
3013                                      const struct auto_pin_cfg *cfg)
3014 {
3015         spec->multiout.num_dacs = 1;
3016         spec->multiout.dac_nids = spec->private_dac_nids;
3017
3018         if (cfg->line_out_pins[0]) {
3019                 /* config dac list */
3020                 spec->multiout.dac_nids[0] = 0x10;
3021         }
3022
3023         return 0;
3024 }
3025
3026 /* add playback controls from the parsed DAC table */
3027 static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
3028                                              const struct auto_pin_cfg *cfg)
3029 {
3030         int err;
3031
3032         if (!cfg->line_out_pins[0])
3033                 return -1;
3034
3035         /* add control to mixer index 0 */
3036         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3037                               "Master Front Playback Volume",
3038                               HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
3039         if (err < 0)
3040                 return err;
3041         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3042                               "Master Front Playback Switch",
3043                               HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
3044         if (err < 0)
3045                 return err;
3046
3047         /* Front */
3048         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3049                               "Front Playback Volume",
3050                               HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
3051         if (err < 0)
3052                 return err;
3053         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3054                               "Front Playback Switch",
3055                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
3056         if (err < 0)
3057                 return err;
3058
3059         return 0;
3060 }
3061
3062 static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3063 {
3064         int err;
3065
3066         if (!pin)
3067                 return 0;
3068
3069         spec->multiout.hp_nid = 0x1D;
3070
3071         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3072                               "Headphone Playback Volume",
3073                               HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
3074         if (err < 0)
3075                 return err;
3076
3077         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3078                               "Headphone Playback Switch",
3079                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3080         if (err < 0)
3081                 return err;
3082
3083         create_hp_imux(spec);
3084
3085         return 0;
3086 }
3087
3088 /* create playback/capture controls for input pins */
3089 static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
3090                                                 const struct auto_pin_cfg *cfg)
3091 {
3092         static char *labels[] = {
3093                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
3094         };
3095         struct hda_input_mux *imux = &spec->private_imux[0];
3096         int i, err, idx = 0;
3097
3098         /* for internal loopback recording select */
3099         imux->items[imux->num_items].label = "Stereo Mixer";
3100         imux->items[imux->num_items].index = 3;
3101         imux->num_items++;
3102
3103         for (i = 0; i < AUTO_PIN_LAST; i++) {
3104                 if (!cfg->input_pins[i])
3105                         continue;
3106
3107                 switch (cfg->input_pins[i]) {
3108                 case 0x14: /* Mic */
3109                         idx = 1;
3110                         break;
3111
3112                 case 0x15: /* Line In */
3113                         idx = 2;
3114                         break;
3115
3116                 case 0x18: /* Front Mic */
3117                         idx = 3;
3118                         break;
3119                 }
3120                 err = via_new_analog_input(spec, cfg->input_pins[i],
3121                                            labels[i], idx, 0x1A);
3122                 if (err < 0)
3123                         return err;
3124                 imux->items[imux->num_items].label = labels[i];
3125                 imux->items[imux->num_items].index = idx-1;
3126                 imux->num_items++;
3127         }
3128         return 0;
3129 }
3130
3131 static int vt1702_parse_auto_config(struct hda_codec *codec)
3132 {
3133         struct via_spec *spec = codec->spec;
3134         int err;
3135         static hda_nid_t vt1702_ignore[] = {0x1C, 0};
3136
3137         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3138                                            vt1702_ignore);
3139         if (err < 0)
3140                 return err;
3141         err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
3142         if (err < 0)
3143                 return err;
3144         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3145                 return 0; /* can't find valid BIOS pin config */
3146
3147         err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
3148         if (err < 0)
3149                 return err;
3150         err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3151         if (err < 0)
3152                 return err;
3153         err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
3154         if (err < 0)
3155                 return err;
3156
3157         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3158
3159         if (spec->autocfg.dig_out_pin)
3160                 spec->multiout.dig_out_nid = VT1702_DIGOUT_NID;
3161
3162         spec->extra_dig_out_nid = 0x1B;
3163
3164         if (spec->kctls.list)
3165                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3166
3167         spec->input_mux = &spec->private_imux[0];
3168
3169         if (spec->hp_mux)
3170                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
3171
3172         return 1;
3173 }
3174
3175 #ifdef CONFIG_SND_HDA_POWER_SAVE
3176 static struct hda_amp_list vt1702_loopbacks[] = {
3177         { 0x1A, HDA_INPUT, 1 },
3178         { 0x1A, HDA_INPUT, 2 },
3179         { 0x1A, HDA_INPUT, 3 },
3180         { 0x1A, HDA_INPUT, 4 },
3181         { } /* end */
3182 };
3183 #endif
3184
3185 static int patch_vt1702(struct hda_codec *codec)
3186 {
3187         struct via_spec *spec;
3188         int err;
3189         unsigned int response;
3190         unsigned char control;
3191
3192         /* create a codec specific record */
3193         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3194         if (spec == NULL)
3195                 return -ENOMEM;
3196
3197         codec->spec = spec;
3198
3199         /* automatic parse from the BIOS config */
3200         err = vt1702_parse_auto_config(codec);
3201         if (err < 0) {
3202                 via_free(codec);
3203                 return err;
3204         } else if (!err) {
3205                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3206                        "from BIOS.  Using genenic mode...\n");
3207         }
3208
3209         spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
3210         spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
3211
3212         spec->stream_name_analog = "VT1702 Analog";
3213         spec->stream_analog_playback = &vt1702_pcm_analog_playback;
3214         spec->stream_analog_capture = &vt1702_pcm_analog_capture;
3215
3216         spec->stream_name_digital = "VT1702 Digital";
3217         spec->stream_digital_playback = &vt1702_pcm_digital_playback;
3218
3219         if (!spec->adc_nids && spec->input_mux) {
3220                 spec->adc_nids = vt1702_adc_nids;
3221                 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
3222                 spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
3223                 spec->num_mixers++;
3224         }
3225
3226         codec->patch_ops = via_patch_ops;
3227
3228         codec->patch_ops.init = via_auto_init;
3229         codec->patch_ops.unsol_event = via_unsol_event;
3230 #ifdef CONFIG_SND_HDA_POWER_SAVE
3231         spec->loopback.amplist = vt1702_loopbacks;
3232 #endif
3233
3234         /* Open backdoor */
3235         response = snd_hda_codec_read(codec, codec->afg, 0, 0xF8C, 0);
3236         control = (unsigned char)(response & 0xff);
3237         control |= 0x3;
3238         snd_hda_codec_write(codec,  codec->afg, 0, 0xF88, control);
3239
3240         /* Enable GPIO 0&1 for volume&mute control */
3241         /* Enable GPIO 2 for DMIC-DATA */
3242         response = snd_hda_codec_read(codec, codec->afg, 0, 0xF84, 0);
3243         control = (unsigned char)((response >> 16) & 0x3f);
3244         snd_hda_codec_write(codec,  codec->afg, 0, 0xF82, control);
3245
3246         return 0;
3247 }
3248
3249 /*
3250  * patch entries
3251  */
3252 struct hda_codec_preset snd_hda_preset_via[] = {
3253         { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708},
3254         { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708},
3255         { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708},
3256         { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708},
3257         { .id = 0x1106E710, .name = "VIA VT1709 10-Ch",
3258           .patch = patch_vt1709_10ch},
3259         { .id = 0x1106E711, .name = "VIA VT1709 10-Ch",
3260           .patch = patch_vt1709_10ch},
3261         { .id = 0x1106E712, .name = "VIA VT1709 10-Ch",
3262           .patch = patch_vt1709_10ch},
3263         { .id = 0x1106E713, .name = "VIA VT1709 10-Ch",
3264           .patch = patch_vt1709_10ch},
3265         { .id = 0x1106E714, .name = "VIA VT1709 6-Ch",
3266           .patch = patch_vt1709_6ch},
3267         { .id = 0x1106E715, .name = "VIA VT1709 6-Ch",
3268           .patch = patch_vt1709_6ch},
3269         { .id = 0x1106E716, .name = "VIA VT1709 6-Ch",
3270           .patch = patch_vt1709_6ch},
3271         { .id = 0x1106E717, .name = "VIA VT1709 6-Ch",
3272           .patch = patch_vt1709_6ch},
3273         { .id = 0x1106E720, .name = "VIA VT1708B 8-Ch",
3274           .patch = patch_vt1708B_8ch},
3275         { .id = 0x1106E721, .name = "VIA VT1708B 8-Ch",
3276           .patch = patch_vt1708B_8ch},
3277         { .id = 0x1106E722, .name = "VIA VT1708B 8-Ch",
3278           .patch = patch_vt1708B_8ch},
3279         { .id = 0x1106E723, .name = "VIA VT1708B 8-Ch",
3280           .patch = patch_vt1708B_8ch},
3281         { .id = 0x1106E724, .name = "VIA VT1708B 4-Ch",
3282           .patch = patch_vt1708B_4ch},
3283         { .id = 0x1106E725, .name = "VIA VT1708B 4-Ch",
3284           .patch = patch_vt1708B_4ch},
3285         { .id = 0x1106E726, .name = "VIA VT1708B 4-Ch",
3286           .patch = patch_vt1708B_4ch},
3287         { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch",
3288           .patch = patch_vt1708B_4ch},
3289         { .id = 0x11060397, .name = "VIA VT1708S",
3290           .patch = patch_vt1708S},
3291         { .id = 0x11061397, .name = "VIA VT1708S",
3292           .patch = patch_vt1708S},
3293         { .id = 0x11062397, .name = "VIA VT1708S",
3294           .patch = patch_vt1708S},
3295         { .id = 0x11063397, .name = "VIA VT1708S",
3296           .patch = patch_vt1708S},
3297         { .id = 0x11064397, .name = "VIA VT1708S",
3298           .patch = patch_vt1708S},
3299         { .id = 0x11065397, .name = "VIA VT1708S",
3300           .patch = patch_vt1708S},
3301         { .id = 0x11066397, .name = "VIA VT1708S",
3302           .patch = patch_vt1708S},
3303         { .id = 0x11067397, .name = "VIA VT1708S",
3304           .patch = patch_vt1708S},
3305         { .id = 0x11060398, .name = "VIA VT1702",
3306           .patch = patch_vt1702},
3307         { .id = 0x11061398, .name = "VIA VT1702",
3308           .patch = patch_vt1702},
3309         { .id = 0x11062398, .name = "VIA VT1702",
3310           .patch = patch_vt1702},
3311         { .id = 0x11063398, .name = "VIA VT1702",
3312           .patch = patch_vt1702},
3313         { .id = 0x11064398, .name = "VIA VT1702",
3314           .patch = patch_vt1702},
3315         { .id = 0x11065398, .name = "VIA VT1702",
3316           .patch = patch_vt1702},
3317         { .id = 0x11066398, .name = "VIA VT1702",
3318           .patch = patch_vt1702},
3319         { .id = 0x11067398, .name = "VIA VT1702",
3320           .patch = patch_vt1702},
3321         {} /* terminator */
3322 };