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