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