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