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