ALSA: hda - Add missing EAPD initialization for VIA codecs
[daniel-s-linux-stuff:linux-kernel.git] / 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         hda_nid_t dig_in_pin;
215
216         /* capture source */
217         const struct hda_input_mux *input_mux;
218         unsigned int cur_mux[3];
219
220         /* PCM information */
221         struct hda_pcm pcm_rec[3];
222
223         /* dynamic controls, init_verbs and input_mux */
224         struct auto_pin_cfg autocfg;
225         struct snd_array kctls;
226         struct hda_input_mux private_imux[2];
227         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
228
229         /* HP mode source */
230         const struct hda_input_mux *hp_mux;
231         unsigned int hp_independent_mode;
232
233 #ifdef CONFIG_SND_HDA_POWER_SAVE
234         struct hda_loopback_check loopback;
235 #endif
236 };
237
238 static hda_nid_t vt1708_adc_nids[2] = {
239         /* ADC1-2 */
240         0x15, 0x27
241 };
242
243 static hda_nid_t vt1709_adc_nids[3] = {
244         /* ADC1-2 */
245         0x14, 0x15, 0x16
246 };
247
248 static hda_nid_t vt1708B_adc_nids[2] = {
249         /* ADC1-2 */
250         0x13, 0x14
251 };
252
253 static hda_nid_t vt1708S_adc_nids[2] = {
254         /* ADC1-2 */
255         0x13, 0x14
256 };
257
258 static hda_nid_t vt1702_adc_nids[3] = {
259         /* ADC1-2 */
260         0x12, 0x20, 0x1F
261 };
262
263 /* add dynamic controls */
264 static int via_add_control(struct via_spec *spec, int type, const char *name,
265                            unsigned long val)
266 {
267         struct snd_kcontrol_new *knew;
268
269         snd_array_init(&spec->kctls, sizeof(*knew), 32);
270         knew = snd_array_new(&spec->kctls);
271         if (!knew)
272                 return -ENOMEM;
273         *knew = vt1708_control_templates[type];
274         knew->name = kstrdup(name, GFP_KERNEL);
275         if (!knew->name)
276                 return -ENOMEM;
277         knew->private_value = val;
278         return 0;
279 }
280
281 static void via_free_kctls(struct hda_codec *codec)
282 {
283         struct via_spec *spec = codec->spec;
284
285         if (spec->kctls.list) {
286                 struct snd_kcontrol_new *kctl = spec->kctls.list;
287                 int i;
288                 for (i = 0; i < spec->kctls.used; i++)
289                         kfree(kctl[i].name);
290         }
291         snd_array_free(&spec->kctls);
292 }
293
294 /* create input playback/capture controls for the given pin */
295 static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
296                                 const char *ctlname, int idx, int mix_nid)
297 {
298         char name[32];
299         int err;
300
301         sprintf(name, "%s Playback Volume", ctlname);
302         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
303                               HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
304         if (err < 0)
305                 return err;
306         sprintf(name, "%s Playback Switch", ctlname);
307         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
308                               HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
309         if (err < 0)
310                 return err;
311         return 0;
312 }
313
314 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
315                                            hda_nid_t nid, int pin_type,
316                                            int dac_idx)
317 {
318         /* set as output */
319         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
320                             pin_type);
321         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
322                             AMP_OUT_UNMUTE);
323         if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
324                 snd_hda_codec_write(codec, nid, 0, 
325                                     AC_VERB_SET_EAPD_BTLENABLE, 0x02);
326 }
327
328
329 static void via_auto_init_multi_out(struct hda_codec *codec)
330 {
331         struct via_spec *spec = codec->spec;
332         int i;
333
334         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
335                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
336                 if (nid)
337                         via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
338         }
339 }
340
341 static void via_auto_init_hp_out(struct hda_codec *codec)
342 {
343         struct via_spec *spec = codec->spec;
344         hda_nid_t pin;
345
346         pin = spec->autocfg.hp_pins[0];
347         if (pin) /* connect to front */
348                 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
349 }
350
351 static void via_auto_init_analog_input(struct hda_codec *codec)
352 {
353         struct via_spec *spec = codec->spec;
354         int i;
355
356         for (i = 0; i < AUTO_PIN_LAST; i++) {
357                 hda_nid_t nid = spec->autocfg.input_pins[i];
358
359                 snd_hda_codec_write(codec, nid, 0,
360                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
361                                     (i <= AUTO_PIN_FRONT_MIC ?
362                                      PIN_VREF50 : PIN_IN));
363
364         }
365 }
366 /*
367  * input MUX handling
368  */
369 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
370                              struct snd_ctl_elem_info *uinfo)
371 {
372         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
373         struct via_spec *spec = codec->spec;
374         return snd_hda_input_mux_info(spec->input_mux, uinfo);
375 }
376
377 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
378                             struct snd_ctl_elem_value *ucontrol)
379 {
380         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
381         struct via_spec *spec = codec->spec;
382         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
383
384         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
385         return 0;
386 }
387
388 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
389                             struct snd_ctl_elem_value *ucontrol)
390 {
391         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
392         struct via_spec *spec = codec->spec;
393         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
394         unsigned int vendor_id = codec->vendor_id;
395
396         /* AIW0  lydia 060801 add for correct sw0 input select */
397         if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0))
398                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
399                                              0x18, &spec->cur_mux[adc_idx]);
400         else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
401                   IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0))
402                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
403                                              0x19, &spec->cur_mux[adc_idx]);
404         else if ((IS_VT1708B_8CH_VENDORID(vendor_id) ||
405                   IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0))
406                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
407                                              0x17, &spec->cur_mux[adc_idx]);
408         else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0))
409                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
410                                              0x13, &spec->cur_mux[adc_idx]);
411         else
412                 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
413                                              spec->adc_nids[adc_idx],
414                                              &spec->cur_mux[adc_idx]);
415 }
416
417 static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
418                                    struct snd_ctl_elem_info *uinfo)
419 {
420         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
421         struct via_spec *spec = codec->spec;
422         return snd_hda_input_mux_info(spec->hp_mux, uinfo);
423 }
424
425 static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
426                                   struct snd_ctl_elem_value *ucontrol)
427 {
428         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
429         struct via_spec *spec = codec->spec;
430         hda_nid_t nid = spec->autocfg.hp_pins[0];
431         unsigned int pinsel = snd_hda_codec_read(codec, nid, 0,
432                                                  AC_VERB_GET_CONNECT_SEL,
433                                                  0x00);
434
435         ucontrol->value.enumerated.item[0] = pinsel;
436
437         return 0;
438 }
439
440 static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
441                                   struct snd_ctl_elem_value *ucontrol)
442 {
443         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
444         struct via_spec *spec = codec->spec;
445         hda_nid_t nid = spec->autocfg.hp_pins[0];
446         unsigned int pinsel = ucontrol->value.enumerated.item[0];
447         unsigned int con_nid = snd_hda_codec_read(codec, nid, 0,
448                                          AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
449
450         if (con_nid == spec->multiout.hp_nid) {
451                 if (pinsel == 0) {
452                         if (!spec->hp_independent_mode) {
453                                 if (spec->multiout.num_dacs > 1)
454                                         spec->multiout.num_dacs -= 1;
455                                 spec->hp_independent_mode = 1;
456                         }
457                 } else if (pinsel == 1) {
458                        if (spec->hp_independent_mode) {
459                                 if (spec->multiout.num_dacs > 1)
460                                         spec->multiout.num_dacs += 1;
461                                 spec->hp_independent_mode = 0;
462                        }
463                 }
464         } else {
465                 if (pinsel == 0) {
466                         if (spec->hp_independent_mode) {
467                                 if (spec->multiout.num_dacs > 1)
468                                         spec->multiout.num_dacs += 1;
469                                 spec->hp_independent_mode = 0;
470                         }
471                 } else if (pinsel == 1) {
472                        if (!spec->hp_independent_mode) {
473                                 if (spec->multiout.num_dacs > 1)
474                                         spec->multiout.num_dacs -= 1;
475                                 spec->hp_independent_mode = 1;
476                        }
477                 }
478         }
479         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
480                             pinsel);
481
482         if (spec->multiout.hp_nid &&
483             spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT])
484                         snd_hda_codec_setup_stream(codec,
485                                                    spec->multiout.hp_nid,
486                                                    0, 0, 0);
487
488         return 0;
489 }
490
491 static struct snd_kcontrol_new via_hp_mixer[] = {
492         {
493                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
494                 .name = "Independent HP",
495                 .count = 1,
496                 .info = via_independent_hp_info,
497                 .get = via_independent_hp_get,
498                 .put = via_independent_hp_put,
499         },
500         { } /* end */
501 };
502
503 /* capture mixer elements */
504 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
505         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
506         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
507         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
508         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
509         {
510                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
511                 /* The multiple "Capture Source" controls confuse alsamixer
512                  * So call somewhat different..
513                  */
514                 /* .name = "Capture Source", */
515                 .name = "Input Source",
516                 .count = 1,
517                 .info = via_mux_enum_info,
518                 .get = via_mux_enum_get,
519                 .put = via_mux_enum_put,
520         },
521         { } /* end */
522 };
523 /*
524  * generic initialization of ADC, input mixers and output mixers
525  */
526 static struct hda_verb vt1708_volume_init_verbs[] = {
527         /*
528          * Unmute ADC0-1 and set the default input to mic-in
529          */
530         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
531         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
532
533
534         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
535          * mixer widget
536          */
537         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
538         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
539         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
540         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
541         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
542         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
543
544         /*
545          * Set up output mixers (0x19 - 0x1b)
546          */
547         /* set vol=0 to output mixers */
548         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
549         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
550         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
551         
552         /* Setup default input to PW4 */
553         {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
554         /* PW9 Output enable */
555         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
556         { }
557 };
558
559 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
560                                  struct hda_codec *codec,
561                                  struct snd_pcm_substream *substream)
562 {
563         struct via_spec *spec = codec->spec;
564         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
565                                              hinfo);
566 }
567
568 static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
569                                     struct hda_codec *codec,
570                                     unsigned int stream_tag,
571                                     unsigned int format,
572                                     struct snd_pcm_substream *substream)
573 {
574         struct via_spec *spec = codec->spec;
575         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
576                                                 stream_tag, format, substream);
577 }
578
579 static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
580                                     struct hda_codec *codec,
581                                     struct snd_pcm_substream *substream)
582 {
583         struct via_spec *spec = codec->spec;
584         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
585 }
586
587
588 static void playback_multi_pcm_prep_0(struct hda_codec *codec,
589                                       unsigned int stream_tag,
590                                       unsigned int format,
591                                       struct snd_pcm_substream *substream)
592 {
593         struct via_spec *spec = codec->spec;
594         struct hda_multi_out *mout = &spec->multiout;
595         hda_nid_t *nids = mout->dac_nids;
596         int chs = substream->runtime->channels;
597         int i;
598
599         mutex_lock(&codec->spdif_mutex);
600         if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
601                 if (chs == 2 &&
602                     snd_hda_is_supported_format(codec, mout->dig_out_nid,
603                                                 format) &&
604                     !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
605                         mout->dig_out_used = HDA_DIG_ANALOG_DUP;
606                         /* turn off SPDIF once; otherwise the IEC958 bits won't
607                          * be updated */
608                         if (codec->spdif_ctls & AC_DIG1_ENABLE)
609                                 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
610                                                     AC_VERB_SET_DIGI_CONVERT_1,
611                                                     codec->spdif_ctls &
612                                                         ~AC_DIG1_ENABLE & 0xff);
613                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
614                                                    stream_tag, 0, format);
615                         /* turn on again (if needed) */
616                         if (codec->spdif_ctls & AC_DIG1_ENABLE)
617                                 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
618                                                     AC_VERB_SET_DIGI_CONVERT_1,
619                                                     codec->spdif_ctls & 0xff);
620                 } else {
621                         mout->dig_out_used = 0;
622                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
623                                                    0, 0, 0);
624                 }
625         }
626         mutex_unlock(&codec->spdif_mutex);
627
628         /* front */
629         snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
630                                    0, format);
631
632         if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
633             !spec->hp_independent_mode)
634                 /* headphone out will just decode front left/right (stereo) */
635                 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
636                                            0, format);
637
638         /* extra outputs copied from front */
639         for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
640                 if (mout->extra_out_nid[i])
641                         snd_hda_codec_setup_stream(codec,
642                                                    mout->extra_out_nid[i],
643                                                    stream_tag, 0, format);
644
645         /* surrounds */
646         for (i = 1; i < mout->num_dacs; i++) {
647                 if (chs >= (i + 1) * 2) /* independent out */
648                         snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
649                                                    i * 2, format);
650                 else /* copy front */
651                         snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
652                                                    0, format);
653         }
654 }
655
656 static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
657                                           struct hda_codec *codec,
658                                           unsigned int stream_tag,
659                                           unsigned int format,
660                                           struct snd_pcm_substream *substream)
661 {
662         struct via_spec *spec = codec->spec;
663         struct hda_multi_out *mout = &spec->multiout;
664         hda_nid_t *nids = mout->dac_nids;
665
666         if (substream->number == 0)
667                 playback_multi_pcm_prep_0(codec, stream_tag, format,
668                                           substream);
669         else {
670                 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
671                     spec->hp_independent_mode)
672                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
673                                                    stream_tag, 0, format);
674         }
675
676         return 0;
677 }
678
679 static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
680                                     struct hda_codec *codec,
681                                     struct snd_pcm_substream *substream)
682 {
683         struct via_spec *spec = codec->spec;
684         struct hda_multi_out *mout = &spec->multiout;
685         hda_nid_t *nids = mout->dac_nids;
686         int i;
687
688         if (substream->number == 0) {
689                 for (i = 0; i < mout->num_dacs; i++)
690                         snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
691
692                 if (mout->hp_nid && !spec->hp_independent_mode)
693                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
694                                                    0, 0, 0);
695
696                 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
697                         if (mout->extra_out_nid[i])
698                                 snd_hda_codec_setup_stream(codec,
699                                                         mout->extra_out_nid[i],
700                                                         0, 0, 0);
701                 mutex_lock(&codec->spdif_mutex);
702                 if (mout->dig_out_nid &&
703                     mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
704                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
705                                                    0, 0, 0);
706                         mout->dig_out_used = 0;
707                 }
708                 mutex_unlock(&codec->spdif_mutex);
709         } else {
710                 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
711                     spec->hp_independent_mode)
712                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
713                                                    0, 0, 0);
714         }
715
716         return 0;
717 }
718
719 /*
720  * Digital out
721  */
722 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
723                                      struct hda_codec *codec,
724                                      struct snd_pcm_substream *substream)
725 {
726         struct via_spec *spec = codec->spec;
727         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
728 }
729
730 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
731                                       struct hda_codec *codec,
732                                       struct snd_pcm_substream *substream)
733 {
734         struct via_spec *spec = codec->spec;
735         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
736 }
737
738 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
739                                         struct hda_codec *codec,
740                                         unsigned int stream_tag,
741                                         unsigned int format,
742                                         struct snd_pcm_substream *substream)
743 {
744         struct via_spec *spec = codec->spec;
745         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
746                                              stream_tag, format, substream);
747 }
748
749 static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
750                                         struct hda_codec *codec,
751                                         struct snd_pcm_substream *substream)
752 {
753         struct via_spec *spec = codec->spec;
754         snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
755         return 0;
756 }
757
758 /*
759  * Analog capture
760  */
761 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
762                                    struct hda_codec *codec,
763                                    unsigned int stream_tag,
764                                    unsigned int format,
765                                    struct snd_pcm_substream *substream)
766 {
767         struct via_spec *spec = codec->spec;
768
769         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
770                                    stream_tag, 0, format);
771         return 0;
772 }
773
774 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
775                                    struct hda_codec *codec,
776                                    struct snd_pcm_substream *substream)
777 {
778         struct via_spec *spec = codec->spec;
779         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
780         return 0;
781 }
782
783 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
784         .substreams = 2,
785         .channels_min = 2,
786         .channels_max = 8,
787         .nid = 0x10, /* NID to query formats and rates */
788         .ops = {
789                 .open = via_playback_pcm_open,
790                 .prepare = via_playback_multi_pcm_prepare,
791                 .cleanup = via_playback_multi_pcm_cleanup
792         },
793 };
794
795 static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
796         .substreams = 1,
797         .channels_min = 2,
798         .channels_max = 8,
799         .nid = 0x10, /* NID to query formats and rates */
800         /* We got noisy outputs on the right channel on VT1708 when
801          * 24bit samples are used.  Until any workaround is found,
802          * disable the 24bit format, so far.
803          */
804         .formats = SNDRV_PCM_FMTBIT_S16_LE,
805         .ops = {
806                 .open = via_playback_pcm_open,
807                 .prepare = via_playback_pcm_prepare,
808                 .cleanup = via_playback_pcm_cleanup
809         },
810 };
811
812 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
813         .substreams = 2,
814         .channels_min = 2,
815         .channels_max = 2,
816         .nid = 0x15, /* NID to query formats and rates */
817         .ops = {
818                 .prepare = via_capture_pcm_prepare,
819                 .cleanup = via_capture_pcm_cleanup
820         },
821 };
822
823 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
824         .substreams = 1,
825         .channels_min = 2,
826         .channels_max = 2,
827         /* NID is set in via_build_pcms */
828         .ops = {
829                 .open = via_dig_playback_pcm_open,
830                 .close = via_dig_playback_pcm_close,
831                 .prepare = via_dig_playback_pcm_prepare,
832                 .cleanup = via_dig_playback_pcm_cleanup
833         },
834 };
835
836 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
837         .substreams = 1,
838         .channels_min = 2,
839         .channels_max = 2,
840 };
841
842 static int via_build_controls(struct hda_codec *codec)
843 {
844         struct via_spec *spec = codec->spec;
845         int err;
846         int i;
847
848         for (i = 0; i < spec->num_mixers; i++) {
849                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
850                 if (err < 0)
851                         return err;
852         }
853
854         if (spec->multiout.dig_out_nid) {
855                 err = snd_hda_create_spdif_out_ctls(codec,
856                                                     spec->multiout.dig_out_nid);
857                 if (err < 0)
858                         return err;
859                 err = snd_hda_create_spdif_share_sw(codec,
860                                                     &spec->multiout);
861                 if (err < 0)
862                         return err;
863                 spec->multiout.share_spdif = 1;
864         }
865         if (spec->dig_in_nid) {
866                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
867                 if (err < 0)
868                         return err;
869         }
870         via_free_kctls(codec); /* no longer needed */
871         return 0;
872 }
873
874 static int via_build_pcms(struct hda_codec *codec)
875 {
876         struct via_spec *spec = codec->spec;
877         struct hda_pcm *info = spec->pcm_rec;
878
879         codec->num_pcms = 1;
880         codec->pcm_info = info;
881
882         info->name = spec->stream_name_analog;
883         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
884         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
885         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
886         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
887
888         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
889                 spec->multiout.max_channels;
890
891         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
892                 codec->num_pcms++;
893                 info++;
894                 info->name = spec->stream_name_digital;
895                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
896                 if (spec->multiout.dig_out_nid) {
897                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
898                                 *(spec->stream_digital_playback);
899                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
900                                 spec->multiout.dig_out_nid;
901                 }
902                 if (spec->dig_in_nid) {
903                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
904                                 *(spec->stream_digital_capture);
905                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
906                                 spec->dig_in_nid;
907                 }
908         }
909
910         return 0;
911 }
912
913 static void via_free(struct hda_codec *codec)
914 {
915         struct via_spec *spec = codec->spec;
916
917         if (!spec)
918                 return;
919
920         via_free_kctls(codec);
921         kfree(codec->spec);
922 }
923
924 /* mute internal speaker if HP is plugged */
925 static void via_hp_automute(struct hda_codec *codec)
926 {
927         unsigned int present;
928         struct via_spec *spec = codec->spec;
929
930         present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0,
931                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
932         snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
933                                  HDA_OUTPUT, 0, HDA_AMP_MUTE,
934                                  present ? HDA_AMP_MUTE : 0);
935 }
936
937 static void via_gpio_control(struct hda_codec *codec)
938 {
939         unsigned int gpio_data;
940         unsigned int vol_counter;
941         unsigned int vol;
942         unsigned int master_vol;
943
944         struct via_spec *spec = codec->spec;
945
946         gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
947                                        AC_VERB_GET_GPIO_DATA, 0) & 0x03;
948
949         vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
950                                           0xF84, 0) & 0x3F0000) >> 16;
951
952         vol = vol_counter & 0x1F;
953         master_vol = snd_hda_codec_read(codec, 0x1A, 0,
954                                         AC_VERB_GET_AMP_GAIN_MUTE,
955                                         AC_AMP_GET_INPUT);
956
957         if (gpio_data == 0x02) {
958                 /* unmute line out */
959                 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
960                                          HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
961
962                 if (vol_counter & 0x20) {
963                         /* decrease volume */
964                         if (vol > master_vol)
965                                 vol = master_vol;
966                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
967                                                  0, HDA_AMP_VOLMASK,
968                                                  master_vol-vol);
969                 } else {
970                         /* increase volume */
971                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
972                                          HDA_AMP_VOLMASK,
973                                          ((master_vol+vol) > 0x2A) ? 0x2A :
974                                           (master_vol+vol));
975                 }
976         } else if (!(gpio_data & 0x02)) {
977                 /* mute line out */
978                 snd_hda_codec_amp_stereo(codec,
979                                          spec->autocfg.line_out_pins[0],
980                                          HDA_OUTPUT, 0, HDA_AMP_MUTE,
981                                          HDA_AMP_MUTE);
982         }
983 }
984
985 /* unsolicited event for jack sensing */
986 static void via_unsol_event(struct hda_codec *codec,
987                                   unsigned int res)
988 {
989         res >>= 26;
990         if (res == VIA_HP_EVENT)
991                 via_hp_automute(codec);
992         else if (res == VIA_GPIO_EVENT)
993                 via_gpio_control(codec);
994 }
995
996 static int via_init(struct hda_codec *codec)
997 {
998         struct via_spec *spec = codec->spec;
999         int i;
1000         for (i = 0; i < spec->num_iverbs; i++)
1001                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1002
1003         /* Lydia Add for EAPD enable */
1004         if (!spec->dig_in_nid) { /* No Digital In connection */
1005                 if (spec->dig_in_pin) {
1006                         snd_hda_codec_write(codec, spec->dig_in_pin, 0,
1007                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1008                                             PIN_OUT);
1009                         snd_hda_codec_write(codec, spec->dig_in_pin, 0,
1010                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1011                 }
1012         } else /* enable SPDIF-input pin */
1013                 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
1014                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
1015
1016         /* assign slave outs */
1017         if (spec->slave_dig_outs[0])
1018                 codec->slave_dig_outs = spec->slave_dig_outs;
1019
1020         return 0;
1021 }
1022
1023 #ifdef CONFIG_SND_HDA_POWER_SAVE
1024 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1025 {
1026         struct via_spec *spec = codec->spec;
1027         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
1028 }
1029 #endif
1030
1031 /*
1032  */
1033 static struct hda_codec_ops via_patch_ops = {
1034         .build_controls = via_build_controls,
1035         .build_pcms = via_build_pcms,
1036         .init = via_init,
1037         .free = via_free,
1038 #ifdef CONFIG_SND_HDA_POWER_SAVE
1039         .check_power_status = via_check_power_status,
1040 #endif
1041 };
1042
1043 /* fill in the dac_nids table from the parsed pin configuration */
1044 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
1045                                      const struct auto_pin_cfg *cfg)
1046 {
1047         int i;
1048         hda_nid_t nid;
1049
1050         spec->multiout.num_dacs = cfg->line_outs;
1051
1052         spec->multiout.dac_nids = spec->private_dac_nids;
1053         
1054         for(i = 0; i < 4; i++) {
1055                 nid = cfg->line_out_pins[i];
1056                 if (nid) {
1057                         /* config dac list */
1058                         switch (i) {
1059                         case AUTO_SEQ_FRONT:
1060                                 spec->multiout.dac_nids[i] = 0x10;
1061                                 break;
1062                         case AUTO_SEQ_CENLFE:
1063                                 spec->multiout.dac_nids[i] = 0x12;
1064                                 break;
1065                         case AUTO_SEQ_SURROUND:
1066                                 spec->multiout.dac_nids[i] = 0x11;
1067                                 break;
1068                         case AUTO_SEQ_SIDE:
1069                                 spec->multiout.dac_nids[i] = 0x13;
1070                                 break;
1071                         }
1072                 }
1073         }
1074
1075         return 0;
1076 }
1077
1078 /* add playback controls from the parsed DAC table */
1079 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
1080                                              const struct auto_pin_cfg *cfg)
1081 {
1082         char name[32];
1083         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1084         hda_nid_t nid, nid_vol = 0;
1085         int i, err;
1086
1087         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1088                 nid = cfg->line_out_pins[i];
1089
1090                 if (!nid)
1091                         continue;
1092                 
1093                 if (i != AUTO_SEQ_FRONT)
1094                         nid_vol = 0x18 + i;
1095
1096                 if (i == AUTO_SEQ_CENLFE) {
1097                         /* Center/LFE */
1098                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1099                                         "Center Playback Volume",
1100                                         HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1101                                                             HDA_OUTPUT));
1102                         if (err < 0)
1103                                 return err;
1104                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1105                                               "LFE Playback Volume",
1106                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1107                                                                   HDA_OUTPUT));
1108                         if (err < 0)
1109                                 return err;
1110                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1111                                               "Center Playback Switch",
1112                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1113                                                                   HDA_OUTPUT));
1114                         if (err < 0)
1115                                 return err;
1116                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1117                                               "LFE Playback Switch",
1118                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1119                                                                   HDA_OUTPUT));
1120                         if (err < 0)
1121                                 return err;
1122                 } else if (i == AUTO_SEQ_FRONT){
1123                         /* add control to mixer index 0 */
1124                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1125                                               "Master Front Playback Volume",
1126                                               HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
1127                                                                   HDA_INPUT));
1128                         if (err < 0)
1129                                 return err;
1130                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1131                                               "Master Front Playback Switch",
1132                                               HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
1133                                                                   HDA_INPUT));
1134                         if (err < 0)
1135                                 return err;
1136                         
1137                         /* add control to PW3 */
1138                         sprintf(name, "%s Playback Volume", chname[i]);
1139                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1140                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1141                                                                   HDA_OUTPUT));
1142                         if (err < 0)
1143                                 return err;
1144                         sprintf(name, "%s Playback Switch", chname[i]);
1145                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1146                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1147                                                                   HDA_OUTPUT));
1148                         if (err < 0)
1149                                 return err;
1150                 } else {
1151                         sprintf(name, "%s Playback Volume", chname[i]);
1152                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1153                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1154                                                                   HDA_OUTPUT));
1155                         if (err < 0)
1156                                 return err;
1157                         sprintf(name, "%s Playback Switch", chname[i]);
1158                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1159                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1160                                                                   HDA_OUTPUT));
1161                         if (err < 0)
1162                                 return err;
1163                 }
1164         }
1165
1166         return 0;
1167 }
1168
1169 static void create_hp_imux(struct via_spec *spec)
1170 {
1171         int i;
1172         struct hda_input_mux *imux = &spec->private_imux[1];
1173         static const char *texts[] = { "OFF", "ON", NULL};
1174
1175         /* for hp mode select */
1176         i = 0;
1177         while (texts[i] != NULL) {
1178                 imux->items[imux->num_items].label =  texts[i];
1179                 imux->items[imux->num_items].index = i;
1180                 imux->num_items++;
1181                 i++;
1182         }
1183
1184         spec->hp_mux = &spec->private_imux[1];
1185 }
1186
1187 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1188 {
1189         int err;
1190
1191         if (!pin)
1192                 return 0;
1193
1194         spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
1195
1196         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1197                               "Headphone Playback Volume",
1198                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1199         if (err < 0)
1200                 return err;
1201         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1202                               "Headphone Playback Switch",
1203                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1204         if (err < 0)
1205                 return err;
1206
1207         create_hp_imux(spec);
1208
1209         return 0;
1210 }
1211
1212 /* create playback/capture controls for input pins */
1213 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
1214                                                 const struct auto_pin_cfg *cfg)
1215 {
1216         static char *labels[] = {
1217                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1218         };
1219         struct hda_input_mux *imux = &spec->private_imux[0];
1220         int i, err, idx = 0;
1221
1222         /* for internal loopback recording select */
1223         imux->items[imux->num_items].label = "Stereo Mixer";
1224         imux->items[imux->num_items].index = idx;
1225         imux->num_items++;
1226
1227         for (i = 0; i < AUTO_PIN_LAST; i++) {
1228                 if (!cfg->input_pins[i])
1229                         continue;
1230
1231                 switch (cfg->input_pins[i]) {
1232                 case 0x1d: /* Mic */
1233                         idx = 2;
1234                         break;
1235                                 
1236                 case 0x1e: /* Line In */
1237                         idx = 3;
1238                         break;
1239
1240                 case 0x21: /* Front Mic */
1241                         idx = 4;
1242                         break;
1243
1244                 case 0x24: /* CD */
1245                         idx = 1;
1246                         break;
1247                 }
1248                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1249                                            idx, 0x17);
1250                 if (err < 0)
1251                         return err;
1252                 imux->items[imux->num_items].label = labels[i];
1253                 imux->items[imux->num_items].index = idx;
1254                 imux->num_items++;
1255         }
1256         return 0;
1257 }
1258
1259 #ifdef CONFIG_SND_HDA_POWER_SAVE
1260 static struct hda_amp_list vt1708_loopbacks[] = {
1261         { 0x17, HDA_INPUT, 1 },
1262         { 0x17, HDA_INPUT, 2 },
1263         { 0x17, HDA_INPUT, 3 },
1264         { 0x17, HDA_INPUT, 4 },
1265         { } /* end */
1266 };
1267 #endif
1268
1269 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
1270 {
1271         unsigned int def_conf;
1272         unsigned char seqassoc;
1273
1274         def_conf = snd_hda_codec_get_pincfg(codec, nid);
1275         seqassoc = (unsigned char) get_defcfg_association(def_conf);
1276         seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
1277         if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) {
1278                 if (seqassoc == 0xff) {
1279                         def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
1280                         snd_hda_codec_set_pincfg(codec, nid, def_conf);
1281                 }
1282         }
1283
1284         return;
1285 }
1286
1287 static int vt1708_parse_auto_config(struct hda_codec *codec)
1288 {
1289         struct via_spec *spec = codec->spec;
1290         int err;
1291
1292         /* Add HP and CD pin config connect bit re-config action */
1293         vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
1294         vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
1295
1296         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1297         if (err < 0)
1298                 return err;
1299         err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
1300         if (err < 0)
1301                 return err;
1302         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1303                 return 0; /* can't find valid BIOS pin config */
1304
1305         err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
1306         if (err < 0)
1307                 return err;
1308         err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1309         if (err < 0)
1310                 return err;
1311         err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
1312         if (err < 0)
1313                 return err;
1314
1315         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1316
1317         if (spec->autocfg.dig_outs)
1318                 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
1319         spec->dig_in_pin = VT1708_DIGIN_PIN;
1320         if (spec->autocfg.dig_in_pin)
1321                 spec->dig_in_nid = VT1708_DIGIN_NID;
1322
1323         if (spec->kctls.list)
1324                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1325
1326         spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
1327
1328         spec->input_mux = &spec->private_imux[0];
1329
1330         if (spec->hp_mux)
1331                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
1332
1333         return 1;
1334 }
1335
1336 /* init callback for auto-configuration model -- overriding the default init */
1337 static int via_auto_init(struct hda_codec *codec)
1338 {
1339         via_init(codec);
1340         via_auto_init_multi_out(codec);
1341         via_auto_init_hp_out(codec);
1342         via_auto_init_analog_input(codec);
1343         return 0;
1344 }
1345
1346 static int patch_vt1708(struct hda_codec *codec)
1347 {
1348         struct via_spec *spec;
1349         int err;
1350
1351         /* create a codec specific record */
1352         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1353         if (spec == NULL)
1354                 return -ENOMEM;
1355
1356         codec->spec = spec;
1357
1358         /* automatic parse from the BIOS config */
1359         err = vt1708_parse_auto_config(codec);
1360         if (err < 0) {
1361                 via_free(codec);
1362                 return err;
1363         } else if (!err) {
1364                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
1365                        "from BIOS.  Using genenic mode...\n");
1366         }
1367
1368         
1369         spec->stream_name_analog = "VT1708 Analog";
1370         spec->stream_analog_playback = &vt1708_pcm_analog_playback;
1371         /* disable 32bit format on VT1708 */
1372         if (codec->vendor_id == 0x11061708)
1373                 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
1374         spec->stream_analog_capture = &vt1708_pcm_analog_capture;
1375
1376         spec->stream_name_digital = "VT1708 Digital";
1377         spec->stream_digital_playback = &vt1708_pcm_digital_playback;
1378         spec->stream_digital_capture = &vt1708_pcm_digital_capture;
1379
1380         
1381         if (!spec->adc_nids && spec->input_mux) {
1382                 spec->adc_nids = vt1708_adc_nids;
1383                 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
1384                 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
1385                 spec->num_mixers++;
1386         }
1387
1388         codec->patch_ops = via_patch_ops;
1389
1390         codec->patch_ops.init = via_auto_init;
1391 #ifdef CONFIG_SND_HDA_POWER_SAVE
1392         spec->loopback.amplist = vt1708_loopbacks;
1393 #endif
1394
1395         return 0;
1396 }
1397
1398 /* capture mixer elements */
1399 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
1400         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
1401         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
1402         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
1403         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
1404         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
1405         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
1406         {
1407                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1408                 /* The multiple "Capture Source" controls confuse alsamixer
1409                  * So call somewhat different..
1410                  */
1411                 /* .name = "Capture Source", */
1412                 .name = "Input Source",
1413                 .count = 1,
1414                 .info = via_mux_enum_info,
1415                 .get = via_mux_enum_get,
1416                 .put = via_mux_enum_put,
1417         },
1418         { } /* end */
1419 };
1420
1421 static struct hda_verb vt1709_uniwill_init_verbs[] = {
1422         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
1423         { }
1424 };
1425
1426 /*
1427  * generic initialization of ADC, input mixers and output mixers
1428  */
1429 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
1430         /*
1431          * Unmute ADC0-2 and set the default input to mic-in
1432          */
1433         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1434         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1435         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1436
1437
1438         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1439          * mixer widget
1440          */
1441         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1442         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1443         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1444         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1445         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1446         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1447
1448         /*
1449          * Set up output selector (0x1a, 0x1b, 0x29)
1450          */
1451         /* set vol=0 to output mixers */
1452         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1453         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1454         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1455
1456         /*
1457          *  Unmute PW3 and PW4
1458          */
1459         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1460         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1461
1462         /* Set input of PW4 as AOW4 */
1463         {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
1464         /* PW9 Output enable */
1465         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1466         { }
1467 };
1468
1469 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
1470         .substreams = 1,
1471         .channels_min = 2,
1472         .channels_max = 10,
1473         .nid = 0x10, /* NID to query formats and rates */
1474         .ops = {
1475                 .open = via_playback_pcm_open,
1476                 .prepare = via_playback_pcm_prepare,
1477                 .cleanup = via_playback_pcm_cleanup
1478         },
1479 };
1480
1481 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
1482         .substreams = 1,
1483         .channels_min = 2,
1484         .channels_max = 6,
1485         .nid = 0x10, /* NID to query formats and rates */
1486         .ops = {
1487                 .open = via_playback_pcm_open,
1488                 .prepare = via_playback_pcm_prepare,
1489                 .cleanup = via_playback_pcm_cleanup
1490         },
1491 };
1492
1493 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
1494         .substreams = 2,
1495         .channels_min = 2,
1496         .channels_max = 2,
1497         .nid = 0x14, /* NID to query formats and rates */
1498         .ops = {
1499                 .prepare = via_capture_pcm_prepare,
1500                 .cleanup = via_capture_pcm_cleanup
1501         },
1502 };
1503
1504 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
1505         .substreams = 1,
1506         .channels_min = 2,
1507         .channels_max = 2,
1508         /* NID is set in via_build_pcms */
1509         .ops = {
1510                 .open = via_dig_playback_pcm_open,
1511                 .close = via_dig_playback_pcm_close
1512         },
1513 };
1514
1515 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
1516         .substreams = 1,
1517         .channels_min = 2,
1518         .channels_max = 2,
1519 };
1520
1521 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
1522                                      const struct auto_pin_cfg *cfg)
1523 {
1524         int i;
1525         hda_nid_t nid;
1526
1527         if (cfg->line_outs == 4)  /* 10 channels */
1528                 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
1529         else if (cfg->line_outs == 3) /* 6 channels */
1530                 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
1531
1532         spec->multiout.dac_nids = spec->private_dac_nids;
1533
1534         if (cfg->line_outs == 4) { /* 10 channels */
1535                 for (i = 0; i < cfg->line_outs; i++) {
1536                         nid = cfg->line_out_pins[i];
1537                         if (nid) {
1538                                 /* config dac list */
1539                                 switch (i) {
1540                                 case AUTO_SEQ_FRONT:
1541                                         /* AOW0 */
1542                                         spec->multiout.dac_nids[i] = 0x10;
1543                                         break;
1544                                 case AUTO_SEQ_CENLFE:
1545                                         /* AOW2 */
1546                                         spec->multiout.dac_nids[i] = 0x12;
1547                                         break;
1548                                 case AUTO_SEQ_SURROUND:
1549                                         /* AOW3 */
1550                                         spec->multiout.dac_nids[i] = 0x11;
1551                                         break;
1552                                 case AUTO_SEQ_SIDE:
1553                                         /* AOW1 */
1554                                         spec->multiout.dac_nids[i] = 0x27;
1555                                         break;
1556                                 default:
1557                                         break;
1558                                 }
1559                         }
1560                 }
1561                 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1562
1563         } else if (cfg->line_outs == 3) { /* 6 channels */
1564                 for(i = 0; i < cfg->line_outs; i++) {
1565                         nid = cfg->line_out_pins[i];
1566                         if (nid) {
1567                                 /* config dac list */
1568                                 switch(i) {
1569                                 case AUTO_SEQ_FRONT:
1570                                         /* AOW0 */
1571                                         spec->multiout.dac_nids[i] = 0x10;
1572                                         break;
1573                                 case AUTO_SEQ_CENLFE:
1574                                         /* AOW2 */
1575                                         spec->multiout.dac_nids[i] = 0x12;
1576                                         break;
1577                                 case AUTO_SEQ_SURROUND:
1578                                         /* AOW1 */
1579                                         spec->multiout.dac_nids[i] = 0x11;
1580                                         break;
1581                                 default:
1582                                         break;
1583                                 }
1584                         }
1585                 }
1586         }
1587
1588         return 0;
1589 }
1590
1591 /* add playback controls from the parsed DAC table */
1592 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1593                                              const struct auto_pin_cfg *cfg)
1594 {
1595         char name[32];
1596         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1597         hda_nid_t nid = 0;
1598         int i, err;
1599
1600         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1601                 nid = cfg->line_out_pins[i];
1602
1603                 if (!nid)       
1604                         continue;
1605
1606                 if (i == AUTO_SEQ_CENLFE) {
1607                         /* Center/LFE */
1608                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1609                                               "Center Playback Volume",
1610                                               HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1611                                                                   HDA_OUTPUT));
1612                         if (err < 0)
1613                                 return err;
1614                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1615                                               "LFE Playback Volume",
1616                                               HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1617                                                                   HDA_OUTPUT));
1618                         if (err < 0)
1619                                 return err;
1620                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1621                                               "Center Playback Switch",
1622                                               HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1623                                                                   HDA_OUTPUT));
1624                         if (err < 0)
1625                                 return err;
1626                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1627                                               "LFE Playback Switch",
1628                                               HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1629                                                                   HDA_OUTPUT));
1630                         if (err < 0)
1631                                 return err;
1632                 } else if (i == AUTO_SEQ_FRONT){
1633                         /* add control to mixer index 0 */
1634                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1635                                               "Master Front Playback Volume",
1636                                               HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1637                                                                   HDA_INPUT));
1638                         if (err < 0)
1639                                 return err;
1640                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1641                                               "Master Front Playback Switch",
1642                                               HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1643                                                                   HDA_INPUT));
1644                         if (err < 0)
1645                                 return err;
1646                         
1647                         /* add control to PW3 */
1648                         sprintf(name, "%s Playback Volume", chname[i]);
1649                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1650                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1651                                                                   HDA_OUTPUT));
1652                         if (err < 0)
1653                                 return err;
1654                         sprintf(name, "%s Playback Switch", chname[i]);
1655                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1656                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1657                                                                   HDA_OUTPUT));
1658                         if (err < 0)
1659                                 return err;
1660                 } else if (i == AUTO_SEQ_SURROUND) {
1661                         sprintf(name, "%s Playback Volume", chname[i]);
1662                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1663                                               HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1664                                                                   HDA_OUTPUT));
1665                         if (err < 0)
1666                                 return err;
1667                         sprintf(name, "%s Playback Switch", chname[i]);
1668                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1669                                               HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
1670                                                                   HDA_OUTPUT));
1671                         if (err < 0)
1672                                 return err;
1673                 } else if (i == AUTO_SEQ_SIDE) {
1674                         sprintf(name, "%s Playback Volume", chname[i]);
1675                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1676                                               HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1677                                                                   HDA_OUTPUT));
1678                         if (err < 0)
1679                                 return err;
1680                         sprintf(name, "%s Playback Switch", chname[i]);
1681                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1682                                               HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
1683                                                                   HDA_OUTPUT));
1684                         if (err < 0)
1685                                 return err;
1686                 }
1687         }
1688
1689         return 0;
1690 }
1691
1692 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1693 {
1694         int err;
1695
1696         if (!pin)
1697                 return 0;
1698
1699         if (spec->multiout.num_dacs == 5) /* 10 channels */
1700                 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1701         else if (spec->multiout.num_dacs == 3) /* 6 channels */
1702                 spec->multiout.hp_nid = 0;
1703
1704         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1705                               "Headphone Playback Volume",
1706                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1707         if (err < 0)
1708                 return err;
1709         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1710                               "Headphone Playback Switch",
1711                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1712         if (err < 0)
1713                 return err;
1714
1715         return 0;
1716 }
1717
1718 /* create playback/capture controls for input pins */
1719 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1720                                                 const struct auto_pin_cfg *cfg)
1721 {
1722         static char *labels[] = {
1723                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1724         };
1725         struct hda_input_mux *imux = &spec->private_imux[0];
1726         int i, err, idx = 0;
1727
1728         /* for internal loopback recording select */
1729         imux->items[imux->num_items].label = "Stereo Mixer";
1730         imux->items[imux->num_items].index = idx;
1731         imux->num_items++;
1732
1733         for (i = 0; i < AUTO_PIN_LAST; i++) {
1734                 if (!cfg->input_pins[i])
1735                         continue;
1736
1737                 switch (cfg->input_pins[i]) {
1738                 case 0x1d: /* Mic */
1739                         idx = 2;
1740                         break;
1741                                 
1742                 case 0x1e: /* Line In */
1743                         idx = 3;
1744                         break;
1745
1746                 case 0x21: /* Front Mic */
1747                         idx = 4;
1748                         break;
1749
1750                 case 0x23: /* CD */
1751                         idx = 1;
1752                         break;
1753                 }
1754                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1755                                            idx, 0x18);
1756                 if (err < 0)
1757                         return err;
1758                 imux->items[imux->num_items].label = labels[i];
1759                 imux->items[imux->num_items].index = idx;
1760                 imux->num_items++;
1761         }
1762         return 0;
1763 }
1764
1765 static int vt1709_parse_auto_config(struct hda_codec *codec)
1766 {
1767         struct via_spec *spec = codec->spec;
1768         int err;
1769
1770         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1771         if (err < 0)
1772                 return err;
1773         err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
1774         if (err < 0)
1775                 return err;
1776         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1777                 return 0; /* can't find valid BIOS pin config */
1778
1779         err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
1780         if (err < 0)
1781                 return err;
1782         err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1783         if (err < 0)
1784                 return err;
1785         err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
1786         if (err < 0)
1787                 return err;
1788
1789         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1790
1791         if (spec->autocfg.dig_outs)
1792                 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
1793         spec->dig_in_pin = VT1709_DIGIN_PIN;
1794         if (spec->autocfg.dig_in_pin)
1795                 spec->dig_in_nid = VT1709_DIGIN_NID;
1796
1797         if (spec->kctls.list)
1798                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1799
1800         spec->input_mux = &spec->private_imux[0];
1801
1802         if (spec->hp_mux)
1803                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
1804
1805         return 1;
1806 }
1807
1808 #ifdef CONFIG_SND_HDA_POWER_SAVE
1809 static struct hda_amp_list vt1709_loopbacks[] = {
1810         { 0x18, HDA_INPUT, 1 },
1811         { 0x18, HDA_INPUT, 2 },
1812         { 0x18, HDA_INPUT, 3 },
1813         { 0x18, HDA_INPUT, 4 },
1814         { } /* end */
1815 };
1816 #endif
1817
1818 static int patch_vt1709_10ch(struct hda_codec *codec)
1819 {
1820         struct via_spec *spec;
1821         int err;
1822
1823         /* create a codec specific record */
1824         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1825         if (spec == NULL)
1826                 return -ENOMEM;
1827
1828         codec->spec = spec;
1829
1830         err = vt1709_parse_auto_config(codec);
1831         if (err < 0) {
1832                 via_free(codec);
1833                 return err;
1834         } else if (!err) {
1835                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1836                        "Using genenic mode...\n");
1837         }
1838
1839         spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
1840         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
1841
1842         spec->stream_name_analog = "VT1709 Analog";
1843         spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
1844         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1845
1846         spec->stream_name_digital = "VT1709 Digital";
1847         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1848         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1849
1850         
1851         if (!spec->adc_nids && spec->input_mux) {
1852                 spec->adc_nids = vt1709_adc_nids;
1853                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1854                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1855                 spec->num_mixers++;
1856         }
1857
1858         codec->patch_ops = via_patch_ops;
1859
1860         codec->patch_ops.init = via_auto_init;
1861         codec->patch_ops.unsol_event = via_unsol_event;
1862 #ifdef CONFIG_SND_HDA_POWER_SAVE
1863         spec->loopback.amplist = vt1709_loopbacks;
1864 #endif
1865
1866         return 0;
1867 }
1868 /*
1869  * generic initialization of ADC, input mixers and output mixers
1870  */
1871 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
1872         /*
1873          * Unmute ADC0-2 and set the default input to mic-in
1874          */
1875         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1876         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1877         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1878
1879
1880         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1881          * mixer widget
1882          */
1883         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1884         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1885         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1886         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1887         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1888         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1889
1890         /*
1891          * Set up output selector (0x1a, 0x1b, 0x29)
1892          */
1893         /* set vol=0 to output mixers */
1894         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1895         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1896         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1897
1898         /*
1899          *  Unmute PW3 and PW4
1900          */
1901         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1902         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1903
1904         /* Set input of PW4 as MW0 */
1905         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1906         /* PW9 Output enable */
1907         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1908         { }
1909 };
1910
1911 static int patch_vt1709_6ch(struct hda_codec *codec)
1912 {
1913         struct via_spec *spec;
1914         int err;
1915
1916         /* create a codec specific record */
1917         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1918         if (spec == NULL)
1919                 return -ENOMEM;
1920
1921         codec->spec = spec;
1922
1923         err = vt1709_parse_auto_config(codec);
1924         if (err < 0) {
1925                 via_free(codec);
1926                 return err;
1927         } else if (!err) {
1928                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
1929                        "Using genenic mode...\n");
1930         }
1931
1932         spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
1933         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
1934
1935         spec->stream_name_analog = "VT1709 Analog";
1936         spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
1937         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1938
1939         spec->stream_name_digital = "VT1709 Digital";
1940         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1941         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1942
1943         
1944         if (!spec->adc_nids && spec->input_mux) {
1945                 spec->adc_nids = vt1709_adc_nids;
1946                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1947                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1948                 spec->num_mixers++;
1949         }
1950
1951         codec->patch_ops = via_patch_ops;
1952
1953         codec->patch_ops.init = via_auto_init;
1954         codec->patch_ops.unsol_event = via_unsol_event;
1955 #ifdef CONFIG_SND_HDA_POWER_SAVE
1956         spec->loopback.amplist = vt1709_loopbacks;
1957 #endif
1958         return 0;
1959 }
1960
1961 /* capture mixer elements */
1962 static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
1963         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
1964         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
1965         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
1966         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
1967         {
1968                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1969                 /* The multiple "Capture Source" controls confuse alsamixer
1970                  * So call somewhat different..
1971                  */
1972                 /* .name = "Capture Source", */
1973                 .name = "Input Source",
1974                 .count = 1,
1975                 .info = via_mux_enum_info,
1976                 .get = via_mux_enum_get,
1977                 .put = via_mux_enum_put,
1978         },
1979         { } /* end */
1980 };
1981 /*
1982  * generic initialization of ADC, input mixers and output mixers
1983  */
1984 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
1985         /*
1986          * Unmute ADC0-1 and set the default input to mic-in
1987          */
1988         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1989         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1990
1991
1992         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1993          * mixer widget
1994          */
1995         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1996         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1997         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1998         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1999         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2000         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2001
2002         /*
2003          * Set up output mixers
2004          */
2005         /* set vol=0 to output mixers */
2006         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2007         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2008         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2009
2010         /* Setup default input to PW4 */
2011         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1},
2012         /* PW9 Output enable */
2013         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2014         /* PW10 Input enable */
2015         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2016         { }
2017 };
2018
2019 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
2020         /*
2021          * Unmute ADC0-1 and set the default input to mic-in
2022          */
2023         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2024         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2025
2026
2027         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2028          * mixer widget
2029          */
2030         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2031         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2032         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2033         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2034         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2035         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2036
2037         /*
2038          * Set up output mixers
2039          */
2040         /* set vol=0 to output mixers */
2041         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2042         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2043         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2044
2045         /* Setup default input of PW4 to MW0 */
2046         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2047         /* PW9 Output enable */
2048         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2049         /* PW10 Input enable */
2050         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2051         { }
2052 };
2053
2054 static struct hda_verb vt1708B_uniwill_init_verbs[] = {
2055         {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
2056         { }
2057 };
2058
2059 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
2060         .substreams = 2,
2061         .channels_min = 2,
2062         .channels_max = 8,
2063         .nid = 0x10, /* NID to query formats and rates */
2064         .ops = {
2065                 .open = via_playback_pcm_open,
2066                 .prepare = via_playback_multi_pcm_prepare,
2067                 .cleanup = via_playback_multi_pcm_cleanup
2068         },
2069 };
2070
2071 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
2072         .substreams = 2,
2073         .channels_min = 2,
2074         .channels_max = 4,
2075         .nid = 0x10, /* NID to query formats and rates */
2076         .ops = {
2077                 .open = via_playback_pcm_open,
2078                 .prepare = via_playback_multi_pcm_prepare,
2079                 .cleanup = via_playback_multi_pcm_cleanup
2080         },
2081 };
2082
2083 static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
2084         .substreams = 2,
2085         .channels_min = 2,
2086         .channels_max = 2,
2087         .nid = 0x13, /* NID to query formats and rates */
2088         .ops = {
2089                 .prepare = via_capture_pcm_prepare,
2090                 .cleanup = via_capture_pcm_cleanup
2091         },
2092 };
2093
2094 static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
2095         .substreams = 1,
2096         .channels_min = 2,
2097         .channels_max = 2,
2098         /* NID is set in via_build_pcms */
2099         .ops = {
2100                 .open = via_dig_playback_pcm_open,
2101                 .close = via_dig_playback_pcm_close,
2102                 .prepare = via_dig_playback_pcm_prepare,
2103                 .cleanup = via_dig_playback_pcm_cleanup
2104         },
2105 };
2106
2107 static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
2108         .substreams = 1,
2109         .channels_min = 2,
2110         .channels_max = 2,
2111 };
2112
2113 /* fill in the dac_nids table from the parsed pin configuration */
2114 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
2115                                      const struct auto_pin_cfg *cfg)
2116 {
2117         int i;
2118         hda_nid_t nid;
2119
2120         spec->multiout.num_dacs = cfg->line_outs;
2121
2122         spec->multiout.dac_nids = spec->private_dac_nids;
2123
2124         for (i = 0; i < 4; i++) {
2125                 nid = cfg->line_out_pins[i];
2126                 if (nid) {
2127                         /* config dac list */
2128                         switch (i) {
2129                         case AUTO_SEQ_FRONT:
2130                                 spec->multiout.dac_nids[i] = 0x10;
2131                                 break;
2132                         case AUTO_SEQ_CENLFE:
2133                                 spec->multiout.dac_nids[i] = 0x24;
2134                                 break;
2135                         case AUTO_SEQ_SURROUND:
2136                                 spec->multiout.dac_nids[i] = 0x11;
2137                                 break;
2138                         case AUTO_SEQ_SIDE:
2139                                 spec->multiout.dac_nids[i] = 0x25;
2140                                 break;
2141                         }
2142                 }
2143         }
2144
2145         return 0;
2146 }
2147
2148 /* add playback controls from the parsed DAC table */
2149 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
2150                                              const struct auto_pin_cfg *cfg)
2151 {
2152         char name[32];
2153         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2154         hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
2155         hda_nid_t nid, nid_vol = 0;
2156         int i, err;
2157
2158         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2159                 nid = cfg->line_out_pins[i];
2160
2161                 if (!nid)
2162                         continue;
2163
2164                 nid_vol = nid_vols[i];
2165
2166                 if (i == AUTO_SEQ_CENLFE) {
2167                         /* Center/LFE */
2168                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2169                                               "Center Playback Volume",
2170                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2171                                                                   HDA_OUTPUT));
2172                         if (err < 0)
2173                                 return err;
2174                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2175                                               "LFE Playback Volume",
2176                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2177                                                                   HDA_OUTPUT));
2178                         if (err < 0)
2179                                 return err;
2180                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2181                                               "Center Playback Switch",
2182                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2183                                                                   HDA_OUTPUT));
2184                         if (err < 0)
2185                                 return err;
2186                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2187                                               "LFE Playback Switch",
2188                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2189                                                                   HDA_OUTPUT));
2190                         if (err < 0)
2191                                 return err;
2192                 } else if (i == AUTO_SEQ_FRONT) {
2193                         /* add control to mixer index 0 */
2194                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2195                                               "Master Front Playback Volume",
2196                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2197                                                                   HDA_INPUT));
2198                         if (err < 0)
2199                                 return err;
2200                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2201                                               "Master Front Playback Switch",
2202                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2203                                                                   HDA_INPUT));
2204                         if (err < 0)
2205                                 return err;
2206
2207                         /* add control to PW3 */
2208                         sprintf(name, "%s Playback Volume", chname[i]);
2209                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2210                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2211                                                                   HDA_OUTPUT));
2212                         if (err < 0)
2213                                 return err;
2214                         sprintf(name, "%s Playback Switch", chname[i]);
2215                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2216                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2217                                                                   HDA_OUTPUT));
2218                         if (err < 0)
2219                                 return err;
2220                 } else {
2221                         sprintf(name, "%s Playback Volume", chname[i]);
2222                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2223                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2224                                                                   HDA_OUTPUT));
2225                         if (err < 0)
2226                                 return err;
2227                         sprintf(name, "%s Playback Switch", chname[i]);
2228                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2229                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2230                                                                   HDA_OUTPUT));
2231                         if (err < 0)
2232                                 return err;
2233                 }
2234         }
2235
2236         return 0;
2237 }
2238
2239 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2240 {
2241         int err;
2242
2243         if (!pin)
2244                 return 0;
2245
2246         spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
2247
2248         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2249                               "Headphone Playback Volume",
2250                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2251         if (err < 0)
2252                 return err;
2253         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2254                               "Headphone Playback Switch",
2255                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2256         if (err < 0)
2257                 return err;
2258
2259         create_hp_imux(spec);
2260
2261         return 0;
2262 }
2263
2264 /* create playback/capture controls for input pins */
2265 static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
2266                                                 const struct auto_pin_cfg *cfg)
2267 {
2268         static char *labels[] = {
2269                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2270         };
2271         struct hda_input_mux *imux = &spec->private_imux[0];
2272         int i, err, idx = 0;
2273
2274         /* for internal loopback recording select */
2275         imux->items[imux->num_items].label = "Stereo Mixer";
2276         imux->items[imux->num_items].index = idx;
2277         imux->num_items++;
2278
2279         for (i = 0; i < AUTO_PIN_LAST; i++) {
2280                 if (!cfg->input_pins[i])
2281                         continue;
2282
2283                 switch (cfg->input_pins[i]) {
2284                 case 0x1a: /* Mic */
2285                         idx = 2;
2286                         break;
2287
2288                 case 0x1b: /* Line In */
2289                         idx = 3;
2290                         break;
2291
2292                 case 0x1e: /* Front Mic */
2293                         idx = 4;
2294                         break;
2295
2296                 case 0x1f: /* CD */
2297                         idx = 1;
2298                         break;
2299                 }
2300                 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
2301                                            idx, 0x16);
2302                 if (err < 0)
2303                         return err;
2304                 imux->items[imux->num_items].label = labels[i];
2305                 imux->items[imux->num_items].index = idx;
2306                 imux->num_items++;
2307         }
2308         return 0;
2309 }
2310
2311 static int vt1708B_parse_auto_config(struct hda_codec *codec)
2312 {
2313         struct via_spec *spec = codec->spec;
2314         int err;
2315
2316         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2317         if (err < 0)
2318                 return err;
2319         err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
2320         if (err < 0)
2321                 return err;
2322         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2323                 return 0; /* can't find valid BIOS pin config */
2324
2325         err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
2326         if (err < 0)
2327                 return err;
2328         err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2329         if (err < 0)
2330                 return err;
2331         err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
2332         if (err < 0)
2333                 return err;
2334
2335         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2336
2337         if (spec->autocfg.dig_outs)
2338                 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
2339         spec->dig_in_pin = VT1708B_DIGIN_PIN;
2340         if (spec->autocfg.dig_in_pin)
2341                 spec->dig_in_nid = VT1708B_DIGIN_NID;
2342
2343         if (spec->kctls.list)
2344                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2345
2346         spec->input_mux = &spec->private_imux[0];
2347
2348         if (spec->hp_mux)
2349                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2350
2351         return 1;
2352 }
2353
2354 #ifdef CONFIG_SND_HDA_POWER_SAVE
2355 static struct hda_amp_list vt1708B_loopbacks[] = {
2356         { 0x16, HDA_INPUT, 1 },
2357         { 0x16, HDA_INPUT, 2 },
2358         { 0x16, HDA_INPUT, 3 },
2359         { 0x16, HDA_INPUT, 4 },
2360         { } /* end */
2361 };
2362 #endif
2363
2364 static int patch_vt1708B_8ch(struct hda_codec *codec)
2365 {
2366         struct via_spec *spec;
2367         int err;
2368
2369         /* create a codec specific record */
2370         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2371         if (spec == NULL)
2372                 return -ENOMEM;
2373
2374         codec->spec = spec;
2375
2376         /* automatic parse from the BIOS config */
2377         err = vt1708B_parse_auto_config(codec);
2378         if (err < 0) {
2379                 via_free(codec);
2380                 return err;
2381         } else if (!err) {
2382                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2383                        "from BIOS.  Using genenic mode...\n");
2384         }
2385
2386         spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
2387         spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
2388
2389         spec->stream_name_analog = "VT1708B Analog";
2390         spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
2391         spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
2392