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