Staging: comedi: remove C99 comments in das1800.c
[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 slave_dig_outs[2];
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 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
735                                         struct hda_codec *codec,
736                                         unsigned int stream_tag,
737                                         unsigned int format,
738                                         struct snd_pcm_substream *substream)
739 {
740         struct via_spec *spec = codec->spec;
741         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
742                                              stream_tag, format, substream);
743 }
744
745 static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
746                                         struct hda_codec *codec,
747                                         struct snd_pcm_substream *substream)
748 {
749         struct via_spec *spec = codec->spec;
750         snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
751         return 0;
752 }
753
754 /*
755  * Analog capture
756  */
757 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
758                                    struct hda_codec *codec,
759                                    unsigned int stream_tag,
760                                    unsigned int format,
761                                    struct snd_pcm_substream *substream)
762 {
763         struct via_spec *spec = codec->spec;
764
765         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
766                                    stream_tag, 0, format);
767         return 0;
768 }
769
770 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
771                                    struct hda_codec *codec,
772                                    struct snd_pcm_substream *substream)
773 {
774         struct via_spec *spec = codec->spec;
775         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
776         return 0;
777 }
778
779 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
780         .substreams = 2,
781         .channels_min = 2,
782         .channels_max = 8,
783         .nid = 0x10, /* NID to query formats and rates */
784         .ops = {
785                 .open = via_playback_pcm_open,
786                 .prepare = via_playback_multi_pcm_prepare,
787                 .cleanup = via_playback_multi_pcm_cleanup
788         },
789 };
790
791 static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
792         .substreams = 1,
793         .channels_min = 2,
794         .channels_max = 8,
795         .nid = 0x10, /* NID to query formats and rates */
796         /* We got noisy outputs on the right channel on VT1708 when
797          * 24bit samples are used.  Until any workaround is found,
798          * disable the 24bit format, so far.
799          */
800         .formats = SNDRV_PCM_FMTBIT_S16_LE,
801         .ops = {
802                 .open = via_playback_pcm_open,
803                 .prepare = via_playback_pcm_prepare,
804                 .cleanup = via_playback_pcm_cleanup
805         },
806 };
807
808 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
809         .substreams = 2,
810         .channels_min = 2,
811         .channels_max = 2,
812         .nid = 0x15, /* NID to query formats and rates */
813         .ops = {
814                 .prepare = via_capture_pcm_prepare,
815                 .cleanup = via_capture_pcm_cleanup
816         },
817 };
818
819 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
820         .substreams = 1,
821         .channels_min = 2,
822         .channels_max = 2,
823         /* NID is set in via_build_pcms */
824         .ops = {
825                 .open = via_dig_playback_pcm_open,
826                 .close = via_dig_playback_pcm_close,
827                 .prepare = via_dig_playback_pcm_prepare,
828                 .cleanup = via_dig_playback_pcm_cleanup
829         },
830 };
831
832 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
833         .substreams = 1,
834         .channels_min = 2,
835         .channels_max = 2,
836 };
837
838 static int via_build_controls(struct hda_codec *codec)
839 {
840         struct via_spec *spec = codec->spec;
841         int err;
842         int i;
843
844         for (i = 0; i < spec->num_mixers; i++) {
845                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
846                 if (err < 0)
847                         return err;
848         }
849
850         if (spec->multiout.dig_out_nid) {
851                 err = snd_hda_create_spdif_out_ctls(codec,
852                                                     spec->multiout.dig_out_nid);
853                 if (err < 0)
854                         return err;
855                 err = snd_hda_create_spdif_share_sw(codec,
856                                                     &spec->multiout);
857                 if (err < 0)
858                         return err;
859                 spec->multiout.share_spdif = 1;
860         }
861         if (spec->dig_in_nid) {
862                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
863                 if (err < 0)
864                         return err;
865         }
866         via_free_kctls(codec); /* no longer needed */
867         return 0;
868 }
869
870 static int via_build_pcms(struct hda_codec *codec)
871 {
872         struct via_spec *spec = codec->spec;
873         struct hda_pcm *info = spec->pcm_rec;
874
875         codec->num_pcms = 1;
876         codec->pcm_info = info;
877
878         info->name = spec->stream_name_analog;
879         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
880         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
881         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
882         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
883
884         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
885                 spec->multiout.max_channels;
886
887         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
888                 codec->num_pcms++;
889                 info++;
890                 info->name = spec->stream_name_digital;
891                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
892                 if (spec->multiout.dig_out_nid) {
893                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
894                                 *(spec->stream_digital_playback);
895                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
896                                 spec->multiout.dig_out_nid;
897                 }
898                 if (spec->dig_in_nid) {
899                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
900                                 *(spec->stream_digital_capture);
901                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
902                                 spec->dig_in_nid;
903                 }
904         }
905
906         return 0;
907 }
908
909 static void via_free(struct hda_codec *codec)
910 {
911         struct via_spec *spec = codec->spec;
912
913         if (!spec)
914                 return;
915
916         via_free_kctls(codec);
917         kfree(codec->spec);
918 }
919
920 /* mute internal speaker if HP is plugged */
921 static void via_hp_automute(struct hda_codec *codec)
922 {
923         unsigned int present;
924         struct via_spec *spec = codec->spec;
925
926         present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0,
927                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
928         snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
929                                  HDA_OUTPUT, 0, HDA_AMP_MUTE,
930                                  present ? HDA_AMP_MUTE : 0);
931 }
932
933 static void via_gpio_control(struct hda_codec *codec)
934 {
935         unsigned int gpio_data;
936         unsigned int vol_counter;
937         unsigned int vol;
938         unsigned int master_vol;
939
940         struct via_spec *spec = codec->spec;
941
942         gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
943                                        AC_VERB_GET_GPIO_DATA, 0) & 0x03;
944
945         vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
946                                           0xF84, 0) & 0x3F0000) >> 16;
947
948         vol = vol_counter & 0x1F;
949         master_vol = snd_hda_codec_read(codec, 0x1A, 0,
950                                         AC_VERB_GET_AMP_GAIN_MUTE,
951                                         AC_AMP_GET_INPUT);
952
953         if (gpio_data == 0x02) {
954                 /* unmute line out */
955                 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
956                                          HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
957
958                 if (vol_counter & 0x20) {
959                         /* decrease volume */
960                         if (vol > master_vol)
961                                 vol = master_vol;
962                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
963                                                  0, HDA_AMP_VOLMASK,
964                                                  master_vol-vol);
965                 } else {
966                         /* increase volume */
967                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
968                                          HDA_AMP_VOLMASK,
969                                          ((master_vol+vol) > 0x2A) ? 0x2A :
970                                           (master_vol+vol));
971                 }
972         } else if (!(gpio_data & 0x02)) {
973                 /* mute line out */
974                 snd_hda_codec_amp_stereo(codec,
975                                          spec->autocfg.line_out_pins[0],
976                                          HDA_OUTPUT, 0, HDA_AMP_MUTE,
977                                          HDA_AMP_MUTE);
978         }
979 }
980
981 /* unsolicited event for jack sensing */
982 static void via_unsol_event(struct hda_codec *codec,
983                                   unsigned int res)
984 {
985         res >>= 26;
986         if (res == VIA_HP_EVENT)
987                 via_hp_automute(codec);
988         else if (res == VIA_GPIO_EVENT)
989                 via_gpio_control(codec);
990 }
991
992 static int via_init(struct hda_codec *codec)
993 {
994         struct via_spec *spec = codec->spec;
995         int i;
996         for (i = 0; i < spec->num_iverbs; i++)
997                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
998
999         /* Lydia Add for EAPD enable */
1000         if (!spec->dig_in_nid) { /* No Digital In connection */
1001                 if (IS_VT1708_VENDORID(codec->vendor_id)) {
1002                         snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
1003                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1004                                             PIN_OUT);
1005                         snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
1006                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1007                 } else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) ||
1008                            IS_VT1709_6CH_VENDORID(codec->vendor_id)) {
1009                         snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
1010                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1011                                             PIN_OUT);
1012                         snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
1013                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1014                 } else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) ||
1015                            IS_VT1708B_4CH_VENDORID(codec->vendor_id)) {
1016                         snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
1017                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1018                                             PIN_OUT);
1019                         snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
1020                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1021                 }
1022         } else /* enable SPDIF-input pin */
1023                 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
1024                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
1025
1026         /* assign slave outs */
1027         if (spec->slave_dig_outs[0])
1028                 codec->slave_dig_outs = spec->slave_dig_outs;
1029
1030         return 0;
1031 }
1032
1033 #ifdef CONFIG_SND_HDA_POWER_SAVE
1034 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1035 {
1036         struct via_spec *spec = codec->spec;
1037         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
1038 }
1039 #endif
1040
1041 /*
1042  */
1043 static struct hda_codec_ops via_patch_ops = {
1044         .build_controls = via_build_controls,
1045         .build_pcms = via_build_pcms,
1046         .init = via_init,
1047         .free = via_free,
1048 #ifdef CONFIG_SND_HDA_POWER_SAVE
1049         .check_power_status = via_check_power_status,
1050 #endif
1051 };
1052
1053 /* fill in the dac_nids table from the parsed pin configuration */
1054 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
1055                                      const struct auto_pin_cfg *cfg)
1056 {
1057         int i;
1058         hda_nid_t nid;
1059
1060         spec->multiout.num_dacs = cfg->line_outs;
1061
1062         spec->multiout.dac_nids = spec->private_dac_nids;
1063         
1064         for(i = 0; i < 4; i++) {
1065                 nid = cfg->line_out_pins[i];
1066                 if (nid) {
1067                         /* config dac list */
1068                         switch (i) {
1069                         case AUTO_SEQ_FRONT:
1070                                 spec->multiout.dac_nids[i] = 0x10;
1071                                 break;
1072                         case AUTO_SEQ_CENLFE:
1073                                 spec->multiout.dac_nids[i] = 0x12;
1074                                 break;
1075                         case AUTO_SEQ_SURROUND:
1076                                 spec->multiout.dac_nids[i] = 0x11;
1077                                 break;
1078                         case AUTO_SEQ_SIDE:
1079                                 spec->multiout.dac_nids[i] = 0x13;
1080                                 break;
1081                         }
1082                 }
1083         }
1084
1085         return 0;
1086 }
1087
1088 /* add playback controls from the parsed DAC table */
1089 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
1090                                              const struct auto_pin_cfg *cfg)
1091 {
1092         char name[32];
1093         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1094         hda_nid_t nid, nid_vol = 0;
1095         int i, err;
1096
1097         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1098                 nid = cfg->line_out_pins[i];
1099
1100                 if (!nid)
1101                         continue;
1102                 
1103                 if (i != AUTO_SEQ_FRONT)
1104                         nid_vol = 0x18 + i;
1105
1106                 if (i == AUTO_SEQ_CENLFE) {
1107                         /* Center/LFE */
1108                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1109                                         "Center Playback Volume",
1110                                         HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1111                                                             HDA_OUTPUT));
1112                         if (err < 0)
1113                                 return err;
1114                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1115                                               "LFE Playback Volume",
1116                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1117                                                                   HDA_OUTPUT));
1118                         if (err < 0)
1119                                 return err;
1120                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1121                                               "Center Playback Switch",
1122                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1123                                                                   HDA_OUTPUT));
1124                         if (err < 0)
1125                                 return err;
1126                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1127                                               "LFE Playback Switch",
1128                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1129                                                                   HDA_OUTPUT));
1130                         if (err < 0)
1131                                 return err;
1132                 } else if (i == AUTO_SEQ_FRONT){
1133                         /* add control to mixer index 0 */
1134                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1135                                               "Master Front Playback Volume",
1136                                               HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
1137                                                                   HDA_INPUT));
1138                         if (err < 0)
1139                                 return err;
1140                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1141                                               "Master Front Playback Switch",
1142                                               HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
1143                                                                   HDA_INPUT));
1144                         if (err < 0)
1145                                 return err;
1146                         
1147                         /* add control to PW3 */
1148                         sprintf(name, "%s Playback Volume", chname[i]);
1149                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1150                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1151                                                                   HDA_OUTPUT));
1152                         if (err < 0)
1153                                 return err;
1154                         sprintf(name, "%s Playback Switch", chname[i]);
1155                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1156                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1157                                                                   HDA_OUTPUT));
1158                         if (err < 0)
1159                                 return err;
1160                 } else {
1161                         sprintf(name, "%s Playback Volume", chname[i]);
1162                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1163                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1164                                                                   HDA_OUTPUT));
1165                         if (err < 0)
1166                                 return err;
1167                         sprintf(name, "%s Playback Switch", chname[i]);
1168                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1169                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1170                                                                   HDA_OUTPUT));
1171                         if (err < 0)
1172                                 return err;
1173                 }
1174         }
1175
1176         return 0;
1177 }
1178
1179 static void create_hp_imux(struct via_spec *spec)
1180 {
1181         int i;
1182         struct hda_input_mux *imux = &spec->private_imux[1];
1183         static const char *texts[] = { "OFF", "ON", NULL};
1184
1185         /* for hp mode select */
1186         i = 0;
1187         while (texts[i] != NULL) {
1188                 imux->items[imux->num_items].label =  texts[i];
1189                 imux->items[imux->num_items].index = i;
1190                 imux->num_items++;
1191                 i++;
1192         }
1193
1194         spec->hp_mux = &spec->private_imux[1];
1195 }
1196
1197 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1198 {
1199         int err;
1200
1201         if (!pin)
1202                 return 0;
1203
1204         spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
1205
1206         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1207                               "Headphone Playback Volume",
1208                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1209         if (err < 0)
1210                 return err;
1211         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1212                               "Headphone Playback Switch",
1213                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1214         if (err < 0)
1215                 return err;
1216
1217         create_hp_imux(spec);
1218
1219         return 0;
1220 }
1221
1222 /* create playback/capture controls for input pins */
1223 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
1224                                                 const struct auto_pin_cfg *cfg)
1225 {
1226         static char *labels[] = {
1227                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1228         };
1229         struct hda_input_mux *imux = &spec->private_imux[0];
1230         int i, err, idx = 0;
1231
1232         /* for internal loopback recording select */
1233         imux->items[imux->num_items].label = "Stereo Mixer";
1234         imux->items[imux->num_items].index = idx;
1235         imux->num_items++;
1236
1237         for (i = 0; i < AUTO_PIN_LAST; i++) {
1238                 if (!cfg->input_pins[i])
1239                         continue;
1240
1241                 switch (cfg->input_pins[i]) {
1242                 case 0x1d: /* Mic */
1243                         idx = 2;
1244                         break;
1245                                 
1246                 case 0x1e: /* Line In */
1247                         idx = 3;
1248                         break;
1249
1250                 case 0x21: /* Front Mic */
1251                         idx = 4;
1252                         break;
1253
1254                 case 0x24: /* CD */
1255                         idx = 1;
1256                         break;
1257                 }
1258                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1259                                            idx, 0x17);
1260                 if (err < 0)
1261                         return err;
1262                 imux->items[imux->num_items].label = labels[i];
1263                 imux->items[imux->num_items].index = idx;
1264                 imux->num_items++;
1265         }
1266         return 0;
1267 }
1268
1269 #ifdef CONFIG_SND_HDA_POWER_SAVE
1270 static struct hda_amp_list vt1708_loopbacks[] = {
1271         { 0x17, HDA_INPUT, 1 },
1272         { 0x17, HDA_INPUT, 2 },
1273         { 0x17, HDA_INPUT, 3 },
1274         { 0x17, HDA_INPUT, 4 },
1275         { } /* end */
1276 };
1277 #endif
1278
1279 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
1280 {
1281         unsigned int def_conf;
1282         unsigned char seqassoc;
1283
1284         def_conf = snd_hda_codec_get_pincfg(codec, nid);
1285         seqassoc = (unsigned char) get_defcfg_association(def_conf);
1286         seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
1287         if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) {
1288                 if (seqassoc == 0xff) {
1289                         def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
1290                         snd_hda_codec_set_pincfg(codec, nid, def_conf);
1291                 }
1292         }
1293
1294         return;
1295 }
1296
1297 static int vt1708_parse_auto_config(struct hda_codec *codec)
1298 {
1299         struct via_spec *spec = codec->spec;
1300         int err;
1301
1302         /* Add HP and CD pin config connect bit re-config action */
1303         vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
1304         vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
1305
1306         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1307         if (err < 0)
1308                 return err;
1309         err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
1310         if (err < 0)
1311                 return err;
1312         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1313                 return 0; /* can't find valid BIOS pin config */
1314
1315         err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
1316         if (err < 0)
1317                 return err;
1318         err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1319         if (err < 0)
1320                 return err;
1321         err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
1322         if (err < 0)
1323                 return err;
1324
1325         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1326
1327         if (spec->autocfg.dig_outs)
1328                 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
1329         if (spec->autocfg.dig_in_pin)
1330                 spec->dig_in_nid = VT1708_DIGIN_NID;
1331
1332         if (spec->kctls.list)
1333                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1334
1335         spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
1336
1337         spec->input_mux = &spec->private_imux[0];
1338
1339         if (spec->hp_mux)
1340                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
1341
1342         return 1;
1343 }
1344
1345 /* init callback for auto-configuration model -- overriding the default init */
1346 static int via_auto_init(struct hda_codec *codec)
1347 {
1348         via_init(codec);
1349         via_auto_init_multi_out(codec);
1350         via_auto_init_hp_out(codec);
1351         via_auto_init_analog_input(codec);
1352         return 0;
1353 }
1354
1355 static int patch_vt1708(struct hda_codec *codec)
1356 {
1357         struct via_spec *spec;
1358         int err;
1359
1360         /* create a codec specific record */
1361         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1362         if (spec == NULL)
1363                 return -ENOMEM;
1364
1365         codec->spec = spec;
1366
1367         /* automatic parse from the BIOS config */
1368         err = vt1708_parse_auto_config(codec);
1369         if (err < 0) {
1370                 via_free(codec);
1371                 return err;
1372         } else if (!err) {
1373                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
1374                        "from BIOS.  Using genenic mode...\n");
1375         }
1376
1377         
1378         spec->stream_name_analog = "VT1708 Analog";
1379         spec->stream_analog_playback = &vt1708_pcm_analog_playback;
1380         /* disable 32bit format on VT1708 */
1381         if (codec->vendor_id == 0x11061708)
1382                 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
1383         spec->stream_analog_capture = &vt1708_pcm_analog_capture;
1384
1385         spec->stream_name_digital = "VT1708 Digital";
1386         spec->stream_digital_playback = &vt1708_pcm_digital_playback;
1387         spec->stream_digital_capture = &vt1708_pcm_digital_capture;
1388
1389         
1390         if (!spec->adc_nids && spec->input_mux) {
1391                 spec->adc_nids = vt1708_adc_nids;
1392                 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
1393                 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
1394                 spec->num_mixers++;
1395         }
1396
1397         codec->patch_ops = via_patch_ops;
1398
1399         codec->patch_ops.init = via_auto_init;
1400 #ifdef CONFIG_SND_HDA_POWER_SAVE
1401         spec->loopback.amplist = vt1708_loopbacks;
1402 #endif
1403
1404         return 0;
1405 }
1406
1407 /* capture mixer elements */
1408 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
1409         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
1410         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
1411         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
1412         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
1413         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
1414         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
1415         {
1416                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1417                 /* The multiple "Capture Source" controls confuse alsamixer
1418                  * So call somewhat different..
1419                  */
1420                 /* .name = "Capture Source", */
1421                 .name = "Input Source",
1422                 .count = 1,
1423                 .info = via_mux_enum_info,
1424                 .get = via_mux_enum_get,
1425                 .put = via_mux_enum_put,
1426         },
1427         { } /* end */
1428 };
1429
1430 static struct hda_verb vt1709_uniwill_init_verbs[] = {
1431         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
1432         { }
1433 };
1434
1435 /*
1436  * generic initialization of ADC, input mixers and output mixers
1437  */
1438 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
1439         /*
1440          * Unmute ADC0-2 and set the default input to mic-in
1441          */
1442         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1443         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1444         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1445
1446
1447         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1448          * mixer widget
1449          */
1450         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1451         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1452         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1453         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1454         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1455         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1456
1457         /*
1458          * Set up output selector (0x1a, 0x1b, 0x29)
1459          */
1460         /* set vol=0 to output mixers */
1461         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1462         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1463         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1464
1465         /*
1466          *  Unmute PW3 and PW4
1467          */
1468         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1469         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1470
1471         /* Set input of PW4 as AOW4 */
1472         {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
1473         /* PW9 Output enable */
1474         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1475         { }
1476 };
1477
1478 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
1479         .substreams = 1,
1480         .channels_min = 2,
1481         .channels_max = 10,
1482         .nid = 0x10, /* NID to query formats and rates */
1483         .ops = {
1484                 .open = via_playback_pcm_open,
1485                 .prepare = via_playback_pcm_prepare,
1486                 .cleanup = via_playback_pcm_cleanup
1487         },
1488 };
1489
1490 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
1491         .substreams = 1,
1492         .channels_min = 2,
1493         .channels_max = 6,
1494         .nid = 0x10, /* NID to query formats and rates */
1495         .ops = {
1496                 .open = via_playback_pcm_open,
1497                 .prepare = via_playback_pcm_prepare,
1498                 .cleanup = via_playback_pcm_cleanup
1499         },
1500 };
1501
1502 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
1503         .substreams = 2,
1504         .channels_min = 2,
1505         .channels_max = 2,
1506         .nid = 0x14, /* NID to query formats and rates */
1507         .ops = {
1508                 .prepare = via_capture_pcm_prepare,
1509                 .cleanup = via_capture_pcm_cleanup
1510         },
1511 };
1512
1513 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
1514         .substreams = 1,
1515         .channels_min = 2,
1516         .channels_max = 2,
1517         /* NID is set in via_build_pcms */
1518         .ops = {
1519                 .open = via_dig_playback_pcm_open,
1520                 .close = via_dig_playback_pcm_close
1521         },
1522 };
1523
1524 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
1525         .substreams = 1,
1526         .channels_min = 2,
1527         .channels_max = 2,
1528 };
1529
1530 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
1531                                      const struct auto_pin_cfg *cfg)
1532 {
1533         int i;
1534         hda_nid_t nid;
1535
1536         if (cfg->line_outs == 4)  /* 10 channels */
1537                 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
1538         else if (cfg->line_outs == 3) /* 6 channels */
1539                 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
1540
1541         spec->multiout.dac_nids = spec->private_dac_nids;
1542
1543         if (cfg->line_outs == 4) { /* 10 channels */
1544                 for (i = 0; i < cfg->line_outs; i++) {
1545                         nid = cfg->line_out_pins[i];
1546                         if (nid) {
1547                                 /* config dac list */
1548                                 switch (i) {
1549                                 case AUTO_SEQ_FRONT:
1550                                         /* AOW0 */
1551                                         spec->multiout.dac_nids[i] = 0x10;
1552                                         break;
1553                                 case AUTO_SEQ_CENLFE:
1554                                         /* AOW2 */
1555                                         spec->multiout.dac_nids[i] = 0x12;
1556                                         break;
1557                                 case AUTO_SEQ_SURROUND:
1558                                         /* AOW3 */
1559                                         spec->multiout.dac_nids[i] = 0x11;
1560                                         break;
1561                                 case AUTO_SEQ_SIDE:
1562                                         /* AOW1 */
1563                                         spec->multiout.dac_nids[i] = 0x27;
1564                                         break;
1565                                 default:
1566                                         break;
1567                                 }
1568                         }
1569                 }
1570                 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1571
1572         } else if (cfg->line_outs == 3) { /* 6 channels */
1573                 for(i = 0; i < cfg->line_outs; i++) {
1574                         nid = cfg->line_out_pins[i];
1575                         if (nid) {
1576                                 /* config dac list */
1577                                 switch(i) {
1578                                 case AUTO_SEQ_FRONT:
1579                                         /* AOW0 */
1580                                         spec->multiout.dac_nids[i] = 0x10;
1581                                         break;
1582                                 case AUTO_SEQ_CENLFE:
1583                                         /* AOW2 */
1584                                         spec->multiout.dac_nids[i] = 0x12;
1585                                         break;
1586                                 case AUTO_SEQ_SURROUND:
1587                                         /* AOW1 */
1588                                         spec->multiout.dac_nids[i] = 0x11;
1589                                         break;
1590                                 default:
1591                                         break;
1592                                 }
1593                         }
1594                 }
1595         }
1596
1597         return 0;
1598 }
1599
1600 /* add playback controls from the parsed DAC table */
1601 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1602                                              const struct auto_pin_cfg *cfg)
1603 {
1604         char name[32];
1605         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1606         hda_nid_t nid = 0;
1607         int i, err;
1608
1609         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1610                 nid = cfg->line_out_pins[i];
1611
1612                 if (!nid)       
1613                         continue;
1614
1615                 if (i == AUTO_SEQ_CENLFE) {
1616                         /* Center/LFE */
1617                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1618                                               "Center Playback Volume",
1619                                               HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1620                                                                   HDA_OUTPUT));
1621                         if (err < 0)
1622                                 return err;
1623                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1624                                               "LFE Playback Volume",
1625                                               HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1626                                                                   HDA_OUTPUT));
1627                         if (err < 0)
1628                                 return err;
1629                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1630                                               "Center Playback Switch",
1631                                               HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1632                                                                   HDA_OUTPUT));
1633                         if (err < 0)
1634                                 return err;
1635                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1636                                               "LFE Playback Switch",
1637                                               HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1638                                                                   HDA_OUTPUT));
1639                         if (err < 0)
1640                                 return err;
1641                 } else if (i == AUTO_SEQ_FRONT){
1642                         /* add control to mixer index 0 */
1643                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1644                                               "Master Front Playback Volume",
1645                                               HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1646                                                                   HDA_INPUT));
1647                         if (err < 0)
1648                                 return err;
1649                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1650                                               "Master Front Playback Switch",
1651                                               HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1652                                                                   HDA_INPUT));
1653                         if (err < 0)
1654                                 return err;
1655                         
1656                         /* add control to PW3 */
1657                         sprintf(name, "%s Playback Volume", chname[i]);
1658                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1659                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1660                                                                   HDA_OUTPUT));
1661                         if (err < 0)
1662                                 return err;
1663                         sprintf(name, "%s Playback Switch", chname[i]);
1664                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1665                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1666                                                                   HDA_OUTPUT));
1667                         if (err < 0)
1668                                 return err;
1669                 } else if (i == AUTO_SEQ_SURROUND) {
1670                         sprintf(name, "%s Playback Volume", chname[i]);
1671                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1672                                               HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1673                                                                   HDA_OUTPUT));
1674                         if (err < 0)
1675                                 return err;
1676                         sprintf(name, "%s Playback Switch", chname[i]);
1677                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1678                                               HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1679                                                                   HDA_OUTPUT));
1680                         if (err < 0)
1681                                 return err;
1682                 } else if (i == AUTO_SEQ_SIDE) {
1683                         sprintf(name, "%s Playback Volume", chname[i]);
1684                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1685                                               HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1686                                                                   HDA_OUTPUT));
1687                         if (err < 0)
1688                                 return err;
1689                         sprintf(name, "%s Playback Switch", chname[i]);
1690                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1691                                               HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1692                                                                   HDA_OUTPUT));
1693                         if (err < 0)
1694                                 return err;
1695                 }
1696         }
1697
1698         return 0;
1699 }
1700
1701 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1702 {
1703         int err;
1704
1705         if (!pin)
1706                 return 0;
1707
1708         if (spec->multiout.num_dacs == 5) /* 10 channels */
1709                 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1710         else if (spec->multiout.num_dacs == 3) /* 6 channels */
1711                 spec->multiout.hp_nid = 0;
1712
1713         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1714                               "Headphone Playback Volume",
1715                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1716         if (err < 0)
1717                 return err;
1718         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1719                               "Headphone Playback Switch",
1720                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1721         if (err < 0)
1722                 return err;
1723
1724         return 0;
1725 }
1726
1727 /* create playback/capture controls for input pins */
1728 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1729                                                 const struct auto_pin_cfg *cfg)
1730 {
1731         static char *labels[] = {
1732                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1733         };
1734         struct hda_input_mux *imux = &spec->private_imux[0];
1735         int i, err, idx = 0;
1736
1737         /* for internal loopback recording select */
1738         imux->items[imux->num_items].label = "Stereo Mixer";
1739         imux->items[imux->num_items].index = idx;
1740         imux->num_items++;
1741
1742         for (i = 0; i < AUTO_PIN_LAST; i++) {
1743                 if (!cfg->input_pins[i])
1744                         continue;
1745
1746                 switch (cfg->input_pins[i]) {
1747                 case 0x1d: /* Mic */
1748                         idx = 2;
1749                         break;
1750                                 
1751                 case 0x1e: /* Line In */
1752                         idx = 3;
1753                         break;
1754
1755                 case 0x21: /* Front Mic */
1756                         idx = 4;
1757                         break;
1758
1759                 case 0x23: /* CD */
1760                         idx = 1;
1761                         break;
1762                 }
1763                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1764                                            idx, 0x18);
1765                 if (err < 0)
1766                         return err;
1767                 imux->items[imux->num_items].label = labels[i];
1768                 imux->items[imux->num_items].index = idx;
1769                 imux->num_items++;
1770         }
1771         return 0;
1772 }
1773
1774 static int vt1709_parse_auto_config(struct hda_codec *codec)
1775 {
1776         struct via_spec *spec = codec->spec;
1777         int err;
1778
1779         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1780         if (err < 0)
1781                 return err;
1782         err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
1783         if (err < 0)
1784                 return err;
1785         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1786                 return 0; /* can't find valid BIOS pin config */
1787
1788         err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
1789         if (err < 0)
1790                 return err;
1791         err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1792         if (err < 0)
1793                 return err;
1794         err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
1795         if (err < 0)
1796                 return err;
1797
1798         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1799
1800         if (spec->autocfg.dig_outs)
1801                 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
1802         if (spec->autocfg.dig_in_pin)
1803                 spec->dig_in_nid = VT1709_DIGIN_NID;
1804
1805         if (spec->kctls.list)
1806                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1807
1808         spec->input_mux = &spec->private_imux[0];
1809
1810         if (spec->hp_mux)
1811                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
1812
1813         return 1;
1814 }
1815
1816 #ifdef CONFIG_SND_HDA_POWER_SAVE
1817 static struct hda_amp_list vt1709_loopbacks[] = {
1818         { 0x18, HDA_INPUT, 1 },
1819         { 0x18, HDA_INPUT, 2 },
1820         { 0x18, HDA_INPUT, 3 },
1821         { 0x18, HDA_INPUT, 4 },
1822         { } /* end */
1823 };
1824 #endif
1825
1826 static int patch_vt1709_10ch(struct hda_codec *codec)
1827 {
1828         struct via_spec *spec;
1829         int err;
1830
1831         /* create a codec specific record */
1832         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1833         if (spec == NULL)
1834                 return -ENOMEM;
1835
1836         codec->spec = spec;
1837
1838         err = vt1709_parse_auto_config(codec);
1839         if (err < 0) {
1840                 via_free(codec);
1841                 return err;
1842         } else if (!err) {
1843                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1844                        "Using genenic mode...\n");
1845         }
1846
1847         spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
1848         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
1849
1850         spec->stream_name_analog = "VT1709 Analog";
1851         spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
1852         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1853
1854         spec->stream_name_digital = "VT1709 Digital";
1855         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1856         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1857
1858         
1859         if (!spec->adc_nids && spec->input_mux) {
1860                 spec->adc_nids = vt1709_adc_nids;
1861                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1862                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1863                 spec->num_mixers++;
1864         }
1865
1866         codec->patch_ops = via_patch_ops;
1867
1868         codec->patch_ops.init = via_auto_init;
1869         codec->patch_ops.unsol_event = via_unsol_event;
1870 #ifdef CONFIG_SND_HDA_POWER_SAVE
1871         spec->loopback.amplist = vt1709_loopbacks;
1872 #endif
1873
1874         return 0;
1875 }
1876 /*
1877  * generic initialization of ADC, input mixers and output mixers
1878  */
1879 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
1880         /*
1881          * Unmute ADC0-2 and set the default input to mic-in
1882          */
1883         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1884         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1885         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1886
1887
1888         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1889          * mixer widget
1890          */
1891         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1892         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1893         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1894         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1895         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1896         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1897
1898         /*
1899          * Set up output selector (0x1a, 0x1b, 0x29)
1900          */
1901         /* set vol=0 to output mixers */
1902         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1903         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1904         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1905
1906         /*
1907          *  Unmute PW3 and PW4
1908          */
1909         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1910         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1911
1912         /* Set input of PW4 as MW0 */
1913         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1914         /* PW9 Output enable */
1915         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1916         { }
1917 };
1918
1919 static int patch_vt1709_6ch(struct hda_codec *codec)
1920 {
1921         struct via_spec *spec;
1922         int err;
1923
1924         /* create a codec specific record */
1925         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1926         if (spec == NULL)
1927                 return -ENOMEM;
1928
1929         codec->spec = spec;
1930
1931         err = vt1709_parse_auto_config(codec);
1932         if (err < 0) {
1933                 via_free(codec);
1934                 return err;
1935         } else if (!err) {
1936                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1937                        "Using genenic mode...\n");
1938         }
1939
1940         spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
1941         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
1942
1943         spec->stream_name_analog = "VT1709 Analog";
1944         spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
1945         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1946
1947         spec->stream_name_digital = "VT1709 Digital";
1948         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1949         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1950
1951         
1952         if (!spec->adc_nids && spec->input_mux) {
1953                 spec->adc_nids = vt1709_adc_nids;
1954                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1955                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1956                 spec->num_mixers++;
1957         }
1958
1959         codec->patch_ops = via_patch_ops;
1960
1961         codec->patch_ops.init = via_auto_init;
1962         codec->patch_ops.unsol_event = via_unsol_event;
1963 #ifdef CONFIG_SND_HDA_POWER_SAVE
1964         spec->loopback.amplist = vt1709_loopbacks;
1965 #endif
1966         return 0;
1967 }
1968
1969 /* capture mixer elements */
1970 static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
1971         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
1972         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
1973         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
1974         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
1975         {
1976                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1977                 /* The multiple "Capture Source" controls confuse alsamixer
1978                  * So call somewhat different..
1979                  */
1980                 /* .name = "Capture Source", */
1981                 .name = "Input Source",
1982                 .count = 1,
1983                 .info = via_mux_enum_info,
1984                 .get = via_mux_enum_get,
1985                 .put = via_mux_enum_put,
1986         },
1987         { } /* end */
1988 };
1989 /*
1990  * generic initialization of ADC, input mixers and output mixers
1991  */
1992 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
1993         /*
1994          * Unmute ADC0-1 and set the default input to mic-in
1995          */
1996         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1997         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1998
1999
2000         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2001          * mixer widget
2002          */
2003         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2004         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2005         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2006         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2007         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2008         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2009
2010         /*
2011          * Set up output mixers
2012          */
2013         /* set vol=0 to output mixers */
2014         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2015         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2016         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2017
2018         /* Setup default input to PW4 */
2019         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1},
2020         /* PW9 Output enable */
2021         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2022         /* PW10 Input enable */
2023         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2024         { }
2025 };
2026
2027 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
2028         /*
2029          * Unmute ADC0-1 and set the default input to mic-in
2030          */
2031         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2032         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2033
2034
2035         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2036          * mixer widget
2037          */
2038         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2039         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2040         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2041         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2042         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2043         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2044
2045         /*
2046          * Set up output mixers
2047          */
2048         /* set vol=0 to output mixers */
2049         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2050         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2051         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2052
2053         /* Setup default input of PW4 to MW0 */
2054         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2055         /* PW9 Output enable */
2056         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2057         /* PW10 Input enable */
2058         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2059         { }
2060 };
2061
2062 static struct hda_verb vt1708B_uniwill_init_verbs[] = {
2063         {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2064         { }
2065 };
2066
2067 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
2068         .substreams = 2,
2069         .channels_min = 2,
2070         .channels_max = 8,
2071         .nid = 0x10, /* NID to query formats and rates */
2072         .ops = {
2073                 .open = via_playback_pcm_open,
2074                 .prepare = via_playback_multi_pcm_prepare,
2075                 .cleanup = via_playback_multi_pcm_cleanup
2076         },
2077 };
2078
2079 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
2080         .substreams = 2,
2081         .channels_min = 2,
2082         .channels_max = 4,
2083         .nid = 0x10, /* NID to query formats and rates */
2084         .ops = {
2085                 .open = via_playback_pcm_open,
2086                 .prepare = via_playback_multi_pcm_prepare,
2087                 .cleanup = via_playback_multi_pcm_cleanup
2088         },
2089 };
2090
2091 static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
2092         .substreams = 2,
2093         .channels_min = 2,
2094         .channels_max = 2,
2095         .nid = 0x13, /* NID to query formats and rates */
2096         .ops = {
2097                 .prepare = via_capture_pcm_prepare,
2098                 .cleanup = via_capture_pcm_cleanup
2099         },
2100 };
2101
2102 static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
2103         .substreams = 1,
2104         .channels_min = 2,
2105         .channels_max = 2,
2106         /* NID is set in via_build_pcms */
2107         .ops = {
2108                 .open = via_dig_playback_pcm_open,
2109                 .close = via_dig_playback_pcm_close,
2110                 .prepare = via_dig_playback_pcm_prepare,
2111                 .cleanup = via_dig_playback_pcm_cleanup
2112         },
2113 };
2114
2115 static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
2116         .substreams = 1,
2117         .channels_min = 2,
2118         .channels_max = 2,
2119 };
2120
2121 /* fill in the dac_nids table from the parsed pin configuration */
2122 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
2123                                      const struct auto_pin_cfg *cfg)
2124 {
2125         int i;
2126         hda_nid_t nid;
2127
2128         spec->multiout.num_dacs = cfg->line_outs;
2129
2130         spec->multiout.dac_nids = spec->private_dac_nids;
2131
2132         for (i = 0; i < 4; i++) {
2133                 nid = cfg->line_out_pins[i];
2134                 if (nid) {
2135                         /* config dac list */
2136                         switch (i) {
2137                         case AUTO_SEQ_FRONT:
2138                                 spec->multiout.dac_nids[i] = 0x10;
2139                                 break;
2140                         case AUTO_SEQ_CENLFE:
2141                                 spec->multiout.dac_nids[i] = 0x24;
2142                                 break;
2143                         case AUTO_SEQ_SURROUND:
2144                                 spec->multiout.dac_nids[i] = 0x11;
2145                                 break;
2146                         case AUTO_SEQ_SIDE:
2147                                 spec->multiout.dac_nids[i] = 0x25;
2148                                 break;
2149                         }
2150                 }
2151         }
2152
2153         return 0;
2154 }
2155
2156 /* add playback controls from the parsed DAC table */
2157 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
2158                                              const struct auto_pin_cfg *cfg)
2159 {
2160         char name[32];
2161         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2162         hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
2163         hda_nid_t nid, nid_vol = 0;
2164         int i, err;
2165
2166         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2167                 nid = cfg->line_out_pins[i];
2168
2169                 if (!nid)
2170                         continue;
2171
2172                 nid_vol = nid_vols[i];
2173
2174                 if (i == AUTO_SEQ_CENLFE) {
2175                         /* Center/LFE */
2176                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2177                                               "Center Playback Volume",
2178                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2179                                                                   HDA_OUTPUT));
2180                         if (err < 0)
2181                                 return err;
2182                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2183                                               "LFE Playback Volume",
2184                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2185                                                                   HDA_OUTPUT));
2186                         if (err < 0)
2187                                 return err;
2188                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2189                                               "Center Playback Switch",
2190                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2191                                                                   HDA_OUTPUT));
2192                         if (err < 0)
2193                                 return err;
2194                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2195                                               "LFE Playback Switch",
2196                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2197                                                                   HDA_OUTPUT));
2198                         if (err < 0)
2199                                 return err;
2200                 } else if (i == AUTO_SEQ_FRONT) {
2201                         /* add control to mixer index 0 */
2202                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2203                                               "Master Front Playback Volume",
2204                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2205                                                                   HDA_INPUT));
2206                         if (err < 0)
2207                                 return err;
2208                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2209                                               "Master Front Playback Switch",
2210                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2211                                                                   HDA_INPUT));
2212                         if (err < 0)
2213                                 return err;
2214
2215                         /* add control to PW3 */
2216                         sprintf(name, "%s Playback Volume", chname[i]);
2217                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2218                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2219                                                                   HDA_OUTPUT));
2220                         if (err < 0)
2221                                 return err;
2222                         sprintf(name, "%s Playback Switch", chname[i]);
2223                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2224                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2225                                                                   HDA_OUTPUT));
2226                         if (err < 0)
2227                                 return err;
2228                 } else {
2229                         sprintf(name, "%s Playback Volume", chname[i]);
2230                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2231                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2232                                                                   HDA_OUTPUT));
2233                         if (err < 0)
2234                                 return err;
2235                         sprintf(name, "%s Playback Switch", chname[i]);
2236                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2237                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2238                                                                   HDA_OUTPUT));
2239                         if (err < 0)
2240                                 return err;
2241                 }
2242         }
2243
2244         return 0;
2245 }
2246
2247 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2248 {
2249         int err;
2250
2251         if (!pin)
2252                 return 0;
2253
2254         spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
2255
2256         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2257                               "Headphone Playback Volume",
2258                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2259         if (err < 0)
2260                 return err;
2261         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2262                               "Headphone Playback Switch",
2263                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2264         if (err < 0)
2265                 return err;
2266
2267         create_hp_imux(spec);
2268
2269         return 0;
2270 }
2271
2272 /* create playback/capture controls for input pins */
2273 static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
2274                                                 const struct auto_pin_cfg *cfg)
2275 {
2276         static char *labels[] = {
2277                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2278         };
2279         struct hda_input_mux *imux = &spec->private_imux[0];
2280         int i, err, idx = 0;
2281
2282         /* for internal loopback recording select */
2283         imux->items[imux->num_items].label = "Stereo Mixer";
2284         imux->items[imux->num_items].index = idx;
2285         imux->num_items++;
2286
2287         for (i = 0; i < AUTO_PIN_LAST; i++) {
2288                 if (!cfg->input_pins[i])
2289                         continue;
2290
2291                 switch (cfg->input_pins[i]) {
2292                 case 0x1a: /* Mic */
2293                         idx = 2;
2294                         break;
2295
2296                 case 0x1b: /* Line In */
2297                         idx = 3;
2298                         break;
2299
2300                 case 0x1e: /* Front Mic */
2301                         idx = 4;
2302                         break;
2303
2304                 case 0x1f: /* CD */
2305                         idx = 1;
2306                         break;
2307                 }
2308                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
2309                                            idx, 0x16);
2310                 if (err < 0)
2311                         return err;
2312                 imux->items[imux->num_items].label = labels[i];
2313                 imux->items[imux->num_items].index = idx;
2314                 imux->num_items++;
2315         }
2316         return 0;
2317 }
2318
2319 static int vt1708B_parse_auto_config(struct hda_codec *codec)
2320 {
2321         struct via_spec *spec = codec->spec;
2322         int err;
2323
2324         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2325         if (err < 0)
2326                 return err;
2327         err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
2328         if (err < 0)
2329                 return err;
2330         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2331                 return 0; /* can't find valid BIOS pin config */
2332
2333         err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
2334         if (err < 0)
2335                 return err;
2336         err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2337         if (err < 0)
2338                 return err;
2339         err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
2340         if (err < 0)
2341                 return err;
2342
2343         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2344
2345         if (spec->autocfg.dig_outs)
2346                 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
2347         if (spec->autocfg.dig_in_pin)
2348                 spec->dig_in_nid = VT1708B_DIGIN_NID;
2349
2350         if (spec->kctls.list)
2351                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2352
2353         spec->input_mux = &spec->private_imux[0];
2354
2355         if (spec->hp_mux)
2356                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2357
2358         return 1;
2359 }
2360
2361 #ifdef CONFIG_SND_HDA_POWER_SAVE
2362 static struct hda_amp_list vt1708B_loopbacks[] = {
2363         { 0x16, HDA_INPUT, 1 },
2364         { 0x16, HDA_INPUT, 2 },
2365         { 0x16, HDA_INPUT, 3 },
2366         { 0x16, HDA_INPUT, 4 },
2367         { } /* end */
2368 };
2369 #endif
2370
2371 static int patch_vt1708B_8ch(struct hda_codec *codec)
2372 {
2373         struct via_spec *spec;
2374         int err;
2375
2376         /* create a codec specific record */
2377         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2378         if (spec == NULL)
2379                 return -ENOMEM;
2380
2381         codec->spec = spec;
2382
2383         /* automatic parse from the BIOS config */
2384         err = vt1708B_parse_auto_config(codec);
2385         if (err < 0) {
2386                 via_free(codec);
2387                 return err;
2388         } else if (!err) {
2389                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2390                        "from BIOS.  Using genenic mode...\n");
2391         }
2392
2393         spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
2394         spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
2395
2396         spec->stream_name_analog = "VT1708B Analog";
2397         spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
2398         spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
2399
2400         spec->stream_name_digital = "VT1708B Digital";
2401         spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
2402         spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
2403
2404         if (!spec->adc_nids && spec->input_mux) {
2405                 spec->adc_nids = vt1708B_adc_nids;
2406                 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
2407                 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
2408                 spec->num_mixers++;
2409         }
2410
2411         codec->patch_ops = via_patch_ops;
2412
2413         codec->patch_ops.init = via_auto_init;
2414         codec->patch_ops.unsol_event = via_unsol_event;
2415 #ifdef CONFIG_SND_HDA_POWER_SAVE
2416         spec->loopback.amplist = vt1708B_loopbacks;
2417 #endif
2418
2419         return 0;
2420 }
2421
2422 static int patch_vt1708B_4ch(struct hda_codec *codec)
2423 {
2424         struct via_spec *spec;
2425         int err;
2426
2427         /* create a codec specific record */
2428         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2429         if (spec == NULL)
2430                 return -ENOMEM;
2431
2432         codec->spec = spec;
2433
2434         /* automatic parse from the BIOS config */
2435         err = vt1708B_parse_auto_config(codec);
2436         if (err < 0) {
2437                 via_free(codec);
2438                 return err;
2439         } else if (!err) {
2440                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2441                        "from BIOS.  Using genenic mode...\n");
2442         }
2443
2444         spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
2445         spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
2446
2447         spec->stream_name_analog = "VT1708B Analog";
2448         spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
2449         spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
2450
2451         spec->stream_name_digital = "VT1708B Digital";
2452         spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
2453         spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
2454
2455         if (!spec->adc_nids && spec->input_mux) {
2456                 spec->adc_nids = vt1708B_adc_nids;
2457                 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
2458                 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
2459                 spec->num_mixers++;
2460         }
2461
2462         codec->patch_ops = via_patch_ops;
2463
2464         codec->patch_ops.init = via_auto_init;
2465         codec->patch_ops.unsol_event = via_unsol_event;
2466 #ifdef CONFIG_SND_HDA_POWER_SAVE
2467         spec->loopback.amplist = vt1708B_loopbacks;
2468 #endif
2469
2470         return 0;
2471 }
2472
2473 /* Patch for VT1708S */
2474
2475 /* VT1708S software backdoor based override for buggy hardware micboost
2476  * setting */
2477 #define MIC_BOOST_VOLUME(xname, nid) {                          \
2478         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
2479         .name = xname,                                  \
2480         .index = 0,                                     \
2481         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |     \
2482         SNDRV_CTL_ELEM_ACCESS_TLV_READ |                \
2483         SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,             \
2484         .info = mic_boost_volume_info,                  \
2485         .get = snd_hda_mixer_amp_volume_get,            \
2486         .put = snd_hda_mixer_amp_volume_put,            \
2487         .tlv = { .c = mic_boost_tlv },                  \
2488         .private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT) }
2489
2490 /* capture mixer elements */
2491 static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
2492         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2493         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2494         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2495         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2496         MIC_BOOST_VOLUME("Mic Boost Capture Volume", 0x1A),
2497         MIC_BOOST_VOLUME("Front Mic Boost Capture Volume", 0x1E),
2498         {
2499                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2500                 /* The multiple "Capture Source" controls confuse alsamixer
2501                  * So call somewhat different..
2502                  */
2503                 /* .name = "Capture Source", */
2504                 .name = "Input Source",
2505                 .count = 1,
2506                 .info = via_mux_enum_info,
2507                 .get = via_mux_enum_get,
2508                 .put = via_mux_enum_put,
2509         },
2510         { } /* end */
2511 };
2512
2513 static struct hda_verb vt1708S_volume_init_verbs[] = {
2514         /* Unmute ADC0-1 and set the default input to mic-in */
2515         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2516         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2517
2518         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
2519          * analog-loopback mixer widget */
2520         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2521         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2522         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2523         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2524         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2525         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2526
2527         /* Setup default input of PW4 to MW0 */
2528         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2529         /* PW9, PW10  Output enable */
2530         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2531         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2532         /* Enable Mic Boost Volume backdoor */
2533         {0x1, 0xf98, 0x1},
2534         { }
2535 };
2536
2537 static struct hda_verb vt1708S_uniwill_init_verbs[] = {
2538         {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2539         { }
2540 };
2541
2542 static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
2543         .substreams = 2,
2544         .channels_min = 2,
2545         .channels_max = 8,
2546         .nid = 0x10, /* NID to query formats and rates */
2547         .ops = {
2548                 .open = via_playback_pcm_open,
2549                 .prepare = via_playback_pcm_prepare,
2550                 .cleanup = via_playback_pcm_cleanup
2551         },
2552 };
2553
2554 static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
2555         .substreams = 2,
2556         .channels_min = 2,
2557         .channels_max = 2,
2558         .nid = 0x13, /* NID to query formats and rates */
2559         .ops = {
2560                 .prepare = via_capture_pcm_prepare,
2561                 .cleanup = via_capture_pcm_cleanup
2562         },
2563 };
2564
2565 static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
2566         .substreams = 1,
2567         .channels_min = 2,
2568         .channels_max = 2,
2569         /* NID is set in via_build_pcms */
2570         .ops = {
2571                 .open = via_dig_playback_pcm_open,
2572                 .close = via_dig_playback_pcm_close,
2573                 .prepare = via_dig_playback_pcm_prepare,
2574                 .cleanup = via_dig_playback_pcm_cleanup
2575         },
2576 };
2577
2578 /* fill in the dac_nids table from the parsed pin configuration */
2579 static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
2580                                      const struct auto_pin_cfg *cfg)
2581 {
2582         int i;
2583         hda_nid_t nid;
2584
2585         spec->multiout.num_dacs = cfg->line_outs;
2586
2587         spec->multiout.dac_nids = spec->private_dac_nids;
2588
2589         for (i = 0; i < 4; i++) {
2590                 nid = cfg->line_out_pins[i];
2591                 if (nid) {
2592                         /* config dac list */
2593                         switch (i) {
2594                         case AUTO_SEQ_FRONT:
2595                                 spec->multiout.dac_nids[i] = 0x10;
2596                                 break;
2597                         case AUTO_SEQ_CENLFE:
2598                                 spec->multiout.dac_nids[i] = 0x24;
2599                                 break;
2600                         case AUTO_SEQ_SURROUND:
2601                                 spec->multiout.dac_nids[i] = 0x11;
2602                                 break;
2603                         case AUTO_SEQ_SIDE:
2604                                 spec->multiout.dac_nids[i] = 0x25;
2605                                 break;
2606                         }
2607                 }
2608         }
2609
2610         return 0;
2611 }
2612
2613 /* add playback controls from the parsed DAC table */
2614 static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
2615                                              const struct auto_pin_cfg *cfg)
2616 {
2617         char name[32];
2618         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2619         hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
2620         hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
2621         hda_nid_t nid, nid_vol, nid_mute;
2622         int i, err;
2623
2624         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2625                 nid = cfg->line_out_pins[i];
2626
2627                 if (!nid)
2628                         continue;
2629
2630                 nid_vol = nid_vols[i];
2631                 nid_mute = nid_mutes[i];
2632
2633                 if (i == AUTO_SEQ_CENLFE) {
2634                         /* Center/LFE */
2635                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2636                                               "Center Playback Volume",
2637                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2638                                                                   HDA_OUTPUT));
2639                         if (err < 0)
2640                                 return err;
2641                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2642                                               "LFE Playback Volume",
2643                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2644                                                                   HDA_OUTPUT));
2645                         if (err < 0)
2646                                 return err;
2647                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2648                                               "Center Playback Switch",
2649                                               HDA_COMPOSE_AMP_VAL(nid_mute,
2650                                                                   1, 0,
2651                                                                   HDA_OUTPUT));
2652                         if (err < 0)
2653                                 return err;
2654                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2655                                               "LFE Playback Switch",
2656                                               HDA_COMPOSE_AMP_VAL(nid_mute,
2657                                                                   2, 0,
2658                                                                   HDA_OUTPUT));
2659                         if (err < 0)
2660                                 return err;
2661                 } else if (i == AUTO_SEQ_FRONT) {
2662                         /* add control to mixer index 0 */
2663                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2664                                               "Master Front Playback Volume",
2665                                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
2666                                                                   HDA_INPUT));
2667                         if (err < 0)
2668                                 return err;
2669                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2670                                               "Master Front Playback Switch",
2671                                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
2672                                                                   HDA_INPUT));
2673                         if (err < 0)
2674                                 return err;
2675
2676                         /* Front */
2677                         sprintf(name, "%s Playback Volume", chname[i]);
2678                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2679                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2680                                                                   HDA_OUTPUT));
2681                         if (err < 0)
2682                                 return err;
2683                         sprintf(name, "%s Playback Switch", chname[i]);
2684                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2685                                               HDA_COMPOSE_AMP_VAL(nid_mute,
2686                                                                   3, 0,
2687                                                                   HDA_OUTPUT));
2688                         if (err < 0)
2689                                 return err;
2690                 } else {
2691                         sprintf(name, "%s Playback Volume", chname[i]);
2692                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2693                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2694                                                                   HDA_OUTPUT));
2695                         if (err < 0)
2696                                 return err;
2697                         sprintf(name, "%s Playback Switch", chname[i]);
2698                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2699                                               HDA_COMPOSE_AMP_VAL(nid_mute,
2700                                                                   3, 0,
2701                                                                   HDA_OUTPUT));
2702                         if (err < 0)
2703                                 return err;
2704                 }
2705         }
2706
2707         return 0;
2708 }
2709
2710 static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2711 {
2712         int err;
2713
2714         if (!pin)
2715                 return 0;
2716
2717         spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
2718
2719         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2720                               "Headphone Playback Volume",
2721                               HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
2722         if (err < 0)
2723                 return err;
2724
2725         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2726                               "Headphone Playback Switch",
2727                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2728         if (err < 0)
2729                 return err;
2730
2731         create_hp_imux(spec);
2732
2733         return 0;
2734 }
2735
2736 /* create playback/capture controls for input pins */
2737 static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
2738                                                 const struct auto_pin_cfg *cfg)
2739 {
2740         static char *labels[] = {
2741                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2742         };
2743         struct hda_input_mux *imux = &spec->private_imux[0];
2744         int i, err, idx = 0;
2745
2746         /* for internal loopback recording select */
2747         imux->items[imux->num_items].label = "Stereo Mixer";
2748         imux->items[imux->num_items].index = 5;
2749         imux->num_items++;
2750
2751         for (i = 0; i < AUTO_PIN_LAST; i++) {
2752                 if (!cfg->input_pins[i])
2753                         continue;
2754
2755                 switch (cfg->input_pins[i]) {
2756                 case 0x1a: /* Mic */
2757                         idx = 2;
2758                         break;
2759
2760                 case 0x1b: /* Line In */
2761                         idx = 3;
2762                         break;
2763
2764                 case 0x1e: /* Front Mic */
2765                         idx = 4;
2766                         break;
2767
2768                 case 0x1f: /* CD */
2769                         idx = 1;
2770                         break;
2771                 }
2772                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
2773                                            idx, 0x16);
2774                 if (err < 0)
2775                         return err;
2776                 imux->items[imux->num_items].label = labels[i];
2777                 imux->items[imux->num_items].index = idx-1;
2778                 imux->num_items++;
2779         }
2780         return 0;
2781 }
2782
2783 /* fill out digital output widgets; one for master and one for slave outputs */
2784 static void fill_dig_outs(struct hda_codec *codec)
2785 {
2786         struct via_spec *spec = codec->spec;
2787         int i;
2788
2789         for (i = 0; i < spec->autocfg.dig_outs; i++) {
2790                 hda_nid_t nid;
2791                 int conn;
2792
2793                 nid = spec->autocfg.dig_out_pins[i];
2794                 if (!nid)
2795                         continue;
2796                 conn = snd_hda_get_connections(codec, nid, &nid, 1);
2797                 if (conn < 1)
2798                         continue;
2799                 if (!spec->multiout.dig_out_nid)
2800                         spec->multiout.dig_out_nid = nid;
2801                 else {
2802                         spec->slave_dig_outs[0] = nid;
2803                         break; /* at most two dig outs */
2804                 }
2805         }
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
2813         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2814         if (err < 0)
2815                 return err;
2816         err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
2817         if (err < 0)
2818                 return err;
2819         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2820                 return 0; /* can't find valid BIOS pin config */
2821
2822         err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
2823         if (err < 0)
2824                 return err;
2825         err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2826         if (err < 0)
2827                 return err;
2828         err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg);
2829         if (err < 0)
2830                 return err;
2831
2832         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2833
2834         fill_dig_outs(codec);
2835
2836         if (spec->kctls.list)
2837                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2838
2839         spec->input_mux = &spec->private_imux[0];
2840
2841         if (spec->hp_mux)
2842                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2843
2844         return 1;
2845 }
2846
2847 #ifdef CONFIG_SND_HDA_POWER_SAVE
2848 static struct hda_amp_list vt1708S_loopbacks[] = {
2849         { 0x16, HDA_INPUT, 1 },
2850         { 0x16, HDA_INPUT, 2 },
2851         { 0x16, HDA_INPUT, 3 },
2852         { 0x16, HDA_INPUT, 4 },
2853         { } /* end */
2854 };
2855 #endif
2856
2857 static int patch_vt1708S(struct hda_codec *codec)
2858 {
2859         struct via_spec *spec;
2860         int err;
2861
2862         /* create a codec specific record */
2863         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2864         if (spec == NULL)
2865                 return -ENOMEM;
2866
2867         codec->spec = spec;
2868
2869         /* automatic parse from the BIOS config */
2870         err = vt1708S_parse_auto_config(codec);
2871         if (err < 0) {
2872                 via_free(codec);
2873                 return err;
2874         } else if (!err) {
2875                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2876                        "from BIOS.  Using genenic mode...\n");
2877         }
2878
2879         spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
2880         spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
2881
2882         spec->stream_name_analog = "VT1708S Analog";
2883         spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
2884         spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
2885
2886         spec->stream_name_digital = "VT1708S Digital";
2887         spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
2888
2889         if (!spec->adc_nids && spec->input_mux) {
2890                 spec->adc_nids = vt1708S_adc_nids;
2891                 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
2892                 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
2893                 spec->num_mixers++;
2894         }
2895
2896         codec->patch_ops = via_patch_ops;
2897
2898         codec->patch_ops.init = via_auto_init;
2899         codec->patch_ops.unsol_event = via_unsol_event;
2900 #ifdef CONFIG_SND_HDA_POWER_SAVE
2901         spec->loopback.amplist = vt1708S_loopbacks;
2902 #endif
2903
2904         return 0;
2905 }
2906
2907 /* Patch for VT1702 */
2908
2909 /* capture mixer elements */
2910 static struct snd_kcontrol_new vt1702_capture_mixer[] = {
2911         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
2912         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
2913         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
2914         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
2915         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
2916         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
2917         HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
2918                          HDA_INPUT),
2919         {
2920                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2921                 /* The multiple "Capture Source" controls confuse alsamixer
2922                  * So call somewhat different..
2923                  */
2924                 /* .name = "Capture Source", */
2925                 .name = "Input Source",
2926                 .count = 1,
2927                 .info = via_mux_enum_info,
2928                 .get = via_mux_enum_get,
2929                 .put = via_mux_enum_put,
2930         },
2931         { } /* end */
2932 };
2933
2934 static struct hda_verb vt1702_volume_init_verbs[] = {
2935         /*
2936          * Unmute ADC0-1 and set the default input to mic-in
2937          */
2938         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2939         {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2940         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2941
2942
2943         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2944          * mixer widget
2945          */
2946         /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
2947         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2948         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2949         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2950         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2951         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2952
2953         /* Setup default input of PW4 to MW0 */
2954         {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
2955         /* PW6 PW7 Output enable */
2956         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2957         {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2958         { }
2959 };
2960
2961 static struct hda_verb vt1702_uniwill_init_verbs[] = {
2962         {0x01, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_GPIO_EVENT},
2963         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2964         { }
2965 };
2966
2967 static struct hda_pcm_stream vt1702_pcm_analog_playback = {
2968         .substreams = 2,
2969         .channels_min = 2,
2970         .channels_max = 2,
2971         .nid = 0x10, /* NID to query formats and rates */
2972         .ops = {
2973                 .open = via_playback_pcm_open,
2974                 .prepare = via_playback_multi_pcm_prepare,
2975                 .cleanup = via_playback_multi_pcm_cleanup
2976         },
2977 };
2978
2979 static struct hda_pcm_stream vt1702_pcm_analog_capture = {
2980         .substreams = 3,
2981         .channels_min = 2,
2982         .channels_max = 2,
2983         .nid = 0x12, /* NID to query formats and rates */
2984         .ops = {
2985                 .prepare = via_capture_pcm_prepare,
2986                 .cleanup = via_capture_pcm_cleanup
2987         },
2988 };
2989
2990 static struct hda_pcm_stream vt1702_pcm_digital_playback = {
2991         .substreams = 2,
2992         .channels_min = 2,
2993         .channels_max = 2,
2994         /* NID is set in via_build_pcms */
2995         .ops = {
2996                 .open = via_dig_playback_pcm_open,
2997                 .close = via_dig_playback_pcm_close,
2998                 .prepare = via_dig_playback_pcm_prepare,
2999                 .cleanup = via_dig_playback_pcm_cleanup
3000         },
3001 };
3002
3003 /* fill in the dac_nids table from the parsed pin configuration */
3004 static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
3005                                      const struct auto_pin_cfg *cfg)
3006 {
3007         spec->multiout.num_dacs = 1;
3008         spec->multiout.dac_nids = spec->private_dac_nids;
3009
3010         if (cfg->line_out_pins[0]) {
3011                 /* config dac list */
3012                 spec->multiout.dac_nids[0] = 0x10;
3013         }
3014
3015         return 0;
3016 }
3017
3018 /* add playback controls from the parsed DAC table */
3019 static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
3020                                              const struct auto_pin_cfg *cfg)
3021 {
3022         int err;
3023
3024         if (!cfg->line_out_pins[0])
3025                 return -1;
3026
3027         /* add control to mixer index 0 */
3028         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3029                               "Master Front Playback Volume",
3030                               HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
3031         if (err < 0)
3032                 return err;
3033         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3034                               "Master Front Playback Switch",
3035                               HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
3036         if (err < 0)
3037                 return err;
3038
3039         /* Front */
3040         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3041                               "Front Playback Volume",
3042                               HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
3043         if (err < 0)
3044                 return err;
3045         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3046                               "Front Playback Switch",
3047                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
3048         if (err < 0)
3049                 return err;
3050
3051         return 0;
3052 }
3053
3054 static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3055 {
3056         int err;
3057
3058         if (!pin)
3059                 return 0;
3060
3061         spec->multiout.hp_nid = 0x1D;
3062
3063         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3064                               "Headphone Playback Volume",
3065                               HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
3066         if (err < 0)
3067                 return err;
3068
3069         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3070                               "Headphone Playback Switch",
3071                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3072         if (err < 0)
3073                 return err;
3074
3075         create_hp_imux(spec);
3076
3077         return 0;
3078 }
3079
3080 /* create playback/capture controls for input pins */
3081 static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
3082                                                 const struct auto_pin_cfg *cfg)
3083 {
3084         static char *labels[] = {
3085                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
3086         };
3087         struct hda_input_mux *imux = &spec->private_imux[0];
3088         int i, err, idx = 0;
3089
3090         /* for internal loopback recording select */
3091         imux->items[imux->num_items].label = "Stereo Mixer";
3092         imux->items[imux->num_items].index = 3;
3093         imux->num_items++;
3094
3095         for (i = 0; i < AUTO_PIN_LAST; i++) {
3096                 if (!cfg->input_pins[i])
3097                         continue;
3098
3099                 switch (cfg->input_pins[i]) {
3100                 case 0x14: /* Mic */
3101                         idx = 1;
3102                         break;
3103
3104                 case 0x15: /* Line In */
3105                         idx = 2;
3106                         break;
3107
3108                 case 0x18: /* Front Mic */
3109                         idx = 3;
3110                         break;
3111                 }
3112                 err = via_new_analog_input(spec, cfg->input_pins[i],
3113                                            labels[i], idx, 0x1A);
3114                 if (err < 0)
3115                         return err;
3116                 imux->items[imux->num_items].label = labels[i];
3117                 imux->items[imux->num_items].index = idx-1;
3118                 imux->num_items++;
3119         }
3120         return 0;
3121 }
3122
3123 static int vt1702_parse_auto_config(struct hda_codec *codec)
3124 {
3125         struct via_spec *spec = codec->spec;
3126         int err;
3127
3128         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3129         if (err < 0)
3130                 return err;
3131         err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
3132         if (err < 0)
3133                 return err;
3134         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3135                 return 0; /* can't find valid BIOS pin config */
3136
3137         err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
3138         if (err < 0)
3139                 return err;
3140         err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3141         if (err < 0)
3142                 return err;
3143         err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
3144         if (err < 0)
3145                 return err;
3146
3147         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3148
3149         fill_dig_outs(codec);
3150
3151         if (spec->kctls.list)
3152                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3153
3154         spec->input_mux = &spec->private_imux[0];
3155
3156         if (spec->hp_mux)
3157                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
3158
3159         return 1;
3160 }
3161
3162 #ifdef CONFIG_SND_HDA_POWER_SAVE
3163 static struct hda_amp_list vt1702_loopbacks[] = {
3164         { 0x1A, HDA_INPUT, 1 },
3165         { 0x1A, HDA_INPUT, 2 },
3166         { 0x1A, HDA_INPUT, 3 },
3167         { 0x1A, HDA_INPUT, 4 },
3168         { } /* end */
3169 };
3170 #endif
3171
3172 static int patch_vt1702(struct hda_codec *codec)
3173 {
3174         struct via_spec *spec;
3175         int err;
3176         unsigned int response;
3177         unsigned char control;
3178
3179         /* create a codec specific record */
3180         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3181         if (spec == NULL)
3182                 return -ENOMEM;
3183
3184         codec->spec = spec;
3185
3186         /* automatic parse from the BIOS config */
3187         err = vt1702_parse_auto_config(codec);
3188         if (err < 0) {
3189                 via_free(codec);
3190                 return err;
3191         } else if (!err) {
3192                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3193                        "from BIOS.  Using genenic mode...\n");
3194         }
3195
3196         spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
3197         spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
3198
3199         spec->stream_name_analog = "VT1702 Analog";
3200         spec->stream_analog_playback = &vt1702_pcm_analog_playback;
3201         spec->stream_analog_capture = &vt1702_pcm_analog_capture;
3202
3203         spec->stream_name_digital = "VT1702 Digital";
3204         spec->stream_digital_playback = &vt1702_pcm_digital_playback;
3205
3206         if (!spec->adc_nids && spec->input_mux) {
3207                 spec->adc_nids = vt1702_adc_nids;
3208                 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
3209                 spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
3210                 spec->num_mixers++;
3211         }
3212
3213         codec->patch_ops = via_patch_ops;
3214
3215         codec->patch_ops.init = via_auto_init;
3216         codec->patch_ops.unsol_event = via_unsol_event;
3217 #ifdef CONFIG_SND_HDA_POWER_SAVE
3218         spec->loopback.amplist = vt1702_loopbacks;
3219 #endif
3220
3221         /* Open backdoor */
3222         response = snd_hda_codec_read(codec, codec->afg, 0, 0xF8C, 0);
3223         control = (unsigned char)(response & 0xff);
3224         control |= 0x3;
3225         snd_hda_codec_write(codec,  codec->afg, 0, 0xF88, control);
3226
3227         /* Enable GPIO 0&1 for volume&mute control */
3228         /* Enable GPIO 2 for DMIC-DATA */
3229         response = snd_hda_codec_read(codec, codec->afg, 0, 0xF84, 0);
3230         control = (unsigned char)((response >> 16) & 0x3f);
3231         snd_hda_codec_write(codec,  codec->afg, 0, 0xF82, control);
3232
3233         return 0;
3234 }
3235
3236 /*
3237  * patch entries
3238  */
3239 static struct hda_codec_preset snd_hda_preset_via[] = {
3240         { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
3241         { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
3242         { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
3243         { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
3244         { .id = 0x1106e710, .name = "VT1709 10-Ch",
3245           .patch = patch_vt1709_10ch},
3246         { .id = 0x1106e711, .name = "VT1709 10-Ch",
3247           .patch = patch_vt1709_10ch},
3248         { .id = 0x1106e712, .name = "VT1709 10-Ch",
3249           .patch = patch_vt1709_10ch},
3250         { .id = 0x1106e713, .name = "VT1709 10-Ch",
3251           .patch = patch_vt1709_10ch},
3252         { .id = 0x1106e714, .name = "VT1709 6-Ch",
3253           .patch = patch_vt1709_6ch},
3254         { .id = 0x1106e715, .name = "VT1709 6-Ch",
3255           .patch = patch_vt1709_6ch},
3256         { .id = 0x1106e716, .name = "VT1709 6-Ch",
3257           .patch = patch_vt1709_6ch},
3258         { .id = 0x1106e717, .name = "VT1709 6-Ch",
3259           .patch = patch_vt1709_6ch},
3260         { .id = 0x1106e720, .name = "VT1708B 8-Ch",
3261           .patch = patch_vt1708B_8ch},
3262         { .id = 0x1106e721, .name = "VT1708B 8-Ch",
3263           .patch = patch_vt1708B_8ch},
3264         { .id = 0x1106e722, .name = "VT1708B 8-Ch",
3265           .patch = patch_vt1708B_8ch},
3266         { .id = 0x1106e723, .name = "VT1708B 8-Ch",
3267           .patch = patch_vt1708B_8ch},
3268         { .id = 0x1106e724, .name = "VT1708B 4-Ch",
3269           .patch = patch_vt1708B_4ch},
3270         { .id = 0x1106e725, .name = "VT1708B 4-Ch",
3271           .patch = patch_vt1708B_4ch},
3272         { .id = 0x1106e726, .name = "VT1708B 4-Ch",
3273           .patch = patch_vt1708B_4ch},
3274         { .id = 0x1106e727, .name = "VT1708B 4-Ch",
3275           .patch = patch_vt1708B_4ch},
3276         { .id = 0x11060397, .name = "VT1708S",
3277           .patch = patch_vt1708S},
3278         { .id = 0x11061397, .name = "VT1708S",
3279           .patch = patch_vt1708S},
3280         { .id = 0x11062397, .name = "VT1708S",
3281           .patch = patch_vt1708S},
3282         { .id = 0x11063397, .name = "VT1708S",
3283           .patch = patch_vt1708S},
3284         { .id = 0x11064397, .name = "VT1708S",
3285           .patch = patch_vt1708S},
3286         { .id = 0x11065397, .name = "VT1708S",
3287           .patch = patch_vt1708S},
3288         { .id = 0x11066397, .name = "VT1708S",
3289           .patch = patch_vt1708S},
3290         { .id = 0x11067397, .name = "VT1708S",
3291           .patch = patch_vt1708S},
3292         { .id = 0x11060398, .name = "VT1702",
3293           .patch = patch_vt1702},
3294         { .id = 0x11061398, .name = "VT1702",
3295           .patch = patch_vt1702},
3296         { .id = 0x11062398, .name = "VT1702",
3297           .patch = patch_vt1702},
3298         { .id = 0x11063398, .name = "VT1702",
3299           .patch = patch_vt1702},
3300         { .id = 0x11064398, .name = "VT1702",
3301           .patch = patch_vt1702},
3302         { .id = 0x11065398, .name = "VT1702",
3303           .patch = patch_vt1702},
3304         { .id = 0x11066398, .name = "VT1702",
3305           .patch = patch_vt1702},
3306         { .id = 0x11067398, .name = "VT1702",
3307           .patch = patch_vt1702},
3308         {} /* terminator */
3309 };
3310
3311 MODULE_ALIAS("snd-hda-codec-id:1106*");
3312
3313 static struct hda_codec_preset_list via_list = {
3314         .preset = snd_hda_preset_via,
3315         .owner = THIS_MODULE,
3316 };
3317
3318 MODULE_LICENSE("GPL");
3319 MODULE_DESCRIPTION("VIA HD-audio codec");
3320
3321 static int __init patch_via_init(void)
3322 {
3323         return snd_hda_add_codec_preset(&via_list);
3324 }
3325
3326 static void __exit patch_via_exit(void)
3327 {
3328         snd_hda_delete_codec_preset(&via_list);
3329 }
3330
3331 module_init(patch_via_init)
3332 module_exit(patch_via_exit)