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