ALSA: hda - VIA: Fix codec type for VT1708BCE at the right timing
[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 VT17xx/VT18xx/VT20xx codec
5  *
6  *  (C) 2006-2009 VIA Technology, Inc.
7  *  (C) 2006-2008 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 /* 2009-02-16  Logan Li    Add support for VT1718S                           */
40 /* 2009-03-13  Logan Li    Add support for VT1716S                           */
41 /* 2009-04-14  Lydai Wang  Add support for VT1828S and VT2020                */
42 /* 2009-07-08  Lydia Wang  Add support for VT2002P                           */
43 /* 2009-07-21  Lydia Wang  Add support for VT1812                            */
44 /* 2009-09-19  Lydia Wang  Add support for VT1818S                           */
45 /*                                                                           */
46 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
47
48
49 #include <linux/init.h>
50 #include <linux/delay.h>
51 #include <linux/slab.h>
52 #include <sound/core.h>
53 #include <sound/asoundef.h>
54 #include "hda_codec.h"
55 #include "hda_local.h"
56
57 #define NID_MAPPING             (-1)
58
59 /* amp values */
60 #define AMP_VAL_IDX_SHIFT       19
61 #define AMP_VAL_IDX_MASK        (0x0f<<19)
62
63 /* Pin Widget NID */
64 #define VT1708_HP_NID           0x13
65 #define VT1708_DIGOUT_NID       0x14
66 #define VT1708_DIGIN_NID        0x16
67 #define VT1708_DIGIN_PIN        0x26
68 #define VT1708_HP_PIN_NID       0x20
69 #define VT1708_CD_PIN_NID       0x24
70
71 #define VT1709_HP_DAC_NID       0x28
72 #define VT1709_DIGOUT_NID       0x13
73 #define VT1709_DIGIN_NID        0x17
74 #define VT1709_DIGIN_PIN        0x25
75
76 #define VT1708B_HP_NID          0x25
77 #define VT1708B_DIGOUT_NID      0x12
78 #define VT1708B_DIGIN_NID       0x15
79 #define VT1708B_DIGIN_PIN       0x21
80
81 #define VT1708S_HP_NID          0x25
82 #define VT1708S_DIGOUT_NID      0x12
83
84 #define VT1702_HP_NID           0x17
85 #define VT1702_DIGOUT_NID       0x11
86
87 enum VIA_HDA_CODEC {
88         UNKNOWN = -1,
89         VT1708,
90         VT1709_10CH,
91         VT1709_6CH,
92         VT1708B_8CH,
93         VT1708B_4CH,
94         VT1708S,
95         VT1708BCE,
96         VT1702,
97         VT1718S,
98         VT1716S,
99         VT2002P,
100         VT1812,
101         CODEC_TYPES,
102 };
103
104 struct via_spec {
105         /* codec parameterization */
106         struct snd_kcontrol_new *mixers[6];
107         unsigned int num_mixers;
108
109         struct hda_verb *init_verbs[5];
110         unsigned int num_iverbs;
111
112         char *stream_name_analog;
113         struct hda_pcm_stream *stream_analog_playback;
114         struct hda_pcm_stream *stream_analog_capture;
115
116         char *stream_name_digital;
117         struct hda_pcm_stream *stream_digital_playback;
118         struct hda_pcm_stream *stream_digital_capture;
119
120         /* playback */
121         struct hda_multi_out multiout;
122         hda_nid_t slave_dig_outs[2];
123
124         /* capture */
125         unsigned int num_adc_nids;
126         hda_nid_t *adc_nids;
127         hda_nid_t mux_nids[3];
128         hda_nid_t dig_in_nid;
129         hda_nid_t dig_in_pin;
130
131         /* capture source */
132         const struct hda_input_mux *input_mux;
133         unsigned int cur_mux[3];
134
135         /* PCM information */
136         struct hda_pcm pcm_rec[3];
137
138         /* dynamic controls, init_verbs and input_mux */
139         struct auto_pin_cfg autocfg;
140         struct snd_array kctls;
141         struct hda_input_mux private_imux[2];
142         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
143
144         /* HP mode source */
145         const struct hda_input_mux *hp_mux;
146         unsigned int hp_independent_mode;
147         unsigned int hp_independent_mode_index;
148         unsigned int smart51_enabled;
149         unsigned int dmic_enabled;
150         enum VIA_HDA_CODEC codec_type;
151
152         /* work to check hp jack state */
153         struct hda_codec *codec;
154         struct delayed_work vt1708_hp_work;
155         int vt1708_jack_detectect;
156         int vt1708_hp_present;
157 #ifdef CONFIG_SND_HDA_POWER_SAVE
158         struct hda_loopback_check loopback;
159 #endif
160 };
161
162 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
163 static struct via_spec * via_new_spec(struct hda_codec *codec)
164 {
165         struct via_spec *spec;
166
167         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
168         if (spec == NULL)
169                 return NULL;
170
171         codec->spec = spec;
172         spec->codec = codec;
173         spec->codec_type = get_codec_type(codec);
174         /* VT1708BCE & VT1708S are almost same */
175         if (spec->codec_type == VT1708BCE)
176                 spec->codec_type = VT1708S;
177         return spec;
178 }
179
180 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
181 {
182         u32 vendor_id = codec->vendor_id;
183         u16 ven_id = vendor_id >> 16;
184         u16 dev_id = vendor_id & 0xffff;
185         enum VIA_HDA_CODEC codec_type;
186
187         /* get codec type */
188         if (ven_id != 0x1106)
189                 codec_type = UNKNOWN;
190         else if (dev_id >= 0x1708 && dev_id <= 0x170b)
191                 codec_type = VT1708;
192         else if (dev_id >= 0xe710 && dev_id <= 0xe713)
193                 codec_type = VT1709_10CH;
194         else if (dev_id >= 0xe714 && dev_id <= 0xe717)
195                 codec_type = VT1709_6CH;
196         else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
197                 codec_type = VT1708B_8CH;
198                 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
199                         codec_type = VT1708BCE;
200         } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
201                 codec_type = VT1708B_4CH;
202         else if ((dev_id & 0xfff) == 0x397
203                  && (dev_id >> 12) < 8)
204                 codec_type = VT1708S;
205         else if ((dev_id & 0xfff) == 0x398
206                  && (dev_id >> 12) < 8)
207                 codec_type = VT1702;
208         else if ((dev_id & 0xfff) == 0x428
209                  && (dev_id >> 12) < 8)
210                 codec_type = VT1718S;
211         else if (dev_id == 0x0433 || dev_id == 0xa721)
212                 codec_type = VT1716S;
213         else if (dev_id == 0x0441 || dev_id == 0x4441)
214                 codec_type = VT1718S;
215         else if (dev_id == 0x0438 || dev_id == 0x4438)
216                 codec_type = VT2002P;
217         else if (dev_id == 0x0448)
218                 codec_type = VT1812;
219         else if (dev_id == 0x0440)
220                 codec_type = VT1708S;
221         else
222                 codec_type = UNKNOWN;
223         return codec_type;
224 };
225
226 #define VIA_HP_EVENT            0x01
227 #define VIA_GPIO_EVENT          0x02
228 #define VIA_JACK_EVENT          0x04
229 #define VIA_MONO_EVENT          0x08
230 #define VIA_SPEAKER_EVENT       0x10
231 #define VIA_BIND_HP_EVENT       0x20
232
233 enum {
234         VIA_CTL_WIDGET_VOL,
235         VIA_CTL_WIDGET_MUTE,
236         VIA_CTL_WIDGET_ANALOG_MUTE,
237         VIA_CTL_WIDGET_BIND_PIN_MUTE,
238 };
239
240 enum {
241         AUTO_SEQ_FRONT = 0,
242         AUTO_SEQ_SURROUND,
243         AUTO_SEQ_CENLFE,
244         AUTO_SEQ_SIDE
245 };
246
247 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
248 static void set_jack_power_state(struct hda_codec *codec);
249 static int is_aa_path_mute(struct hda_codec *codec);
250
251 static void vt1708_start_hp_work(struct via_spec *spec)
252 {
253         if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
254                 return;
255         snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
256                             !spec->vt1708_jack_detectect);
257         if (!delayed_work_pending(&spec->vt1708_hp_work))
258                 schedule_delayed_work(&spec->vt1708_hp_work,
259                                       msecs_to_jiffies(100));
260 }
261
262 static void vt1708_stop_hp_work(struct via_spec *spec)
263 {
264         if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
265                 return;
266         if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
267             && !is_aa_path_mute(spec->codec))
268                 return;
269         snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
270                             !spec->vt1708_jack_detectect);
271         cancel_delayed_work_sync(&spec->vt1708_hp_work);
272 }
273
274
275 static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
276                                    struct snd_ctl_elem_value *ucontrol)
277 {
278         int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
279         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
280
281         set_jack_power_state(codec);
282         analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
283         if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
284                 if (is_aa_path_mute(codec))
285                         vt1708_start_hp_work(codec->spec);
286                 else
287                         vt1708_stop_hp_work(codec->spec);
288         }
289         return change;
290 }
291
292 /* modify .put = snd_hda_mixer_amp_switch_put */
293 #define ANALOG_INPUT_MUTE                                               \
294         {               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
295                         .name = NULL,                                   \
296                         .index = 0,                                     \
297                         .info = snd_hda_mixer_amp_switch_info,          \
298                         .get = snd_hda_mixer_amp_switch_get,            \
299                         .put = analog_input_switch_put,                 \
300                         .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
301
302 static void via_hp_bind_automute(struct hda_codec *codec);
303
304 static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
305                                struct snd_ctl_elem_value *ucontrol)
306 {
307         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
308         struct via_spec *spec = codec->spec;
309         int i;
310         int change = 0;
311
312         long *valp = ucontrol->value.integer.value;
313         int lmute, rmute;
314         if (strstr(kcontrol->id.name, "Switch") == NULL) {
315                 snd_printd("Invalid control!\n");
316                 return change;
317         }
318         change = snd_hda_mixer_amp_switch_put(kcontrol,
319                                               ucontrol);
320         /* Get mute value */
321         lmute = *valp ? 0 : HDA_AMP_MUTE;
322         valp++;
323         rmute = *valp ? 0 : HDA_AMP_MUTE;
324
325         /* Set hp pins */
326         if (!spec->hp_independent_mode) {
327                 for (i = 0; i < spec->autocfg.hp_outs; i++) {
328                         snd_hda_codec_amp_update(
329                                 codec, spec->autocfg.hp_pins[i],
330                                 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
331                                 lmute);
332                         snd_hda_codec_amp_update(
333                                 codec, spec->autocfg.hp_pins[i],
334                                 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
335                                 rmute);
336                 }
337         }
338
339         if (!lmute && !rmute) {
340                 /* Line Outs */
341                 for (i = 0; i < spec->autocfg.line_outs; i++)
342                         snd_hda_codec_amp_stereo(
343                                 codec, spec->autocfg.line_out_pins[i],
344                                 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
345                 /* Speakers */
346                 for (i = 0; i < spec->autocfg.speaker_outs; i++)
347                         snd_hda_codec_amp_stereo(
348                                 codec, spec->autocfg.speaker_pins[i],
349                                 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
350                 /* unmute */
351                 via_hp_bind_automute(codec);
352
353         } else {
354                 if (lmute) {
355                         /* Mute all left channels */
356                         for (i = 1; i < spec->autocfg.line_outs; i++)
357                                 snd_hda_codec_amp_update(
358                                         codec,
359                                         spec->autocfg.line_out_pins[i],
360                                         0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
361                                         lmute);
362                         for (i = 0; i < spec->autocfg.speaker_outs; i++)
363                                 snd_hda_codec_amp_update(
364                                         codec,
365                                         spec->autocfg.speaker_pins[i],
366                                         0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
367                                         lmute);
368                 }
369                 if (rmute) {
370                         /* mute all right channels */
371                         for (i = 1; i < spec->autocfg.line_outs; i++)
372                                 snd_hda_codec_amp_update(
373                                         codec,
374                                         spec->autocfg.line_out_pins[i],
375                                         1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
376                                         rmute);
377                         for (i = 0; i < spec->autocfg.speaker_outs; i++)
378                                 snd_hda_codec_amp_update(
379                                         codec,
380                                         spec->autocfg.speaker_pins[i],
381                                         1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
382                                         rmute);
383                 }
384         }
385         return change;
386 }
387
388 #define BIND_PIN_MUTE                                                   \
389         {               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
390                         .name = NULL,                                   \
391                         .index = 0,                                     \
392                         .info = snd_hda_mixer_amp_switch_info,          \
393                         .get = snd_hda_mixer_amp_switch_get,            \
394                         .put = bind_pin_switch_put,                     \
395                         .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
396
397 static struct snd_kcontrol_new via_control_templates[] = {
398         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
399         HDA_CODEC_MUTE(NULL, 0, 0, 0),
400         ANALOG_INPUT_MUTE,
401         BIND_PIN_MUTE,
402 };
403
404 static hda_nid_t vt1708_adc_nids[2] = {
405         /* ADC1-2 */
406         0x15, 0x27
407 };
408
409 static hda_nid_t vt1709_adc_nids[3] = {
410         /* ADC1-2 */
411         0x14, 0x15, 0x16
412 };
413
414 static hda_nid_t vt1708B_adc_nids[2] = {
415         /* ADC1-2 */
416         0x13, 0x14
417 };
418
419 static hda_nid_t vt1708S_adc_nids[2] = {
420         /* ADC1-2 */
421         0x13, 0x14
422 };
423
424 static hda_nid_t vt1702_adc_nids[3] = {
425         /* ADC1-2 */
426         0x12, 0x20, 0x1F
427 };
428
429 static hda_nid_t vt1718S_adc_nids[2] = {
430         /* ADC1-2 */
431         0x10, 0x11
432 };
433
434 static hda_nid_t vt1716S_adc_nids[2] = {
435         /* ADC1-2 */
436         0x13, 0x14
437 };
438
439 static hda_nid_t vt2002P_adc_nids[2] = {
440         /* ADC1-2 */
441         0x10, 0x11
442 };
443
444 static hda_nid_t vt1812_adc_nids[2] = {
445         /* ADC1-2 */
446         0x10, 0x11
447 };
448
449
450 /* add dynamic controls */
451 static int __via_add_control(struct via_spec *spec, int type, const char *name,
452                              int idx, unsigned long val)
453 {
454         struct snd_kcontrol_new *knew;
455
456         snd_array_init(&spec->kctls, sizeof(*knew), 32);
457         knew = snd_array_new(&spec->kctls);
458         if (!knew)
459                 return -ENOMEM;
460         *knew = via_control_templates[type];
461         knew->name = kstrdup(name, GFP_KERNEL);
462         if (!knew->name)
463                 return -ENOMEM;
464         if (get_amp_nid_(val))
465                 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
466         knew->private_value = val;
467         return 0;
468 }
469
470 #define via_add_control(spec, type, name, val) \
471         __via_add_control(spec, type, name, 0, val)
472
473 static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
474                                                 struct snd_kcontrol_new *tmpl)
475 {
476         struct snd_kcontrol_new *knew;
477
478         snd_array_init(&spec->kctls, sizeof(*knew), 32);
479         knew = snd_array_new(&spec->kctls);
480         if (!knew)
481                 return NULL;
482         *knew = *tmpl;
483         knew->name = kstrdup(tmpl->name, GFP_KERNEL);
484         if (!knew->name)
485                 return NULL;
486         return knew;
487 }
488
489 static void via_free_kctls(struct hda_codec *codec)
490 {
491         struct via_spec *spec = codec->spec;
492
493         if (spec->kctls.list) {
494                 struct snd_kcontrol_new *kctl = spec->kctls.list;
495                 int i;
496                 for (i = 0; i < spec->kctls.used; i++)
497                         kfree(kctl[i].name);
498         }
499         snd_array_free(&spec->kctls);
500 }
501
502 /* create input playback/capture controls for the given pin */
503 static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
504                                 int type_idx, int idx, int mix_nid)
505 {
506         char name[32];
507         int err;
508
509         sprintf(name, "%s Playback Volume", ctlname);
510         err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
511                               HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
512         if (err < 0)
513                 return err;
514         sprintf(name, "%s Playback Switch", ctlname);
515         err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
516                               HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
517         if (err < 0)
518                 return err;
519         return 0;
520 }
521
522 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
523                                            hda_nid_t nid, int pin_type,
524                                            int dac_idx)
525 {
526         /* set as output */
527         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
528                             pin_type);
529         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
530                             AMP_OUT_UNMUTE);
531         if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
532                 snd_hda_codec_write(codec, nid, 0,
533                                     AC_VERB_SET_EAPD_BTLENABLE, 0x02);
534 }
535
536
537 static void via_auto_init_multi_out(struct hda_codec *codec)
538 {
539         struct via_spec *spec = codec->spec;
540         int i;
541
542         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
543                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
544                 if (nid)
545                         via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
546         }
547 }
548
549 static void via_auto_init_hp_out(struct hda_codec *codec)
550 {
551         struct via_spec *spec = codec->spec;
552         hda_nid_t pin;
553         int i;
554
555         for (i = 0; i < spec->autocfg.hp_outs; i++) {
556                 pin = spec->autocfg.hp_pins[i];
557                 if (pin) /* connect to front */
558                         via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
559         }
560 }
561
562 static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
563
564 static void via_auto_init_analog_input(struct hda_codec *codec)
565 {
566         struct via_spec *spec = codec->spec;
567         const struct auto_pin_cfg *cfg = &spec->autocfg;
568         unsigned int ctl;
569         int i;
570
571         for (i = 0; i < cfg->num_inputs; i++) {
572                 hda_nid_t nid = cfg->inputs[i].pin;
573                 if (spec->smart51_enabled && is_smart51_pins(spec, nid))
574                         ctl = PIN_OUT;
575                 else if (cfg->inputs[i].type == AUTO_PIN_MIC)
576                         ctl = PIN_VREF50;
577                 else
578                         ctl = PIN_IN;
579                 snd_hda_codec_write(codec, nid, 0,
580                                     AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
581         }
582 }
583
584 static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
585                                 unsigned int *affected_parm)
586 {
587         unsigned parm;
588         unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
589         unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
590                 >> AC_DEFCFG_MISC_SHIFT
591                 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
592         unsigned present = snd_hda_jack_detect(codec, nid);
593         struct via_spec *spec = codec->spec;
594         if ((spec->smart51_enabled && is_smart51_pins(spec, nid))
595             || ((no_presence || present)
596                 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
597                 *affected_parm = AC_PWRST_D0; /* if it's connected */
598                 parm = AC_PWRST_D0;
599         } else
600                 parm = AC_PWRST_D3;
601
602         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
603 }
604
605 static void set_jack_power_state(struct hda_codec *codec)
606 {
607         struct via_spec *spec = codec->spec;
608         int imux_is_smixer;
609         unsigned int parm;
610
611         if (spec->codec_type == VT1702) {
612                 imux_is_smixer = snd_hda_codec_read(
613                         codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
614                 /* inputs */
615                 /* PW 1/2/5 (14h/15h/18h) */
616                 parm = AC_PWRST_D3;
617                 set_pin_power_state(codec, 0x14, &parm);
618                 set_pin_power_state(codec, 0x15, &parm);
619                 set_pin_power_state(codec, 0x18, &parm);
620                 if (imux_is_smixer)
621                         parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
622                 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
623                 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
624                                     parm);
625                 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
626                                     parm);
627                 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
628                                     parm);
629                 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
630                                     parm);
631
632                 /* outputs */
633                 /* PW 3/4 (16h/17h) */
634                 parm = AC_PWRST_D3;
635                 set_pin_power_state(codec, 0x16, &parm);
636                 set_pin_power_state(codec, 0x17, &parm);
637                 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
638                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
639                                     imux_is_smixer ? AC_PWRST_D0 : parm);
640                 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
641                                     parm);
642                 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
643                                     parm);
644         } else if (spec->codec_type == VT1708B_8CH
645                    || spec->codec_type == VT1708B_4CH
646                    || spec->codec_type == VT1708S) {
647                 /* SW0 (17h) = stereo mixer */
648                 int is_8ch = spec->codec_type != VT1708B_4CH;
649                 imux_is_smixer = snd_hda_codec_read(
650                         codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
651                         == ((spec->codec_type == VT1708S)  ? 5 : 0);
652                 /* inputs */
653                 /* PW 1/2/5 (1ah/1bh/1eh) */
654                 parm = AC_PWRST_D3;
655                 set_pin_power_state(codec, 0x1a, &parm);
656                 set_pin_power_state(codec, 0x1b, &parm);
657                 set_pin_power_state(codec, 0x1e, &parm);
658                 if (imux_is_smixer)
659                         parm = AC_PWRST_D0;
660                 /* SW0 (17h), AIW 0/1 (13h/14h) */
661                 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
662                                     parm);
663                 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
664                                     parm);
665                 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
666                                     parm);
667
668                 /* outputs */
669                 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
670                 parm = AC_PWRST_D3;
671                 set_pin_power_state(codec, 0x19, &parm);
672                 if (spec->smart51_enabled)
673                         parm = AC_PWRST_D0;
674                 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
675                                     parm);
676                 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
677                                     parm);
678
679                 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
680                 if (is_8ch) {
681                         parm = AC_PWRST_D3;
682                         set_pin_power_state(codec, 0x22, &parm);
683                         if (spec->smart51_enabled)
684                                 parm = AC_PWRST_D0;
685                         snd_hda_codec_write(codec, 0x26, 0,
686                                             AC_VERB_SET_POWER_STATE, parm);
687                         snd_hda_codec_write(codec, 0x24, 0,
688                                             AC_VERB_SET_POWER_STATE, parm);
689                 }
690
691                 /* PW 3/4/7 (1ch/1dh/23h) */
692                 parm = AC_PWRST_D3;
693                 /* force to D0 for internal Speaker */
694                 set_pin_power_state(codec, 0x1c, &parm);
695                 set_pin_power_state(codec, 0x1d, &parm);
696                 if (is_8ch)
697                         set_pin_power_state(codec, 0x23, &parm);
698                 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
699                 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
700                                     imux_is_smixer ? AC_PWRST_D0 : parm);
701                 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
702                                     parm);
703                 if (is_8ch) {
704                         snd_hda_codec_write(codec, 0x25, 0,
705                                             AC_VERB_SET_POWER_STATE, parm);
706                         snd_hda_codec_write(codec, 0x27, 0,
707                                             AC_VERB_SET_POWER_STATE, parm);
708                 }
709         }  else if (spec->codec_type == VT1718S) {
710                 /* MUX6 (1eh) = stereo mixer */
711                 imux_is_smixer = snd_hda_codec_read(
712                         codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
713                 /* inputs */
714                 /* PW 5/6/7 (29h/2ah/2bh) */
715                 parm = AC_PWRST_D3;
716                 set_pin_power_state(codec, 0x29, &parm);
717                 set_pin_power_state(codec, 0x2a, &parm);
718                 set_pin_power_state(codec, 0x2b, &parm);
719                 if (imux_is_smixer)
720                         parm = AC_PWRST_D0;
721                 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
722                 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
723                                     parm);
724                 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
725                                     parm);
726                 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
727                                     parm);
728                 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
729                                     parm);
730
731                 /* outputs */
732                 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
733                 parm = AC_PWRST_D3;
734                 set_pin_power_state(codec, 0x27, &parm);
735                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
736                                     parm);
737                 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
738                                     parm);
739
740                 /* PW2 (26h), AOW2 (ah) */
741                 parm = AC_PWRST_D3;
742                 set_pin_power_state(codec, 0x26, &parm);
743                 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
744                                     parm);
745
746                 /* PW0/1 (24h/25h) */
747                 parm = AC_PWRST_D3;
748                 set_pin_power_state(codec, 0x24, &parm);
749                 set_pin_power_state(codec, 0x25, &parm);
750                 if (!spec->hp_independent_mode) /* check for redirected HP */
751                         set_pin_power_state(codec, 0x28, &parm);
752                 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
753                                     parm);
754                 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
755                                     parm);
756                 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
757                 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
758                                     imux_is_smixer ? AC_PWRST_D0 : parm);
759                 if (spec->hp_independent_mode) {
760                         /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
761                         parm = AC_PWRST_D3;
762                         set_pin_power_state(codec, 0x28, &parm);
763                         snd_hda_codec_write(codec, 0x1b, 0,
764                                             AC_VERB_SET_POWER_STATE, parm);
765                         snd_hda_codec_write(codec, 0x34, 0,
766                                             AC_VERB_SET_POWER_STATE, parm);
767                         snd_hda_codec_write(codec, 0xc, 0,
768                                             AC_VERB_SET_POWER_STATE, parm);
769                 }
770         } else if (spec->codec_type == VT1716S) {
771                 unsigned int mono_out, present;
772                 /* SW0 (17h) = stereo mixer */
773                 imux_is_smixer = snd_hda_codec_read(
774                         codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) ==  5;
775                 /* inputs */
776                 /* PW 1/2/5 (1ah/1bh/1eh) */
777                 parm = AC_PWRST_D3;
778                 set_pin_power_state(codec, 0x1a, &parm);
779                 set_pin_power_state(codec, 0x1b, &parm);
780                 set_pin_power_state(codec, 0x1e, &parm);
781                 if (imux_is_smixer)
782                         parm = AC_PWRST_D0;
783                 /* SW0 (17h), AIW0(13h) */
784                 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
785                                     parm);
786                 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
787                                     parm);
788
789                 parm = AC_PWRST_D3;
790                 set_pin_power_state(codec, 0x1e, &parm);
791                 /* PW11 (22h) */
792                 if (spec->dmic_enabled)
793                         set_pin_power_state(codec, 0x22, &parm);
794                 else
795                         snd_hda_codec_write(
796                                 codec, 0x22, 0,
797                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
798
799                 /* SW2(26h), AIW1(14h) */
800                 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
801                                     parm);
802                 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
803                                     parm);
804
805                 /* outputs */
806                 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
807                 parm = AC_PWRST_D3;
808                 set_pin_power_state(codec, 0x19, &parm);
809                 /* Smart 5.1 PW2(1bh) */
810                 if (spec->smart51_enabled)
811                         set_pin_power_state(codec, 0x1b, &parm);
812                 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
813                                     parm);
814                 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
815                                     parm);
816
817                 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
818                 parm = AC_PWRST_D3;
819                 set_pin_power_state(codec, 0x23, &parm);
820                 /* Smart 5.1 PW1(1ah) */
821                 if (spec->smart51_enabled)
822                         set_pin_power_state(codec, 0x1a, &parm);
823                 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
824                                     parm);
825
826                 /* Smart 5.1 PW5(1eh) */
827                 if (spec->smart51_enabled)
828                         set_pin_power_state(codec, 0x1e, &parm);
829                 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
830                                     parm);
831
832                 /* Mono out */
833                 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
834                 present = snd_hda_jack_detect(codec, 0x1c);
835                 if (present)
836                         mono_out = 0;
837                 else {
838                         present = snd_hda_jack_detect(codec, 0x1d);
839                         if (!spec->hp_independent_mode && present)
840                                 mono_out = 0;
841                         else
842                                 mono_out = 1;
843                 }
844                 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
845                 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
846                                     parm);
847                 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
848                                     parm);
849                 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
850                                     parm);
851
852                 /* PW 3/4 (1ch/1dh) */
853                 parm = AC_PWRST_D3;
854                 set_pin_power_state(codec, 0x1c, &parm);
855                 set_pin_power_state(codec, 0x1d, &parm);
856                 /* HP Independent Mode, power on AOW3 */
857                 if (spec->hp_independent_mode)
858                         snd_hda_codec_write(codec, 0x25, 0,
859                                             AC_VERB_SET_POWER_STATE, parm);
860
861                 /* force to D0 for internal Speaker */
862                 /* MW0 (16h), AOW0 (10h) */
863                 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
864                                     imux_is_smixer ? AC_PWRST_D0 : parm);
865                 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
866                                     mono_out ? AC_PWRST_D0 : parm);
867         } else if (spec->codec_type == VT2002P) {
868                 unsigned int present;
869                 /* MUX9 (1eh) = stereo mixer */
870                 imux_is_smixer = snd_hda_codec_read(
871                         codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
872                 /* inputs */
873                 /* PW 5/6/7 (29h/2ah/2bh) */
874                 parm = AC_PWRST_D3;
875                 set_pin_power_state(codec, 0x29, &parm);
876                 set_pin_power_state(codec, 0x2a, &parm);
877                 set_pin_power_state(codec, 0x2b, &parm);
878                 if (imux_is_smixer)
879                         parm = AC_PWRST_D0;
880                 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
881                 snd_hda_codec_write(codec, 0x1e, 0,
882                                     AC_VERB_SET_POWER_STATE, parm);
883                 snd_hda_codec_write(codec, 0x1f, 0,
884                                     AC_VERB_SET_POWER_STATE, parm);
885                 snd_hda_codec_write(codec, 0x10, 0,
886                                     AC_VERB_SET_POWER_STATE, parm);
887                 snd_hda_codec_write(codec, 0x11, 0,
888                                     AC_VERB_SET_POWER_STATE, parm);
889
890                 /* outputs */
891                 /* AOW0 (8h)*/
892                 snd_hda_codec_write(codec, 0x8, 0,
893                                     AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
894
895                 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
896                 parm = AC_PWRST_D3;
897                 set_pin_power_state(codec, 0x26, &parm);
898                 snd_hda_codec_write(codec, 0x1c, 0,
899                                     AC_VERB_SET_POWER_STATE, parm);
900                 snd_hda_codec_write(codec, 0x37,
901                                     0, AC_VERB_SET_POWER_STATE, parm);
902
903                 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
904                 parm = AC_PWRST_D3;
905                 set_pin_power_state(codec, 0x25, &parm);
906                 snd_hda_codec_write(codec, 0x19, 0,
907                                     AC_VERB_SET_POWER_STATE, parm);
908                 snd_hda_codec_write(codec, 0x35, 0,
909                                     AC_VERB_SET_POWER_STATE, parm);
910                 if (spec->hp_independent_mode)  {
911                         snd_hda_codec_write(codec, 0x9, 0,
912                                             AC_VERB_SET_POWER_STATE, parm);
913                 }
914
915                 /* Class-D */
916                 /* PW0 (24h), MW0(18h), MUX0(34h) */
917                 present = snd_hda_jack_detect(codec, 0x25);
918                 parm = AC_PWRST_D3;
919                 set_pin_power_state(codec, 0x24, &parm);
920                 if (present) {
921                         snd_hda_codec_write(
922                                 codec, 0x18, 0,
923                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
924                         snd_hda_codec_write(
925                                 codec, 0x34, 0,
926                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
927                 } else {
928                         snd_hda_codec_write(
929                                 codec, 0x18, 0,
930                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
931                         snd_hda_codec_write(
932                                 codec, 0x34, 0,
933                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
934                 }
935
936                 /* Mono Out */
937                 /* PW15 (31h), MW8(17h), MUX8(3bh) */
938                 present = snd_hda_jack_detect(codec, 0x26);
939                 parm = AC_PWRST_D3;
940                 set_pin_power_state(codec, 0x31, &parm);
941                 if (present) {
942                         snd_hda_codec_write(
943                                 codec, 0x17, 0,
944                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
945                         snd_hda_codec_write(
946                                 codec, 0x3b, 0,
947                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
948                 } else {
949                         snd_hda_codec_write(
950                                 codec, 0x17, 0,
951                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
952                         snd_hda_codec_write(
953                                 codec, 0x3b, 0,
954                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
955                 }
956
957                 /* MW9 (21h) */
958                 if (imux_is_smixer || !is_aa_path_mute(codec))
959                         snd_hda_codec_write(
960                                 codec, 0x21, 0,
961                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
962                 else
963                         snd_hda_codec_write(
964                                 codec, 0x21, 0,
965                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
966         } else if (spec->codec_type == VT1812) {
967                 unsigned int present;
968                 /* MUX10 (1eh) = stereo mixer */
969                 imux_is_smixer = snd_hda_codec_read(
970                         codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
971                 /* inputs */
972                 /* PW 5/6/7 (29h/2ah/2bh) */
973                 parm = AC_PWRST_D3;
974                 set_pin_power_state(codec, 0x29, &parm);
975                 set_pin_power_state(codec, 0x2a, &parm);
976                 set_pin_power_state(codec, 0x2b, &parm);
977                 if (imux_is_smixer)
978                         parm = AC_PWRST_D0;
979                 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
980                 snd_hda_codec_write(codec, 0x1e, 0,
981                                     AC_VERB_SET_POWER_STATE, parm);
982                 snd_hda_codec_write(codec, 0x1f, 0,
983                                     AC_VERB_SET_POWER_STATE, parm);
984                 snd_hda_codec_write(codec, 0x10, 0,
985                                     AC_VERB_SET_POWER_STATE, parm);
986                 snd_hda_codec_write(codec, 0x11, 0,
987                                     AC_VERB_SET_POWER_STATE, parm);
988
989                 /* outputs */
990                 /* AOW0 (8h)*/
991                 snd_hda_codec_write(codec, 0x8, 0,
992                                     AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
993
994                 /* PW4 (28h), MW4 (18h), MUX4(38h) */
995                 parm = AC_PWRST_D3;
996                 set_pin_power_state(codec, 0x28, &parm);
997                 snd_hda_codec_write(codec, 0x18, 0,
998                                     AC_VERB_SET_POWER_STATE, parm);
999                 snd_hda_codec_write(codec, 0x38, 0,
1000                                     AC_VERB_SET_POWER_STATE, parm);
1001
1002                 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
1003                 parm = AC_PWRST_D3;
1004                 set_pin_power_state(codec, 0x25, &parm);
1005                 snd_hda_codec_write(codec, 0x15, 0,
1006                                     AC_VERB_SET_POWER_STATE, parm);
1007                 snd_hda_codec_write(codec, 0x35, 0,
1008                                     AC_VERB_SET_POWER_STATE, parm);
1009                 if (spec->hp_independent_mode)  {
1010                         snd_hda_codec_write(codec, 0x9, 0,
1011                                             AC_VERB_SET_POWER_STATE, parm);
1012                 }
1013
1014                 /* Internal Speaker */
1015                 /* PW0 (24h), MW0(14h), MUX0(34h) */
1016                 present = snd_hda_jack_detect(codec, 0x25);
1017                 parm = AC_PWRST_D3;
1018                 set_pin_power_state(codec, 0x24, &parm);
1019                 if (present) {
1020                         snd_hda_codec_write(codec, 0x14, 0,
1021                                             AC_VERB_SET_POWER_STATE,
1022                                             AC_PWRST_D3);
1023                         snd_hda_codec_write(codec, 0x34, 0,
1024                                             AC_VERB_SET_POWER_STATE,
1025                                             AC_PWRST_D3);
1026                 } else {
1027                         snd_hda_codec_write(codec, 0x14, 0,
1028                                             AC_VERB_SET_POWER_STATE,
1029                                             AC_PWRST_D0);
1030                         snd_hda_codec_write(codec, 0x34, 0,
1031                                             AC_VERB_SET_POWER_STATE,
1032                                             AC_PWRST_D0);
1033                 }
1034                 /* Mono Out */
1035                 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1036                 present = snd_hda_jack_detect(codec, 0x28);
1037                 parm = AC_PWRST_D3;
1038                 set_pin_power_state(codec, 0x31, &parm);
1039                 if (present) {
1040                         snd_hda_codec_write(codec, 0x1c, 0,
1041                                             AC_VERB_SET_POWER_STATE,
1042                                             AC_PWRST_D3);
1043                         snd_hda_codec_write(codec, 0x3c, 0,
1044                                             AC_VERB_SET_POWER_STATE,
1045                                             AC_PWRST_D3);
1046                         snd_hda_codec_write(codec, 0x3e, 0,
1047                                             AC_VERB_SET_POWER_STATE,
1048                                             AC_PWRST_D3);
1049                 } else {
1050                         snd_hda_codec_write(codec, 0x1c, 0,
1051                                             AC_VERB_SET_POWER_STATE,
1052                                             AC_PWRST_D0);
1053                         snd_hda_codec_write(codec, 0x3c, 0,
1054                                             AC_VERB_SET_POWER_STATE,
1055                                             AC_PWRST_D0);
1056                         snd_hda_codec_write(codec, 0x3e, 0,
1057                                             AC_VERB_SET_POWER_STATE,
1058                                             AC_PWRST_D0);
1059                 }
1060
1061                 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1062                 parm = AC_PWRST_D3;
1063                 set_pin_power_state(codec, 0x33, &parm);
1064                 snd_hda_codec_write(codec, 0x1d, 0,
1065                                     AC_VERB_SET_POWER_STATE, parm);
1066                 snd_hda_codec_write(codec, 0x3d, 0,
1067                                     AC_VERB_SET_POWER_STATE, parm);
1068
1069                 /* MW9 (21h) */
1070                 if (imux_is_smixer || !is_aa_path_mute(codec))
1071                         snd_hda_codec_write(
1072                                 codec, 0x21, 0,
1073                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1074                 else
1075                         snd_hda_codec_write(
1076                                 codec, 0x21, 0,
1077                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1078         }
1079 }
1080
1081 /*
1082  * input MUX handling
1083  */
1084 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
1085                              struct snd_ctl_elem_info *uinfo)
1086 {
1087         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1088         struct via_spec *spec = codec->spec;
1089         return snd_hda_input_mux_info(spec->input_mux, uinfo);
1090 }
1091
1092 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
1093                             struct snd_ctl_elem_value *ucontrol)
1094 {
1095         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1096         struct via_spec *spec = codec->spec;
1097         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1098
1099         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
1100         return 0;
1101 }
1102
1103 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1104                             struct snd_ctl_elem_value *ucontrol)
1105 {
1106         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1107         struct via_spec *spec = codec->spec;
1108         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1109         int ret;
1110
1111         if (!spec->mux_nids[adc_idx])
1112                 return -EINVAL;
1113         /* switch to D0 beofre change index */
1114         if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
1115                                AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
1116                 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
1117                                     AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1118
1119         ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
1120                                      spec->mux_nids[adc_idx],
1121                                      &spec->cur_mux[adc_idx]);
1122         /* update jack power state */
1123         set_jack_power_state(codec);
1124
1125         return ret;
1126 }
1127
1128 static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
1129                                    struct snd_ctl_elem_info *uinfo)
1130 {
1131         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1132         struct via_spec *spec = codec->spec;
1133         return snd_hda_input_mux_info(spec->hp_mux, uinfo);
1134 }
1135
1136 static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1137                                   struct snd_ctl_elem_value *ucontrol)
1138 {
1139         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1140         hda_nid_t nid = kcontrol->private_value;
1141         unsigned int pinsel;
1142
1143         /* use !! to translate conn sel 2 for VT1718S */
1144         pinsel = !!snd_hda_codec_read(codec, nid, 0,
1145                                       AC_VERB_GET_CONNECT_SEL,
1146                                       0x00);
1147         ucontrol->value.enumerated.item[0] = pinsel;
1148
1149         return 0;
1150 }
1151
1152 static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1153 {
1154         struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
1155         if (ctl) {
1156                 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1157                 ctl->vd[0].access |= active
1158                         ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1159                 snd_ctl_notify(codec->bus->card,
1160                                SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
1161         }
1162 }
1163
1164 static hda_nid_t side_mute_channel(struct via_spec *spec)
1165 {
1166         switch (spec->codec_type) {
1167         case VT1708:            return 0x1b;
1168         case VT1709_10CH:       return 0x29;
1169         case VT1708B_8CH:       /* fall thru */
1170         case VT1708S:           return 0x27;
1171         default:                return 0;
1172         }
1173 }
1174
1175 static int update_side_mute_status(struct hda_codec *codec)
1176 {
1177         /* mute side channel */
1178         struct via_spec *spec = codec->spec;
1179         unsigned int parm = spec->hp_independent_mode
1180                 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1181         hda_nid_t sw3 = side_mute_channel(spec);
1182
1183         if (sw3)
1184                 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1185                                     parm);
1186         return 0;
1187 }
1188
1189 static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1190                                   struct snd_ctl_elem_value *ucontrol)
1191 {
1192         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1193         struct via_spec *spec = codec->spec;
1194         hda_nid_t nid = kcontrol->private_value;
1195         unsigned int pinsel = ucontrol->value.enumerated.item[0];
1196         /* Get Independent Mode index of headphone pin widget */
1197         spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1198                 ? 1 : 0;
1199         if (spec->codec_type == VT1718S)
1200                 snd_hda_codec_write(codec, nid, 0,
1201                                     AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
1202         else
1203                 snd_hda_codec_write(codec, nid, 0,
1204                                     AC_VERB_SET_CONNECT_SEL, pinsel);
1205
1206         if (spec->codec_type == VT1812)
1207                 snd_hda_codec_write(codec, 0x35, 0,
1208                                     AC_VERB_SET_CONNECT_SEL, pinsel);
1209         if (spec->multiout.hp_nid && spec->multiout.hp_nid
1210             != spec->multiout.dac_nids[HDA_FRONT])
1211                 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
1212                                            0, 0, 0);
1213
1214         update_side_mute_status(codec);
1215         /* update HP volume/swtich active state */
1216         if (spec->codec_type == VT1708S
1217             || spec->codec_type == VT1702
1218             || spec->codec_type == VT1718S
1219             || spec->codec_type == VT1716S
1220             || spec->codec_type == VT2002P
1221             || spec->codec_type == VT1812) {
1222                 activate_ctl(codec, "Headphone Playback Volume",
1223                              spec->hp_independent_mode);
1224                 activate_ctl(codec, "Headphone Playback Switch",
1225                              spec->hp_independent_mode);
1226         }
1227         /* update jack power state */
1228         set_jack_power_state(codec);
1229         return 0;
1230 }
1231
1232 static struct snd_kcontrol_new via_hp_mixer[2] = {
1233         {
1234                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1235                 .name = "Independent HP",
1236                 .info = via_independent_hp_info,
1237                 .get = via_independent_hp_get,
1238                 .put = via_independent_hp_put,
1239         },
1240         {
1241                 .iface = NID_MAPPING,
1242                 .name = "Independent HP",
1243         },
1244 };
1245
1246 static int via_hp_build(struct hda_codec *codec)
1247 {
1248         struct via_spec *spec = codec->spec;
1249         struct snd_kcontrol_new *knew;
1250         hda_nid_t nid;
1251         int nums;
1252         hda_nid_t conn[HDA_MAX_CONNECTIONS];
1253
1254         switch (spec->codec_type) {
1255         case VT1718S:
1256                 nid = 0x34;
1257                 break;
1258         case VT2002P:
1259                 nid = 0x35;
1260                 break;
1261         case VT1812:
1262                 nid = 0x3d;
1263                 break;
1264         default:
1265                 nid = spec->autocfg.hp_pins[0];
1266                 break;
1267         }
1268
1269         nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
1270         if (nums <= 1)
1271                 return 0;
1272
1273         knew = via_clone_control(spec, &via_hp_mixer[0]);
1274         if (knew == NULL)
1275                 return -ENOMEM;
1276
1277         knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1278         knew->private_value = nid;
1279
1280         knew = via_clone_control(spec, &via_hp_mixer[1]);
1281         if (knew == NULL)
1282                 return -ENOMEM;
1283         knew->subdevice = side_mute_channel(spec);
1284
1285         return 0;
1286 }
1287
1288 static void notify_aa_path_ctls(struct hda_codec *codec)
1289 {
1290         int i;
1291         struct snd_ctl_elem_id id;
1292         const char *labels[] = {"Mic", "Front Mic", "Line"};
1293
1294         memset(&id, 0, sizeof(id));
1295         id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1296         for (i = 0; i < ARRAY_SIZE(labels); i++) {
1297                 sprintf(id.name, "%s Playback Volume", labels[i]);
1298                 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1299                                &id);
1300         }
1301 }
1302
1303 static void mute_aa_path(struct hda_codec *codec, int mute)
1304 {
1305         struct via_spec *spec = codec->spec;
1306         hda_nid_t  nid_mixer;
1307         int start_idx;
1308         int end_idx;
1309         int i;
1310         /* get nid of MW0 and start & end index */
1311         switch (spec->codec_type) {
1312         case VT1708:
1313                 nid_mixer = 0x17;
1314                 start_idx = 2;
1315                 end_idx = 4;
1316                 break;
1317         case VT1709_10CH:
1318         case VT1709_6CH:
1319                 nid_mixer = 0x18;
1320                 start_idx = 2;
1321                 end_idx = 4;
1322                 break;
1323         case VT1708B_8CH:
1324         case VT1708B_4CH:
1325         case VT1708S:
1326         case VT1716S:
1327                 nid_mixer = 0x16;
1328                 start_idx = 2;
1329                 end_idx = 4;
1330                 break;
1331         case VT1718S:
1332                 nid_mixer = 0x21;
1333                 start_idx = 1;
1334                 end_idx = 3;
1335                 break;
1336         default:
1337                 return;
1338         }
1339         /* check AA path's mute status */
1340         for (i = start_idx; i <= end_idx; i++) {
1341                 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
1342                 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i,
1343                                          HDA_AMP_MUTE, val);
1344         }
1345 }
1346 static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1347 {
1348         const struct auto_pin_cfg *cfg = &spec->autocfg;
1349         int i;
1350
1351         for (i = 0; i < cfg->num_inputs; i++) {
1352                 if (pin == cfg->inputs[i].pin)
1353                         return cfg->inputs[i].type <= AUTO_PIN_LINE_IN;
1354         }
1355         return 0;
1356 }
1357
1358 static int via_smart51_info(struct snd_kcontrol *kcontrol,
1359                             struct snd_ctl_elem_info *uinfo)
1360 {
1361         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1362         uinfo->count = 1;
1363         uinfo->value.integer.min = 0;
1364         uinfo->value.integer.max = 1;
1365         return 0;
1366 }
1367
1368 static int via_smart51_get(struct snd_kcontrol *kcontrol,
1369                            struct snd_ctl_elem_value *ucontrol)
1370 {
1371         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1372         struct via_spec *spec = codec->spec;
1373         const struct auto_pin_cfg *cfg = &spec->autocfg;
1374         int on = 1;
1375         int i;
1376
1377         for (i = 0; i < cfg->num_inputs; i++) {
1378                 hda_nid_t nid = cfg->inputs[i].pin;
1379                 int ctl = snd_hda_codec_read(codec, nid, 0,
1380                                              AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1381                 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1382                         continue;
1383                 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1384                     spec->hp_independent_mode && spec->codec_type != VT1718S)
1385                         continue; /* ignore FMic for independent HP */
1386                 if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
1387                         on = 0;
1388         }
1389         *ucontrol->value.integer.value = on;
1390         return 0;
1391 }
1392
1393 static int via_smart51_put(struct snd_kcontrol *kcontrol,
1394                            struct snd_ctl_elem_value *ucontrol)
1395 {
1396         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1397         struct via_spec *spec = codec->spec;
1398         const struct auto_pin_cfg *cfg = &spec->autocfg;
1399         int out_in = *ucontrol->value.integer.value
1400                 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1401         int i;
1402
1403         for (i = 0; i < cfg->num_inputs; i++) {
1404                 hda_nid_t nid = cfg->inputs[i].pin;
1405                 unsigned int parm;
1406
1407                 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1408                         continue;
1409                 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1410                     spec->hp_independent_mode && spec->codec_type != VT1718S)
1411                         continue; /* don't retask FMic for independent HP */
1412
1413                 parm = snd_hda_codec_read(codec, nid, 0,
1414                                           AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1415                 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1416                 parm |= out_in;
1417                 snd_hda_codec_write(codec, nid, 0,
1418                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
1419                                     parm);
1420                 if (out_in == AC_PINCTL_OUT_EN) {
1421                         mute_aa_path(codec, 1);
1422                         notify_aa_path_ctls(codec);
1423                 }
1424                 if (spec->codec_type == VT1718S) {
1425                         snd_hda_codec_amp_stereo(
1426                                         codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1427                                         HDA_AMP_UNMUTE);
1428                 }
1429                 if (cfg->inputs[i].type == AUTO_PIN_MIC) {
1430                         if (spec->codec_type == VT1708S
1431                             || spec->codec_type == VT1716S) {
1432                                 /* input = index 1 (AOW3) */
1433                                 snd_hda_codec_write(
1434                                         codec, nid, 0,
1435                                         AC_VERB_SET_CONNECT_SEL, 1);
1436                                 snd_hda_codec_amp_stereo(
1437                                         codec, nid, HDA_OUTPUT,
1438                                         0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1439                         }
1440                 }
1441         }
1442         spec->smart51_enabled = *ucontrol->value.integer.value;
1443         set_jack_power_state(codec);
1444         return 1;
1445 }
1446
1447 static struct snd_kcontrol_new via_smart51_mixer[2] = {
1448         {
1449          .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1450          .name = "Smart 5.1",
1451          .count = 1,
1452          .info = via_smart51_info,
1453          .get = via_smart51_get,
1454          .put = via_smart51_put,
1455          },
1456         {
1457          .iface = NID_MAPPING,
1458          .name = "Smart 5.1",
1459         }
1460 };
1461
1462 static int via_smart51_build(struct via_spec *spec)
1463 {
1464         struct snd_kcontrol_new *knew;
1465         const struct auto_pin_cfg *cfg = &spec->autocfg;
1466         hda_nid_t nid;
1467         int i;
1468
1469         knew = via_clone_control(spec, &via_smart51_mixer[0]);
1470         if (knew == NULL)
1471                 return -ENOMEM;
1472
1473         for (i = 0; i < cfg->num_inputs; i++) {
1474                 nid = cfg->inputs[i].pin;
1475                 if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) {
1476                         knew = via_clone_control(spec, &via_smart51_mixer[1]);
1477                         if (knew == NULL)
1478                                 return -ENOMEM;
1479                         knew->subdevice = nid;
1480                         break;
1481                 }
1482         }
1483
1484         return 0;
1485 }
1486
1487 /* capture mixer elements */
1488 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1489         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1490         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1491         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1492         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1493         {
1494                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1495                 /* The multiple "Capture Source" controls confuse alsamixer
1496                  * So call somewhat different..
1497                  */
1498                 /* .name = "Capture Source", */
1499                 .name = "Input Source",
1500                 .count = 1,
1501                 .info = via_mux_enum_info,
1502                 .get = via_mux_enum_get,
1503                 .put = via_mux_enum_put,
1504         },
1505         { } /* end */
1506 };
1507
1508 /* check AA path's mute statue */
1509 static int is_aa_path_mute(struct hda_codec *codec)
1510 {
1511         int mute = 1;
1512         hda_nid_t  nid_mixer;
1513         int start_idx;
1514         int end_idx;
1515         int i;
1516         struct via_spec *spec = codec->spec;
1517         /* get nid of MW0 and start & end index */
1518         switch (spec->codec_type) {
1519         case VT1708B_8CH:
1520         case VT1708B_4CH:
1521         case VT1708S:
1522         case VT1716S:
1523                 nid_mixer = 0x16;
1524                 start_idx = 2;
1525                 end_idx = 4;
1526                 break;
1527         case VT1702:
1528                 nid_mixer = 0x1a;
1529                 start_idx = 1;
1530                 end_idx = 3;
1531                 break;
1532         case VT1718S:
1533                 nid_mixer = 0x21;
1534                 start_idx = 1;
1535                 end_idx = 3;
1536                 break;
1537         case VT2002P:
1538         case VT1812:
1539                 nid_mixer = 0x21;
1540                 start_idx = 0;
1541                 end_idx = 2;
1542                 break;
1543         default:
1544                 return 0;
1545         }
1546         /* check AA path's mute status */
1547         for (i = start_idx; i <= end_idx; i++) {
1548                 unsigned int con_list = snd_hda_codec_read(
1549                         codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1550                 int shift = 8 * (i % 4);
1551                 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1552                 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1553                 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1554                         /* check mute status while the pin is connected */
1555                         int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1556                                                             HDA_INPUT, i) >> 7;
1557                         int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1558                                                             HDA_INPUT, i) >> 7;
1559                         if (!mute_l || !mute_r) {
1560                                 mute = 0;
1561                                 break;
1562                         }
1563                 }
1564         }
1565         return mute;
1566 }
1567
1568 /* enter/exit analog low-current mode */
1569 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1570 {
1571         struct via_spec *spec = codec->spec;
1572         static int saved_stream_idle = 1; /* saved stream idle status */
1573         int enable = is_aa_path_mute(codec);
1574         unsigned int verb = 0;
1575         unsigned int parm = 0;
1576
1577         if (stream_idle == -1)  /* stream status did not change */
1578                 enable = enable && saved_stream_idle;
1579         else {
1580                 enable = enable && stream_idle;
1581                 saved_stream_idle = stream_idle;
1582         }
1583
1584         /* decide low current mode's verb & parameter */
1585         switch (spec->codec_type) {
1586         case VT1708B_8CH:
1587         case VT1708B_4CH:
1588                 verb = 0xf70;
1589                 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1590                 break;
1591         case VT1708S:
1592         case VT1718S:
1593         case VT1716S:
1594                 verb = 0xf73;
1595                 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1596                 break;
1597         case VT1702:
1598                 verb = 0xf73;
1599                 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1600                 break;
1601         case VT2002P:
1602         case VT1812:
1603                 verb = 0xf93;
1604                 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1605                 break;
1606         default:
1607                 return;         /* other codecs are not supported */
1608         }
1609         /* send verb */
1610         snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1611 }
1612
1613 /*
1614  * generic initialization of ADC, input mixers and output mixers
1615  */
1616 static struct hda_verb vt1708_volume_init_verbs[] = {
1617         /*
1618          * Unmute ADC0-1 and set the default input to mic-in
1619          */
1620         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1621         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1622
1623
1624         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1625          * mixer widget
1626          */
1627         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1628         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1629         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1630         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1631         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1632         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1633
1634         /*
1635          * Set up output mixers (0x19 - 0x1b)
1636          */
1637         /* set vol=0 to output mixers */
1638         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1639         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1640         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1641
1642         /* Setup default input MW0 to PW4 */
1643         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1644         /* PW9 Output enable */
1645         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1646         { }
1647 };
1648
1649 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
1650                                  struct hda_codec *codec,
1651                                  struct snd_pcm_substream *substream)
1652 {
1653         struct via_spec *spec = codec->spec;
1654         int idle = substream->pstr->substream_opened == 1
1655                 && substream->ref_count == 0;
1656         analog_low_current_mode(codec, idle);
1657         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1658                                              hinfo);
1659 }
1660
1661 static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1662                                       unsigned int stream_tag,
1663                                       unsigned int format,
1664                                       struct snd_pcm_substream *substream)
1665 {
1666         struct via_spec *spec = codec->spec;
1667         struct hda_multi_out *mout = &spec->multiout;
1668         hda_nid_t *nids = mout->dac_nids;
1669         int chs = substream->runtime->channels;
1670         int i;
1671
1672         mutex_lock(&codec->spdif_mutex);
1673         if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1674                 if (chs == 2 &&
1675                     snd_hda_is_supported_format(codec, mout->dig_out_nid,
1676                                                 format) &&
1677                     !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1678                         mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1679                         /* turn off SPDIF once; otherwise the IEC958 bits won't
1680                          * be updated */
1681                         if (codec->spdif_ctls & AC_DIG1_ENABLE)
1682                                 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1683                                                     AC_VERB_SET_DIGI_CONVERT_1,
1684                                                     codec->spdif_ctls &
1685                                                         ~AC_DIG1_ENABLE & 0xff);
1686                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1687                                                    stream_tag, 0, format);
1688                         /* turn on again (if needed) */
1689                         if (codec->spdif_ctls & AC_DIG1_ENABLE)
1690                                 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1691                                                     AC_VERB_SET_DIGI_CONVERT_1,
1692                                                     codec->spdif_ctls & 0xff);
1693                 } else {
1694                         mout->dig_out_used = 0;
1695                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1696                                                    0, 0, 0);
1697                 }
1698         }
1699         mutex_unlock(&codec->spdif_mutex);
1700
1701         /* front */
1702         snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1703                                    0, format);
1704
1705         if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1706             && !spec->hp_independent_mode)
1707                 /* headphone out will just decode front left/right (stereo) */
1708                 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1709                                            0, format);
1710
1711         /* extra outputs copied from front */
1712         for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1713                 if (mout->extra_out_nid[i])
1714                         snd_hda_codec_setup_stream(codec,
1715                                                    mout->extra_out_nid[i],
1716                                                    stream_tag, 0, format);
1717
1718         /* surrounds */
1719         for (i = 1; i < mout->num_dacs; i++) {
1720                 if (chs >= (i + 1) * 2) /* independent out */
1721                         snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1722                                                    i * 2, format);
1723                 else /* copy front */
1724                         snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1725                                                    0, format);
1726         }
1727 }
1728
1729 static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1730                                           struct hda_codec *codec,
1731                                           unsigned int stream_tag,
1732                                           unsigned int format,
1733                                           struct snd_pcm_substream *substream)
1734 {
1735         struct via_spec *spec = codec->spec;
1736         struct hda_multi_out *mout = &spec->multiout;
1737         hda_nid_t *nids = mout->dac_nids;
1738
1739         if (substream->number == 0)
1740                 playback_multi_pcm_prep_0(codec, stream_tag, format,
1741                                           substream);
1742         else {
1743                 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1744                     spec->hp_independent_mode)
1745                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
1746                                                    stream_tag, 0, format);
1747         }
1748         vt1708_start_hp_work(spec);
1749         return 0;
1750 }
1751
1752 static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1753                                     struct hda_codec *codec,
1754                                     struct snd_pcm_substream *substream)
1755 {
1756         struct via_spec *spec = codec->spec;
1757         struct hda_multi_out *mout = &spec->multiout;
1758         hda_nid_t *nids = mout->dac_nids;
1759         int i;
1760
1761         if (substream->number == 0) {
1762                 for (i = 0; i < mout->num_dacs; i++)
1763                         snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1764
1765                 if (mout->hp_nid && !spec->hp_independent_mode)
1766                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
1767                                                    0, 0, 0);
1768
1769                 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1770                         if (mout->extra_out_nid[i])
1771                                 snd_hda_codec_setup_stream(codec,
1772                                                         mout->extra_out_nid[i],
1773                                                         0, 0, 0);
1774                 mutex_lock(&codec->spdif_mutex);
1775                 if (mout->dig_out_nid &&
1776                     mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1777                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1778                                                    0, 0, 0);
1779                         mout->dig_out_used = 0;
1780                 }
1781                 mutex_unlock(&codec->spdif_mutex);
1782         } else {
1783                 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1784                     spec->hp_independent_mode)
1785                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
1786                                                    0, 0, 0);
1787         }
1788         vt1708_stop_hp_work(spec);
1789         return 0;
1790 }
1791
1792 /*
1793  * Digital out
1794  */
1795 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1796                                      struct hda_codec *codec,
1797                                      struct snd_pcm_substream *substream)
1798 {
1799         struct via_spec *spec = codec->spec;
1800         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1801 }
1802
1803 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1804                                       struct hda_codec *codec,
1805                                       struct snd_pcm_substream *substream)
1806 {
1807         struct via_spec *spec = codec->spec;
1808         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1809 }
1810
1811 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1812                                         struct hda_codec *codec,
1813                                         unsigned int stream_tag,
1814                                         unsigned int format,
1815                                         struct snd_pcm_substream *substream)
1816 {
1817         struct via_spec *spec = codec->spec;
1818         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1819                                              stream_tag, format, substream);
1820 }
1821
1822 static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1823                                         struct hda_codec *codec,
1824                                         struct snd_pcm_substream *substream)
1825 {
1826         struct via_spec *spec = codec->spec;
1827         snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1828         return 0;
1829 }
1830
1831 /*
1832  * Analog capture
1833  */
1834 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1835                                    struct hda_codec *codec,
1836                                    unsigned int stream_tag,
1837                                    unsigned int format,
1838                                    struct snd_pcm_substream *substream)
1839 {
1840         struct via_spec *spec = codec->spec;
1841
1842         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1843                                    stream_tag, 0, format);
1844         return 0;
1845 }
1846
1847 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1848                                    struct hda_codec *codec,
1849                                    struct snd_pcm_substream *substream)
1850 {
1851         struct via_spec *spec = codec->spec;
1852         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1853         return 0;
1854 }
1855
1856 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1857         .substreams = 2,
1858         .channels_min = 2,
1859         .channels_max = 8,
1860         .nid = 0x10, /* NID to query formats and rates */
1861         .ops = {
1862                 .open = via_playback_pcm_open,
1863                 .prepare = via_playback_multi_pcm_prepare,
1864                 .cleanup = via_playback_multi_pcm_cleanup
1865         },
1866 };
1867
1868 static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1869         .substreams = 2,
1870         .channels_min = 2,
1871         .channels_max = 8,
1872         .nid = 0x10, /* NID to query formats and rates */
1873         /* We got noisy outputs on the right channel on VT1708 when
1874          * 24bit samples are used.  Until any workaround is found,
1875          * disable the 24bit format, so far.
1876          */
1877         .formats = SNDRV_PCM_FMTBIT_S16_LE,
1878         .ops = {
1879                 .open = via_playback_pcm_open,
1880                 .prepare = via_playback_multi_pcm_prepare,
1881                 .cleanup = via_playback_multi_pcm_cleanup
1882         },
1883 };
1884
1885 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1886         .substreams = 2,
1887         .channels_min = 2,
1888         .channels_max = 2,
1889         .nid = 0x15, /* NID to query formats and rates */
1890         .ops = {
1891                 .prepare = via_capture_pcm_prepare,
1892                 .cleanup = via_capture_pcm_cleanup
1893         },
1894 };
1895
1896 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1897         .substreams = 1,
1898         .channels_min = 2,
1899         .channels_max = 2,
1900         /* NID is set in via_build_pcms */
1901         .ops = {
1902                 .open = via_dig_playback_pcm_open,
1903                 .close = via_dig_playback_pcm_close,
1904                 .prepare = via_dig_playback_pcm_prepare,
1905                 .cleanup = via_dig_playback_pcm_cleanup
1906         },
1907 };
1908
1909 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1910         .substreams = 1,
1911         .channels_min = 2,
1912         .channels_max = 2,
1913 };
1914
1915 static int via_build_controls(struct hda_codec *codec)
1916 {
1917         struct via_spec *spec = codec->spec;
1918         struct snd_kcontrol *kctl;
1919         struct snd_kcontrol_new *knew;
1920         int err, i;
1921
1922         for (i = 0; i < spec->num_mixers; i++) {
1923                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1924                 if (err < 0)
1925                         return err;
1926         }
1927
1928         if (spec->multiout.dig_out_nid) {
1929                 err = snd_hda_create_spdif_out_ctls(codec,
1930                                                     spec->multiout.dig_out_nid);
1931                 if (err < 0)
1932                         return err;
1933                 err = snd_hda_create_spdif_share_sw(codec,
1934                                                     &spec->multiout);
1935                 if (err < 0)
1936                         return err;
1937                 spec->multiout.share_spdif = 1;
1938         }
1939         if (spec->dig_in_nid) {
1940                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1941                 if (err < 0)
1942                         return err;
1943         }
1944
1945         /* assign Capture Source enums to NID */
1946         kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1947         for (i = 0; kctl && i < kctl->count; i++) {
1948                 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1949                 if (err < 0)
1950                         return err;
1951         }
1952
1953         /* other nid->control mapping */
1954         for (i = 0; i < spec->num_mixers; i++) {
1955                 for (knew = spec->mixers[i]; knew->name; knew++) {
1956                         if (knew->iface != NID_MAPPING)
1957                                 continue;
1958                         kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1959                         if (kctl == NULL)
1960                                 continue;
1961                         err = snd_hda_add_nid(codec, kctl, 0,
1962                                               knew->subdevice);
1963                 }
1964         }
1965
1966         /* init power states */
1967         set_jack_power_state(codec);
1968         analog_low_current_mode(codec, 1);
1969
1970         via_free_kctls(codec); /* no longer needed */
1971         return 0;
1972 }
1973
1974 static int via_build_pcms(struct hda_codec *codec)
1975 {
1976         struct via_spec *spec = codec->spec;
1977         struct hda_pcm *info = spec->pcm_rec;
1978
1979         codec->num_pcms = 1;
1980         codec->pcm_info = info;
1981
1982         info->name = spec->stream_name_analog;
1983         info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1984                 *(spec->stream_analog_playback);
1985         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1986                 spec->multiout.dac_nids[0];
1987         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1988         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1989
1990         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1991                 spec->multiout.max_channels;
1992
1993         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1994                 codec->num_pcms++;
1995                 info++;
1996                 info->name = spec->stream_name_digital;
1997                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1998                 if (spec->multiout.dig_out_nid) {
1999                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2000                                 *(spec->stream_digital_playback);
2001                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2002                                 spec->multiout.dig_out_nid;
2003                 }
2004                 if (spec->dig_in_nid) {
2005                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2006                                 *(spec->stream_digital_capture);
2007                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2008                                 spec->dig_in_nid;
2009                 }
2010         }
2011
2012         return 0;
2013 }
2014
2015 static void via_free(struct hda_codec *codec)
2016 {
2017         struct via_spec *spec = codec->spec;
2018
2019         if (!spec)
2020                 return;
2021
2022         via_free_kctls(codec);
2023         vt1708_stop_hp_work(spec);
2024         kfree(codec->spec);
2025 }
2026
2027 /* mute internal speaker if HP is plugged */
2028 static void via_hp_automute(struct hda_codec *codec)
2029 {
2030         unsigned int present = 0;
2031         struct via_spec *spec = codec->spec;
2032
2033         present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2034
2035         if (!spec->hp_independent_mode) {
2036                 struct snd_ctl_elem_id id;
2037                 /* auto mute */
2038                 snd_hda_codec_amp_stereo(
2039                         codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0,
2040                         HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2041                 /* notify change */
2042                 memset(&id, 0, sizeof(id));
2043                 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2044                 strcpy(id.name, "Front Playback Switch");
2045                 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2046                                &id);
2047         }
2048 }
2049
2050 /* mute mono out if HP or Line out is plugged */
2051 static void via_mono_automute(struct hda_codec *codec)
2052 {
2053         unsigned int hp_present, lineout_present;
2054         struct via_spec *spec = codec->spec;
2055
2056         if (spec->codec_type != VT1716S)
2057                 return;
2058
2059         lineout_present = snd_hda_jack_detect(codec,
2060                                               spec->autocfg.line_out_pins[0]);
2061
2062         /* Mute Mono Out if Line Out is plugged */
2063         if (lineout_present) {
2064                 snd_hda_codec_amp_stereo(
2065                         codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE);
2066                 return;
2067         }
2068
2069         hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2070
2071         if (!spec->hp_independent_mode)
2072                 snd_hda_codec_amp_stereo(
2073                         codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE,
2074                         hp_present ? HDA_AMP_MUTE : 0);
2075 }
2076
2077 static void via_gpio_control(struct hda_codec *codec)
2078 {
2079         unsigned int gpio_data;
2080         unsigned int vol_counter;
2081         unsigned int vol;
2082         unsigned int master_vol;
2083
2084         struct via_spec *spec = codec->spec;
2085
2086         gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
2087                                        AC_VERB_GET_GPIO_DATA, 0) & 0x03;
2088
2089         vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
2090                                           0xF84, 0) & 0x3F0000) >> 16;
2091
2092         vol = vol_counter & 0x1F;
2093         master_vol = snd_hda_codec_read(codec, 0x1A, 0,
2094                                         AC_VERB_GET_AMP_GAIN_MUTE,
2095                                         AC_AMP_GET_INPUT);
2096
2097         if (gpio_data == 0x02) {
2098                 /* unmute line out */
2099                 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
2100                                          HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
2101
2102                 if (vol_counter & 0x20) {
2103                         /* decrease volume */
2104                         if (vol > master_vol)
2105                                 vol = master_vol;
2106                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
2107                                                  0, HDA_AMP_VOLMASK,
2108                                                  master_vol-vol);
2109                 } else {
2110                         /* increase volume */
2111                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
2112                                          HDA_AMP_VOLMASK,
2113                                          ((master_vol+vol) > 0x2A) ? 0x2A :
2114                                           (master_vol+vol));
2115                 }
2116         } else if (!(gpio_data & 0x02)) {
2117                 /* mute line out */
2118                 snd_hda_codec_amp_stereo(codec,
2119                                          spec->autocfg.line_out_pins[0],
2120                                          HDA_OUTPUT, 0, HDA_AMP_MUTE,
2121                                          HDA_AMP_MUTE);
2122         }
2123 }
2124
2125 /* mute Internal-Speaker if HP is plugged */
2126 static void via_speaker_automute(struct hda_codec *codec)
2127 {
2128         unsigned int hp_present;
2129         struct via_spec *spec = codec->spec;
2130
2131         if (spec->codec_type != VT2002P && spec->codec_type != VT1812)
2132                 return;
2133
2134         hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2135
2136         if (!spec->hp_independent_mode) {
2137                 struct snd_ctl_elem_id id;
2138                 snd_hda_codec_amp_stereo(
2139                         codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
2140                         HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2141                 /* notify change */
2142                 memset(&id, 0, sizeof(id));
2143                 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2144                 strcpy(id.name, "Speaker Playback Switch");
2145                 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2146                                &id);
2147         }
2148 }
2149
2150 /* mute line-out and internal speaker if HP is plugged */
2151 static void via_hp_bind_automute(struct hda_codec *codec)
2152 {
2153         /* use long instead of int below just to avoid an internal compiler
2154          * error with gcc 4.0.x
2155          */
2156         unsigned long hp_present, present = 0;
2157         struct via_spec *spec = codec->spec;
2158         int i;
2159
2160         if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
2161                 return;
2162
2163         hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2164
2165         present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
2166
2167         if (!spec->hp_independent_mode) {
2168                 /* Mute Line-Outs */
2169                 for (i = 0; i < spec->autocfg.line_outs; i++)
2170                         snd_hda_codec_amp_stereo(
2171                                 codec, spec->autocfg.line_out_pins[i],
2172                                 HDA_OUTPUT, 0,
2173                                 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2174                 if (hp_present)
2175                         present = hp_present;
2176         }
2177         /* Speakers */
2178         for (i = 0; i < spec->autocfg.speaker_outs; i++)
2179                 snd_hda_codec_amp_stereo(
2180                         codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
2181                         HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2182 }
2183
2184
2185 /* unsolicited event for jack sensing */
2186 static void via_unsol_event(struct hda_codec *codec,
2187                                   unsigned int res)
2188 {
2189         res >>= 26;
2190         if (res & VIA_HP_EVENT)
2191                 via_hp_automute(codec);
2192         if (res & VIA_GPIO_EVENT)
2193                 via_gpio_control(codec);
2194         if (res & VIA_JACK_EVENT)
2195                 set_jack_power_state(codec);
2196         if (res & VIA_MONO_EVENT)
2197                 via_mono_automute(codec);
2198         if (res & VIA_SPEAKER_EVENT)
2199                 via_speaker_automute(codec);
2200         if (res & VIA_BIND_HP_EVENT)
2201                 via_hp_bind_automute(codec);
2202 }
2203
2204 static int via_init(struct hda_codec *codec)
2205 {
2206         struct via_spec *spec = codec->spec;
2207         int i;
2208         for (i = 0; i < spec->num_iverbs; i++)
2209                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2210
2211         /* Lydia Add for EAPD enable */
2212         if (!spec->dig_in_nid) { /* No Digital In connection */
2213                 if (spec->dig_in_pin) {
2214                         snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2215                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
2216                                             PIN_OUT);
2217                         snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2218                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
2219                 }
2220         } else /* enable SPDIF-input pin */
2221                 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2222                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2223
2224         /* assign slave outs */
2225         if (spec->slave_dig_outs[0])
2226                 codec->slave_dig_outs = spec->slave_dig_outs;
2227
2228         return 0;
2229 }
2230
2231 #ifdef SND_HDA_NEEDS_RESUME
2232 static int via_suspend(struct hda_codec *codec, pm_message_t state)
2233 {
2234         struct via_spec *spec = codec->spec;
2235         vt1708_stop_hp_work(spec);
2236         return 0;
2237 }
2238 #endif
2239
2240 #ifdef CONFIG_SND_HDA_POWER_SAVE
2241 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2242 {
2243         struct via_spec *spec = codec->spec;
2244         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2245 }
2246 #endif
2247
2248 /*
2249  */
2250 static struct hda_codec_ops via_patch_ops = {
2251         .build_controls = via_build_controls,
2252         .build_pcms = via_build_pcms,
2253         .init = via_init,
2254         .free = via_free,
2255 #ifdef SND_HDA_NEEDS_RESUME
2256         .suspend = via_suspend,
2257 #endif
2258 #ifdef CONFIG_SND_HDA_POWER_SAVE
2259         .check_power_status = via_check_power_status,
2260 #endif
2261 };
2262
2263 /* fill in the dac_nids table from the parsed pin configuration */
2264 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
2265                                      const struct auto_pin_cfg *cfg)
2266 {
2267         int i;
2268         hda_nid_t nid;
2269
2270         spec->multiout.num_dacs = cfg->line_outs;
2271
2272         spec->multiout.dac_nids = spec->private_dac_nids;
2273
2274         for (i = 0; i < 4; i++) {
2275                 nid = cfg->line_out_pins[i];
2276                 if (nid) {
2277                         /* config dac list */
2278                         switch (i) {
2279                         case AUTO_SEQ_FRONT:
2280                                 spec->multiout.dac_nids[i] = 0x10;
2281                                 break;
2282                         case AUTO_SEQ_CENLFE:
2283                                 spec->multiout.dac_nids[i] = 0x12;
2284                                 break;
2285                         case AUTO_SEQ_SURROUND:
2286                                 spec->multiout.dac_nids[i] = 0x11;
2287                                 break;
2288                         case AUTO_SEQ_SIDE:
2289                                 spec->multiout.dac_nids[i] = 0x13;
2290                                 break;
2291                         }
2292                 }
2293         }
2294
2295         return 0;
2296 }
2297
2298 /* add playback controls from the parsed DAC table */
2299 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
2300                                              const struct auto_pin_cfg *cfg)
2301 {
2302         char name[32];
2303         static const char * const chname[4] = {
2304                 "Front", "Surround", "C/LFE", "Side"
2305         };
2306         hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
2307         int i, err;
2308
2309         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2310                 nid = cfg->line_out_pins[i];
2311
2312                 if (!nid)
2313                         continue;
2314
2315                 nid_vol = nid_vols[i];
2316
2317                 if (i == AUTO_SEQ_CENLFE) {
2318                         /* Center/LFE */
2319                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2320                                         "Center Playback Volume",
2321                                         HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2322                                                             HDA_OUTPUT));
2323                         if (err < 0)
2324                                 return err;
2325                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2326                                               "LFE Playback Volume",
2327                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2328                                                                   HDA_OUTPUT));
2329                         if (err < 0)
2330                                 return err;
2331                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2332                                               "Center Playback Switch",
2333                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2334                                                                   HDA_OUTPUT));
2335                         if (err < 0)
2336                                 return err;
2337                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2338                                               "LFE Playback Switch",
2339                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2340                                                                   HDA_OUTPUT));
2341                         if (err < 0)
2342                                 return err;
2343                 } else if (i == AUTO_SEQ_FRONT) {
2344                         /* add control to mixer index 0 */
2345                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2346                                               "Master Front Playback Volume",
2347                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2348                                                                   HDA_INPUT));
2349                         if (err < 0)
2350                                 return err;
2351                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2352                                               "Master Front Playback Switch",
2353                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2354                                                                   HDA_INPUT));
2355                         if (err < 0)
2356                                 return err;
2357
2358                         /* add control to PW3 */
2359                         sprintf(name, "%s Playback Volume", chname[i]);
2360                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2361                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2362                                                                   HDA_OUTPUT));
2363                         if (err < 0)
2364                                 return err;
2365                         sprintf(name, "%s Playback Switch", chname[i]);
2366                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2367                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2368                                                                   HDA_OUTPUT));
2369                         if (err < 0)
2370                                 return err;
2371                 } else {
2372                         sprintf(name, "%s Playback Volume", chname[i]);
2373                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2374                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2375                                                                   HDA_OUTPUT));
2376                         if (err < 0)
2377                                 return err;
2378                         sprintf(name, "%s Playback Switch", chname[i]);
2379                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2380                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2381                                                                   HDA_OUTPUT));
2382                         if (err < 0)
2383                                 return err;
2384                 }
2385         }
2386
2387         return 0;
2388 }
2389
2390 static void create_hp_imux(struct via_spec *spec)
2391 {
2392         int i;
2393         struct hda_input_mux *imux = &spec->private_imux[1];
2394         static const char * const texts[] = { "OFF", "ON", NULL};
2395
2396         /* for hp mode select */
2397         for (i = 0; texts[i]; i++)
2398                 snd_hda_add_imux_item(imux, texts[i], i, NULL);
2399
2400         spec->hp_mux = &spec->private_imux[1];
2401 }
2402
2403 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2404 {
2405         int err;
2406
2407         if (!pin)
2408                 return 0;
2409
2410         spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
2411         spec->hp_independent_mode_index = 1;
2412
2413         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2414                               "Headphone Playback Volume",
2415                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2416         if (err < 0)
2417                 return err;
2418         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2419                               "Headphone Playback Switch",
2420                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2421         if (err < 0)
2422                 return err;
2423
2424         create_hp_imux(spec);
2425
2426         return 0;
2427 }
2428
2429 /* create playback/capture controls for input pins */
2430 static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
2431                                             const struct auto_pin_cfg *cfg,
2432                                             hda_nid_t cap_nid,
2433                                             hda_nid_t pin_idxs[], int num_idxs)
2434 {
2435         struct via_spec *spec = codec->spec;
2436         struct hda_input_mux *imux = &spec->private_imux[0];
2437         int i, err, idx, type, type_idx = 0;
2438
2439         /* for internal loopback recording select */
2440         for (idx = 0; idx < num_idxs; idx++) {
2441                 if (pin_idxs[idx] == 0xff) {
2442                         snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL);
2443                         break;
2444                 }
2445         }
2446
2447         for (i = 0; i < cfg->num_inputs; i++) {
2448                 const char *label;
2449                 type = cfg->inputs[i].type;
2450                 for (idx = 0; idx < num_idxs; idx++)
2451                         if (pin_idxs[idx] == cfg->inputs[i].pin)
2452                                 break;
2453                 if (idx >= num_idxs)
2454                         continue;
2455                 if (i > 0 && type == cfg->inputs[i - 1].type)
2456                         type_idx++;
2457                 else
2458                         type_idx = 0;
2459                 label = hda_get_autocfg_input_label(codec, cfg, i);
2460                 if (spec->codec_type == VT1708S ||
2461                     spec->codec_type == VT1702 ||
2462                     spec->codec_type == VT1716S)
2463                         err = via_new_analog_input(spec, label, type_idx,
2464                                                    idx+1, cap_nid);
2465                 else
2466                         err = via_new_analog_input(spec, label, type_idx,
2467                                                    idx, cap_nid);
2468                 if (err < 0)
2469                         return err;
2470                 snd_hda_add_imux_item(imux, label, idx, NULL);
2471         }
2472         return 0;
2473 }
2474
2475 /* create playback/capture controls for input pins */
2476 static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec,
2477                                                 const struct auto_pin_cfg *cfg)
2478 {
2479         static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
2480         return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs,
2481                                                 ARRAY_SIZE(pin_idxs));
2482 }
2483
2484 #ifdef CONFIG_SND_HDA_POWER_SAVE
2485 static struct hda_amp_list vt1708_loopbacks[] = {
2486         { 0x17, HDA_INPUT, 1 },
2487         { 0x17, HDA_INPUT, 2 },
2488         { 0x17, HDA_INPUT, 3 },
2489         { 0x17, HDA_INPUT, 4 },
2490         { } /* end */
2491 };
2492 #endif
2493
2494 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2495 {
2496         unsigned int def_conf;
2497         unsigned char seqassoc;
2498
2499         def_conf = snd_hda_codec_get_pincfg(codec, nid);
2500         seqassoc = (unsigned char) get_defcfg_association(def_conf);
2501         seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
2502         if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2503             && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2504                 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2505                 snd_hda_codec_set_pincfg(codec, nid, def_conf);
2506         }
2507
2508         return;
2509 }
2510
2511 static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2512                                      struct snd_ctl_elem_value *ucontrol)
2513 {
2514         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2515         struct via_spec *spec = codec->spec;
2516
2517         if (spec->codec_type != VT1708)
2518                 return 0;
2519         spec->vt1708_jack_detectect =
2520                 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2521         ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
2522         return 0;
2523 }
2524
2525 static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2526                                      struct snd_ctl_elem_value *ucontrol)
2527 {
2528         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2529         struct via_spec *spec = codec->spec;
2530         int change;
2531
2532         if (spec->codec_type != VT1708)
2533                 return 0;
2534         spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
2535         change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2536                 == !spec->vt1708_jack_detectect;
2537         if (spec->vt1708_jack_detectect) {
2538                 mute_aa_path(codec, 1);
2539                 notify_aa_path_ctls(codec);
2540         }
2541         return change;
2542 }
2543
2544 static struct snd_kcontrol_new vt1708_jack_detectect[] = {
2545         {
2546                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2547                 .name = "Jack Detect",
2548                 .count = 1,
2549                 .info = snd_ctl_boolean_mono_info,
2550                 .get = vt1708_jack_detectect_get,
2551                 .put = vt1708_jack_detectect_put,
2552         },
2553         {} /* end */
2554 };
2555
2556 static int vt1708_parse_auto_config(struct hda_codec *codec)
2557 {
2558         struct via_spec *spec = codec->spec;
2559         int err;
2560
2561         /* Add HP and CD pin config connect bit re-config action */
2562         vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2563         vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2564
2565         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2566         if (err < 0)
2567                 return err;
2568         err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2569         if (err < 0)
2570                 return err;
2571         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2572                 return 0; /* can't find valid BIOS pin config */
2573
2574         err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
2575         if (err < 0)
2576                 return err;
2577         err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2578         if (err < 0)
2579                 return err;
2580         err = vt1708_auto_create_analog_input_ctls(codec, &spec->autocfg);
2581         if (err < 0)
2582                 return err;
2583         /* add jack detect on/off control */
2584         err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
2585         if (err < 0)
2586                 return err;
2587
2588         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2589
2590         if (spec->autocfg.dig_outs)
2591                 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
2592         spec->dig_in_pin = VT1708_DIGIN_PIN;
2593         if (spec->autocfg.dig_in_pin)
2594                 spec->dig_in_nid = VT1708_DIGIN_NID;
2595
2596         if (spec->kctls.list)
2597                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2598
2599         spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2600
2601         spec->input_mux = &spec->private_imux[0];
2602
2603         if (spec->hp_mux)
2604                 via_hp_build(codec);
2605
2606         via_smart51_build(spec);
2607         return 1;
2608 }
2609
2610 /* init callback for auto-configuration model -- overriding the default init */
2611 static int via_auto_init(struct hda_codec *codec)
2612 {
2613         struct via_spec *spec = codec->spec;
2614
2615         via_init(codec);
2616         via_auto_init_multi_out(codec);
2617         via_auto_init_hp_out(codec);
2618         via_auto_init_analog_input(codec);
2619         if (spec->codec_type == VT2002P || spec->codec_type == VT1812) {
2620                 via_hp_bind_automute(codec);
2621         } else {
2622                 via_hp_automute(codec);
2623                 via_speaker_automute(codec);
2624         }
2625
2626         return 0;
2627 }
2628
2629 static void vt1708_update_hp_jack_state(struct work_struct *work)
2630 {
2631         struct via_spec *spec = container_of(work, struct via_spec,
2632                                              vt1708_hp_work.work);
2633         if (spec->codec_type != VT1708)
2634                 return;
2635         /* if jack state toggled */
2636         if (spec->vt1708_hp_present
2637             != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2638                 spec->vt1708_hp_present ^= 1;
2639                 via_hp_automute(spec->codec);
2640         }
2641         vt1708_start_hp_work(spec);
2642 }
2643
2644 static int get_mux_nids(struct hda_codec *codec)
2645 {
2646         struct via_spec *spec = codec->spec;
2647         hda_nid_t nid, conn[8];
2648         unsigned int type;
2649         int i, n;
2650
2651         for (i = 0; i < spec->num_adc_nids; i++) {
2652                 nid = spec->adc_nids[i];
2653                 while (nid) {
2654                         type = get_wcaps_type(get_wcaps(codec, nid));
2655                         if (type == AC_WID_PIN)
2656                                 break;
2657                         n = snd_hda_get_connections(codec, nid, conn,
2658                                                     ARRAY_SIZE(conn));
2659                         if (n <= 0)
2660                                 break;
2661                         if (n > 1) {
2662                                 spec->mux_nids[i] = nid;
2663                                 break;
2664                         }
2665                         nid = conn[0];
2666                 }
2667         }
2668         return 0;
2669 }
2670
2671 static int patch_vt1708(struct hda_codec *codec)
2672 {
2673         struct via_spec *spec;
2674         int err;
2675
2676         /* create a codec specific record */
2677         spec = via_new_spec(codec);
2678         if (spec == NULL)
2679                 return -ENOMEM;
2680
2681         /* automatic parse from the BIOS config */
2682         err = vt1708_parse_auto_config(codec);
2683         if (err < 0) {
2684                 via_free(codec);
2685                 return err;
2686         } else if (!err) {
2687                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2688                        "from BIOS.  Using genenic mode...\n");
2689         }
2690
2691
2692         spec->stream_name_analog = "VT1708 Analog";
2693         spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2694         /* disable 32bit format on VT1708 */
2695         if (codec->vendor_id == 0x11061708)
2696                 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2697         spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2698
2699         spec->stream_name_digital = "VT1708 Digital";
2700         spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2701         spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2702
2703
2704         if (!spec->adc_nids && spec->input_mux) {
2705                 spec->adc_nids = vt1708_adc_nids;
2706                 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2707                 get_mux_nids(codec);
2708                 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2709                 spec->num_mixers++;
2710         }
2711
2712         codec->patch_ops = via_patch_ops;
2713
2714         codec->patch_ops.init = via_auto_init;
2715 #ifdef CONFIG_SND_HDA_POWER_SAVE
2716         spec->loopback.amplist = vt1708_loopbacks;
2717 #endif
2718         INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2719         return 0;
2720 }
2721
2722 /* capture mixer elements */
2723 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2724         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2725         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2726         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2727         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2728         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2729         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2730         {
2731                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2732                 /* The multiple "Capture Source" controls confuse alsamixer
2733                  * So call somewhat different..
2734                  */
2735                 /* .name = "Capture Source", */
2736                 .name = "Input Source",
2737                 .count = 1,
2738                 .info = via_mux_enum_info,
2739                 .get = via_mux_enum_get,
2740                 .put = via_mux_enum_put,
2741         },
2742         { } /* end */
2743 };
2744
2745 static struct hda_verb vt1709_uniwill_init_verbs[] = {
2746         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2747          AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2748         { }
2749 };
2750
2751 /*
2752  * generic initialization of ADC, input mixers and output mixers
2753  */
2754 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2755         /*
2756          * Unmute ADC0-2 and set the default input to mic-in
2757          */
2758         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2759         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2760         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2761
2762
2763         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2764          * mixer widget
2765          */
2766         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2767         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2768         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2769         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2770         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2771         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2772
2773         /*
2774          * Set up output selector (0x1a, 0x1b, 0x29)
2775          */
2776         /* set vol=0 to output mixers */
2777         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2778         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2779         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2780
2781         /*
2782          *  Unmute PW3 and PW4
2783          */
2784         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2785         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2786
2787         /* Set input of PW4 as MW0 */
2788         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2789         /* PW9 Output enable */
2790         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2791         { }
2792 };
2793
2794 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2795         .substreams = 1,
2796         .channels_min = 2,
2797         .channels_max = 10,
2798         .nid = 0x10, /* NID to query formats and rates */
2799         .ops = {
2800                 .open = via_playback_pcm_open,
2801                 .prepare = via_playback_multi_pcm_prepare,
2802                 .cleanup = via_playback_multi_pcm_cleanup,
2803         },
2804 };
2805
2806 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2807         .substreams = 1,
2808         .channels_min = 2,
2809         .channels_max = 6,
2810         .nid = 0x10, /* NID to query formats and rates */
2811         .ops = {
2812                 .open = via_playback_pcm_open,
2813                 .prepare = via_playback_multi_pcm_prepare,
2814                 .cleanup = via_playback_multi_pcm_cleanup,
2815         },
2816 };
2817
2818 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2819         .substreams = 2,
2820         .channels_min = 2,
2821         .channels_max = 2,
2822         .nid = 0x14, /* NID to query formats and rates */
2823         .ops = {
2824                 .prepare = via_capture_pcm_prepare,
2825                 .cleanup = via_capture_pcm_cleanup
2826         },
2827 };
2828
2829 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2830         .substreams = 1,
2831         .channels_min = 2,
2832         .channels_max = 2,
2833         /* NID is set in via_build_pcms */
2834         .ops = {
2835                 .open = via_dig_playback_pcm_open,
2836                 .close = via_dig_playback_pcm_close
2837         },
2838 };
2839
2840 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
2841         .substreams = 1,
2842         .channels_min = 2,
2843         .channels_max = 2,
2844 };
2845
2846 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2847                                      const struct auto_pin_cfg *cfg)
2848 {
2849         int i;
2850         hda_nid_t nid;
2851
2852         if (cfg->line_outs == 4)  /* 10 channels */
2853                 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2854         else if (cfg->line_outs == 3) /* 6 channels */
2855                 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2856
2857         spec->multiout.dac_nids = spec->private_dac_nids;
2858
2859         if (cfg->line_outs == 4) { /* 10 channels */
2860                 for (i = 0; i < cfg->line_outs; i++) {
2861                         nid = cfg->line_out_pins[i];
2862                         if (nid) {
2863                                 /* config dac list */
2864                                 switch (i) {
2865                                 case AUTO_SEQ_FRONT:
2866                                         /* AOW0 */
2867                                         spec->multiout.dac_nids[i] = 0x10;
2868                                         break;
2869                                 case AUTO_SEQ_CENLFE:
2870                                         /* AOW2 */
2871                                         spec->multiout.dac_nids[i] = 0x12;
2872                                         break;
2873                                 case AUTO_SEQ_SURROUND:
2874                                         /* AOW3 */
2875                                         spec->multiout.dac_nids[i] = 0x11;
2876                                         break;
2877                                 case AUTO_SEQ_SIDE:
2878                                         /* AOW1 */
2879                                         spec->multiout.dac_nids[i] = 0x27;
2880                                         break;
2881                                 default:
2882                                         break;
2883                                 }
2884                         }
2885                 }
2886                 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2887
2888         } else if (cfg->line_outs == 3) { /* 6 channels */
2889                 for (i = 0; i < cfg->line_outs; i++) {
2890                         nid = cfg->line_out_pins[i];
2891                         if (nid) {
2892                                 /* config dac list */
2893                                 switch (i) {
2894                                 case AUTO_SEQ_FRONT:
2895                                         /* AOW0 */
2896                                         spec->multiout.dac_nids[i] = 0x10;
2897                                         break;
2898                                 case AUTO_SEQ_CENLFE:
2899                                         /* AOW2 */
2900                                         spec->multiout.dac_nids[i] = 0x12;
2901                                         break;
2902                                 case AUTO_SEQ_SURROUND:
2903                                         /* AOW1 */
2904                                         spec->multiout.dac_nids[i] = 0x11;
2905                                         break;
2906                                 default:
2907                                         break;
2908                                 }
2909                         }
2910                 }
2911         }
2912
2913         return 0;
2914 }
2915
2916 /* add playback controls from the parsed DAC table */
2917 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2918                                              const struct auto_pin_cfg *cfg)
2919 {
2920         char name[32];
2921         static const char * const chname[4] = {
2922                 "Front", "Surround", "C/LFE", "Side"
2923         };
2924         hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2925         int i, err;
2926
2927         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2928                 nid = cfg->line_out_pins[i];
2929
2930                 if (!nid)
2931                         continue;
2932
2933                 nid_vol = nid_vols[i];
2934
2935                 if (i == AUTO_SEQ_CENLFE) {
2936                         /* Center/LFE */
2937                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2938                                               "Center Playback Volume",
2939                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2940                                                                   HDA_OUTPUT));
2941                         if (err < 0)
2942                                 return err;
2943                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2944                                               "LFE Playback Volume",
2945                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2946                                                                   HDA_OUTPUT));
2947                         if (err < 0)
2948                                 return err;
2949                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2950                                               "Center Playback Switch",
2951                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2952                                                                   HDA_OUTPUT));
2953                         if (err < 0)
2954                                 return err;
2955                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2956                                               "LFE Playback Switch",
2957                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2958                                                                   HDA_OUTPUT));
2959                         if (err < 0)
2960                                 return err;
2961                 } else if (i == AUTO_SEQ_FRONT) {
2962                         /* ADD control to mixer index 0 */
2963                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2964                                               "Master Front Playback Volume",
2965                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2966                                                                   HDA_INPUT));
2967                         if (err < 0)
2968                                 return err;
2969                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2970                                               "Master Front Playback Switch",
2971                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2972                                                                   HDA_INPUT));
2973                         if (err < 0)
2974                                 return err;
2975
2976                         /* add control to PW3 */
2977                         sprintf(name, "%s Playback Volume", chname[i]);
2978                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2979                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2980                                                                   HDA_OUTPUT));
2981                         if (err < 0)
2982                                 return err;
2983                         sprintf(name, "%s Playback Switch", chname[i]);
2984                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2985                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2986                                                                   HDA_OUTPUT));
2987                         if (err < 0)
2988                                 return err;
2989                 } else if (i == AUTO_SEQ_SURROUND) {
2990                         sprintf(name, "%s Playback Volume", chname[i]);
2991                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2992                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2993                                                                   HDA_OUTPUT));
2994                         if (err < 0)
2995                                 return err;
2996                         sprintf(name, "%s Playback Switch", chname[i]);
2997                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2998                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2999                                                                   HDA_OUTPUT));
3000                         if (err < 0)
3001                                 return err;
3002                 } else if (i == AUTO_SEQ_SIDE) {
3003                         sprintf(name, "%s Playback Volume", chname[i]);
3004                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3005                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3006                                                                   HDA_OUTPUT));
3007                         if (err < 0)
3008                                 return err;
3009                         sprintf(name, "%s Playback Switch", chname[i]);
3010                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3011                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3012                                                                   HDA_OUTPUT));
3013                         if (err < 0)
3014                                 return err;
3015                 }
3016         }
3017
3018         return 0;
3019 }
3020
3021 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3022 {
3023         int err;
3024
3025         if (!pin)
3026                 return 0;
3027
3028         if (spec->multiout.num_dacs == 5) /* 10 channels */
3029                 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
3030         else if (spec->multiout.num_dacs == 3) /* 6 channels */
3031                 spec->multiout.hp_nid = 0;
3032         spec->hp_independent_mode_index = 1;
3033
3034         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3035                               "Headphone Playback Volume",
3036                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3037         if (err < 0)
3038                 return err;
3039         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3040                               "Headphone Playback Switch",
3041                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3042         if (err < 0)
3043                 return err;
3044
3045         return 0;
3046 }
3047
3048 /* create playback/capture controls for input pins */
3049 static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
3050                                                 const struct auto_pin_cfg *cfg)
3051 {
3052         static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
3053         return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
3054                                                 ARRAY_SIZE(pin_idxs));
3055 }
3056
3057 static int vt1709_parse_auto_config(struct hda_codec *codec)
3058 {
3059         struct via_spec *spec = codec->spec;
3060         int err;
3061
3062         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3063         if (err < 0)
3064                 return err;
3065         err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
3066         if (err < 0)
3067                 return err;
3068         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3069                 return 0; /* can't find valid BIOS pin config */
3070
3071         err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
3072         if (err < 0)
3073                 return err;
3074         err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3075         if (err < 0)
3076                 return err;
3077         err = vt1709_auto_create_analog_input_ctls(codec, &spec->autocfg);
3078         if (err < 0)
3079                 return err;
3080
3081         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3082
3083         if (spec->autocfg.dig_outs)
3084                 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
3085         spec->dig_in_pin = VT1709_DIGIN_PIN;
3086         if (spec->autocfg.dig_in_pin)
3087                 spec->dig_in_nid = VT1709_DIGIN_NID;
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                 via_hp_build(codec);
3096
3097         via_smart51_build(spec);
3098         return 1;
3099 }
3100
3101 #ifdef CONFIG_SND_HDA_POWER_SAVE
3102 static struct hda_amp_list vt1709_loopbacks[] = {
3103         { 0x18, HDA_INPUT, 1 },
3104         { 0x18, HDA_INPUT, 2 },
3105         { 0x18, HDA_INPUT, 3 },
3106         { 0x18, HDA_INPUT, 4 },
3107         { } /* end */
3108 };
3109 #endif
3110
3111 static int patch_vt1709_10ch(struct hda_codec *codec)
3112 {
3113         struct via_spec *spec;
3114         int err;
3115
3116         /* create a codec specific record */
3117         spec = via_new_spec(codec);
3118         if (spec == NULL)
3119                 return -ENOMEM;
3120
3121         err = vt1709_parse_auto_config(codec);
3122         if (err < 0) {
3123                 via_free(codec);
3124                 return err;
3125         } else if (!err) {
3126                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3127                        "Using genenic mode...\n");
3128         }
3129
3130         spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
3131         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3132
3133         spec->stream_name_analog = "VT1709 Analog";
3134         spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
3135         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3136
3137         spec->stream_name_digital = "VT1709 Digital";
3138         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3139         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3140
3141
3142         if (!spec->adc_nids && spec->input_mux) {
3143                 spec->adc_nids = vt1709_adc_nids;
3144                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3145                 get_mux_nids(codec);
3146                 spec->mixers[spec->num_mixers] = vt1709_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 = vt1709_loopbacks;
3156 #endif
3157
3158         return 0;
3159 }
3160 /*
3161  * generic initialization of ADC, input mixers and output mixers
3162  */
3163 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
3164         /*
3165          * Unmute ADC0-2 and set the default input to mic-in
3166          */
3167         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3168         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3169         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3170
3171
3172         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3173          * mixer widget
3174          */
3175         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3176         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3177         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3178         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3179         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3180         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3181
3182         /*
3183          * Set up output selector (0x1a, 0x1b, 0x29)
3184          */
3185         /* set vol=0 to output mixers */
3186         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3187         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3188         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3189
3190         /*
3191          *  Unmute PW3 and PW4
3192          */
3193         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3194         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3195
3196         /* Set input of PW4 as MW0 */
3197         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
3198         /* PW9 Output enable */
3199         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3200         { }
3201 };
3202
3203 static int patch_vt1709_6ch(struct hda_codec *codec)
3204 {
3205         struct via_spec *spec;
3206         int err;
3207
3208         /* create a codec specific record */
3209         spec = via_new_spec(codec);
3210         if (spec == NULL)
3211                 return -ENOMEM;
3212
3213         err = vt1709_parse_auto_config(codec);
3214         if (err < 0) {
3215                 via_free(codec);
3216                 return err;
3217         } else if (!err) {
3218                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3219                        "Using genenic mode...\n");
3220         }
3221
3222         spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
3223         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3224
3225         spec->stream_name_analog = "VT1709 Analog";
3226         spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
3227         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3228
3229         spec->stream_name_digital = "VT1709 Digital";
3230         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3231         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3232
3233
3234         if (!spec->adc_nids && spec->input_mux) {
3235                 spec->adc_nids = vt1709_adc_nids;
3236                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3237                 get_mux_nids(codec);
3238                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3239                 spec->num_mixers++;
3240         }
3241
3242         codec->patch_ops = via_patch_ops;
3243
3244         codec->patch_ops.init = via_auto_init;
3245         codec->patch_ops.unsol_event = via_unsol_event;
3246 #ifdef CONFIG_SND_HDA_POWER_SAVE
3247         spec->loopback.amplist = vt1709_loopbacks;
3248 #endif
3249         return 0;
3250 }
3251
3252 /* capture mixer elements */
3253 static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3254         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3255         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3256         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3257         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3258         {
3259                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3260                 /* The multiple "Capture Source" controls confuse alsamixer
3261                  * So call somewhat different..
3262                  */
3263                 /* .name = "Capture Source", */
3264                 .name = "Input Source",
3265                 .count = 1,
3266                 .info = via_mux_enum_info,
3267                 .get = via_mux_enum_get,
3268                 .put = via_mux_enum_put,
3269         },
3270         { } /* end */
3271 };
3272 /*
3273  * generic initialization of ADC, input mixers and output mixers
3274  */
3275 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3276         /*
3277          * Unmute ADC0-1 and set the default input to mic-in
3278          */
3279         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3280         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3281
3282
3283         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3284          * mixer widget
3285          */
3286         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3287         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3288         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3289         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3290         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3291         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3292
3293         /*
3294          * Set up output mixers
3295          */
3296         /* set vol=0 to output mixers */
3297         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3298         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3299         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3300
3301         /* Setup default input to PW4 */
3302         {0x1d, AC_VERB_SET_CONNECT_SEL, 0},
3303         /* PW9 Output enable */
3304         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3305         /* PW10 Input enable */
3306         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3307         { }
3308 };
3309
3310 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3311         /*
3312          * Unmute ADC0-1 and set the default input to mic-in
3313          */
3314         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3315         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3316
3317
3318         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3319          * mixer widget
3320          */
3321         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3322         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3323         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3324         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3325         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3326         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3327
3328         /*
3329          * Set up output mixers
3330          */
3331         /* set vol=0 to output mixers */
3332         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3333         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3334         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3335
3336         /* Setup default input of PW4 to MW0 */
3337         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3338         /* PW9 Output enable */
3339         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3340         /* PW10 Input enable */
3341         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3342         { }
3343 };
3344
3345 static struct hda_verb vt1708B_uniwill_init_verbs[] = {
3346         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3347          AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3348         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3349         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3350         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3351         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3352         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3353         {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3354         {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3355         { }
3356 };
3357
3358 static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3359                               struct hda_codec *codec,
3360                               struct snd_pcm_substream *substream)
3361 {
3362         int idle = substream->pstr->substream_opened == 1
3363                 && substream->ref_count == 0;
3364
3365         analog_low_current_mode(codec, idle);
3366         return 0;
3367 }
3368
3369 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3370         .substreams = 2,
3371         .channels_min = 2,
3372         .channels_max = 8,
3373         .nid = 0x10, /* NID to query formats and rates */
3374         .ops = {
3375                 .open = via_playback_pcm_open,
3376                 .prepare = via_playback_multi_pcm_prepare,
3377                 .cleanup = via_playback_multi_pcm_cleanup,
3378                 .close = via_pcm_open_close
3379         },
3380 };
3381
3382 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3383         .substreams = 2,
3384         .channels_min = 2,
3385         .channels_max = 4,
3386         .nid = 0x10, /* NID to query formats and rates */
3387         .ops = {
3388                 .open = via_playback_pcm_open,
3389                 .prepare = via_playback_multi_pcm_prepare,
3390                 .cleanup = via_playback_multi_pcm_cleanup
3391         },
3392 };
3393
3394 static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3395         .substreams = 2,
3396         .channels_min = 2,
3397         .channels_max = 2,
3398         .nid = 0x13, /* NID to query formats and rates */
3399         .ops = {
3400                 .open = via_pcm_open_close,
3401                 .prepare = via_capture_pcm_prepare,
3402                 .cleanup = via_capture_pcm_cleanup,
3403                 .close = via_pcm_open_close
3404         },
3405 };
3406
3407 static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3408         .substreams = 1,
3409         .channels_min = 2,
3410         .channels_max = 2,
3411         /* NID is set in via_build_pcms */
3412         .ops = {
3413                 .open = via_dig_playback_pcm_open,
3414                 .close = via_dig_playback_pcm_close,
3415                 .prepare = via_dig_playback_pcm_prepare,
3416                 .cleanup = via_dig_playback_pcm_cleanup
3417         },
3418 };
3419
3420 static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3421         .substreams = 1,
3422         .channels_min = 2,
3423         .channels_max = 2,
3424 };
3425
3426 /* fill in the dac_nids table from the parsed pin configuration */
3427 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3428                                      const struct auto_pin_cfg *cfg)
3429 {
3430         int i;
3431         hda_nid_t nid;
3432
3433         spec->multiout.num_dacs = cfg->line_outs;
3434
3435         spec->multiout.dac_nids = spec->private_dac_nids;
3436
3437         for (i = 0; i < 4; i++) {
3438                 nid = cfg->line_out_pins[i];
3439                 if (nid) {
3440                         /* config dac list */
3441                         switch (i) {
3442                         case AUTO_SEQ_FRONT:
3443                                 spec->multiout.dac_nids[i] = 0x10;
3444                                 break;
3445                         case AUTO_SEQ_CENLFE:
3446                                 spec->multiout.dac_nids[i] = 0x24;
3447                                 break;
3448                         case AUTO_SEQ_SURROUND:
3449                                 spec->multiout.dac_nids[i] = 0x11;
3450                                 break;
3451                         case AUTO_SEQ_SIDE:
3452                                 spec->multiout.dac_nids[i] = 0x25;
3453                                 break;
3454                         }
3455                 }
3456         }
3457
3458         return 0;
3459 }
3460
3461 /* add playback controls from the parsed DAC table */
3462 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3463                                              const struct auto_pin_cfg *cfg)
3464 {
3465         char name[32];
3466         static const char * const chname[4] = {
3467                 "Front", "Surround", "C/LFE", "Side"
3468         };
3469         hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3470         hda_nid_t nid, nid_vol = 0;
3471         int i, err;
3472
3473         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3474                 nid = cfg->line_out_pins[i];
3475
3476                 if (!nid)
3477                         continue;
3478
3479                 nid_vol = nid_vols[i];
3480
3481                 if (i == AUTO_SEQ_CENLFE) {
3482                         /* Center/LFE */
3483                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3484                                               "Center Playback Volume",
3485                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3486                                                                   HDA_OUTPUT));
3487                         if (err < 0)
3488                                 return err;
3489                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3490                                               "LFE Playback Volume",
3491                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3492                                                                   HDA_OUTPUT));
3493                         if (err < 0)
3494                                 return err;
3495                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3496                                               "Center Playback Switch",
3497                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3498                                                                   HDA_OUTPUT));
3499                         if (err < 0)
3500                                 return err;
3501                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3502                                               "LFE Playback Switch",
3503                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3504                                                                   HDA_OUTPUT));
3505                         if (err < 0)
3506                                 return err;
3507                 } else if (i == AUTO_SEQ_FRONT) {
3508                         /* add control to mixer index 0 */
3509                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3510                                               "Master Front Playback Volume",
3511                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3512                                                                   HDA_INPUT));
3513                         if (err < 0)
3514                                 return err;
3515                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3516                                               "Master Front Playback Switch",
3517                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3518                                                                   HDA_INPUT));
3519                         if (err < 0)
3520                                 return err;
3521
3522                         /* add control to PW3 */
3523                         sprintf(name, "%s Playback Volume", chname[i]);
3524                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3525                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3526                                                                   HDA_OUTPUT));
3527                         if (err < 0)
3528                                 return err;
3529                         sprintf(name, "%s Playback Switch", chname[i]);
3530                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3531                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3532                                                                   HDA_OUTPUT));
3533                         if (err < 0)
3534                                 return err;
3535                 } else {
3536                         sprintf(name, "%s Playback Volume", chname[i]);
3537                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3538                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3539                                                                   HDA_OUTPUT));
3540                         if (err < 0)
3541                                 return err;
3542                         sprintf(name, "%s Playback Switch", chname[i]);
3543                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3544                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3545                                                                   HDA_OUTPUT));
3546                         if (err < 0)
3547                                 return err;
3548                 }
3549         }
3550
3551         return 0;
3552 }
3553
3554 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3555 {
3556         int err;
3557
3558         if (!pin)
3559                 return 0;
3560
3561         spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3562         spec->hp_independent_mode_index = 1;
3563
3564         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3565                               "Headphone Playback Volume",
3566                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3567         if (err < 0)
3568                 return err;
3569         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3570                               "Headphone Playback Switch",
3571                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3572         if (err < 0)
3573                 return err;
3574
3575         create_hp_imux(spec);
3576
3577         return 0;
3578 }
3579
3580 /* create playback/capture controls for input pins */
3581 static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
3582                                                 const struct auto_pin_cfg *cfg)
3583 {
3584         static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3585         return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3586                                                 ARRAY_SIZE(pin_idxs));
3587 }
3588
3589 static int vt1708B_parse_auto_config(struct hda_codec *codec)
3590 {
3591         struct via_spec *spec = codec->spec;
3592         int err;
3593
3594         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3595         if (err < 0)
3596                 return err;
3597         err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
3598         if (err < 0)
3599                 return err;
3600         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3601                 return 0; /* can't find valid BIOS pin config */
3602
3603         err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
3604         if (err < 0)
3605                 return err;
3606         err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3607         if (err < 0)
3608                 return err;
3609         err = vt1708B_auto_create_analog_input_ctls(codec, &spec->autocfg);
3610         if (err < 0)
3611                 return err;
3612
3613         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3614
3615         if (spec->autocfg.dig_outs)
3616                 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
3617         spec->dig_in_pin = VT1708B_DIGIN_PIN;
3618         if (spec->autocfg.dig_in_pin)
3619                 spec->dig_in_nid = VT1708B_DIGIN_NID;
3620
3621         if (spec->kctls.list)
3622                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3623
3624         spec->input_mux = &spec->private_imux[0];
3625
3626         if (spec->hp_mux)
3627                 via_hp_build(codec);
3628
3629         via_smart51_build(spec);
3630         return 1;
3631 }
3632
3633 #ifdef CONFIG_SND_HDA_POWER_SAVE
3634 static struct hda_amp_list vt1708B_loopbacks[] = {
3635         { 0x16, HDA_INPUT, 1 },
3636         { 0x16, HDA_INPUT, 2 },
3637         { 0x16, HDA_INPUT, 3 },
3638         { 0x16, HDA_INPUT, 4 },
3639         { } /* end */
3640 };
3641 #endif
3642 static int patch_vt1708S(struct hda_codec *codec);
3643 static int patch_vt1708B_8ch(struct hda_codec *codec)
3644 {
3645         struct via_spec *spec;
3646         int err;
3647
3648         if (get_codec_type(codec) == VT1708BCE)
3649                 return patch_vt1708S(codec);
3650         /* create a codec specific record */
3651         spec = via_new_spec(codec);
3652         if (spec == NULL)
3653                 return -ENOMEM;
3654
3655         /* automatic parse from the BIOS config */
3656         err = vt1708B_parse_auto_config(codec);
3657         if (err < 0) {
3658                 via_free(codec);
3659                 return err;
3660         } else if (!err) {
3661                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3662                        "from BIOS.  Using genenic mode...\n");
3663         }
3664
3665         spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
3666         spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3667
3668         spec->stream_name_analog = "VT1708B Analog";
3669         spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
3670         spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3671
3672         spec->stream_name_digital = "VT1708B Digital";
3673         spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3674         spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3675
3676         if (!spec->adc_nids && spec->input_mux) {
3677                 spec->adc_nids = vt1708B_adc_nids;
3678                 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3679                 get_mux_nids(codec);
3680                 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3681                 spec->num_mixers++;
3682         }
3683
3684         codec->patch_ops = via_patch_ops;
3685
3686         codec->patch_ops.init = via_auto_init;
3687         codec->patch_ops.unsol_event = via_unsol_event;
3688 #ifdef CONFIG_SND_HDA_POWER_SAVE
3689         spec->loopback.amplist = vt1708B_loopbacks;
3690 #endif
3691
3692         return 0;
3693 }
3694
3695 static int patch_vt1708B_4ch(struct hda_codec *codec)
3696 {
3697         struct via_spec *spec;
3698         int err;
3699
3700         /* create a codec specific record */
3701         spec = via_new_spec(codec);
3702         if (spec == NULL)
3703                 return -ENOMEM;
3704
3705         /* automatic parse from the BIOS config */
3706         err = vt1708B_parse_auto_config(codec);
3707         if (err < 0) {
3708                 via_free(codec);
3709                 return err;
3710         } else if (!err) {
3711                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3712                        "from BIOS.  Using genenic mode...\n");
3713         }
3714
3715         spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
3716         spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3717
3718         spec->stream_name_analog = "VT1708B Analog";
3719         spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
3720         spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3721
3722         spec->stream_name_digital = "VT1708B Digital";
3723         spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3724         spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3725
3726         if (!spec->adc_nids && spec->input_mux) {
3727                 spec->adc_nids = vt1708B_adc_nids;
3728                 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3729                 get_mux_nids(codec);
3730                 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3731                 spec->num_mixers++;
3732         }
3733
3734         codec->patch_ops = via_patch_ops;
3735
3736         codec->patch_ops.init = via_auto_init;
3737         codec->patch_ops.unsol_event = via_unsol_event;
3738 #ifdef CONFIG_SND_HDA_POWER_SAVE
3739         spec->loopback.amplist = vt1708B_loopbacks;
3740 #endif
3741
3742         return 0;
3743 }
3744
3745 /* Patch for VT1708S */
3746
3747 /* capture mixer elements */
3748 static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3749         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3750         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3751         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3752         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3753         HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
3754         HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3755                          HDA_INPUT),
3756         {
3757                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3758                 /* The multiple "Capture Source" controls confuse alsamixer
3759                  * So call somewhat different..
3760                  */
3761                 /* .name = "Capture Source", */
3762                 .name = "Input Source",
3763                 .count = 1,
3764                 .info = via_mux_enum_info,
3765                 .get = via_mux_enum_get,
3766                 .put = via_mux_enum_put,
3767         },
3768         { } /* end */
3769 };
3770
3771 static struct hda_verb vt1708S_volume_init_verbs[] = {
3772         /* Unmute ADC0-1 and set the default input to mic-in */
3773         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3774         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3775
3776         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
3777          * analog-loopback mixer widget */
3778         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3779         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3780         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3781         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3782         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3783         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3784
3785         /* Setup default input of PW4 to MW0 */
3786         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3787         /* PW9, PW10  Output enable */
3788         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3789         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3790         /* Enable Mic Boost Volume backdoor */
3791         {0x1, 0xf98, 0x1},
3792         /* don't bybass mixer */
3793         {0x1, 0xf88, 0xc0},
3794         { }
3795 };
3796
3797 static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3798         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3799          AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3800         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3801         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3802         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3803         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3804         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3805         {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3806         {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3807         { }
3808 };
3809
3810 static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3811         .substreams = 2,
3812         .channels_min = 2,
3813         .channels_max = 8,
3814         .nid = 0x10, /* NID to query formats and rates */
3815         .ops = {
3816                 .open = via_playback_pcm_open,
3817                 .prepare = via_playback_multi_pcm_prepare,
3818                 .cleanup = via_playback_multi_pcm_cleanup,
3819                 .close = via_pcm_open_close
3820         },
3821 };
3822
3823 static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3824         .substreams = 2,
3825         .channels_min = 2,
3826         .channels_max = 2,
3827         .nid = 0x13, /* NID to query formats and rates */
3828         .ops = {
3829                 .open = via_pcm_open_close,
3830                 .prepare = via_capture_pcm_prepare,
3831                 .cleanup = via_capture_pcm_cleanup,
3832                 .close = via_pcm_open_close
3833         },
3834 };
3835
3836 static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3837         .substreams = 1,
3838         .channels_min = 2,
3839         .channels_max = 2,
3840         /* NID is set in via_build_pcms */
3841         .ops = {
3842                 .open = via_dig_playback_pcm_open,
3843                 .close = via_dig_playback_pcm_close,
3844                 .prepare = via_dig_playback_pcm_prepare,
3845                 .cleanup = via_dig_playback_pcm_cleanup
3846         },
3847 };
3848
3849 /* fill in the dac_nids table from the parsed pin configuration */
3850 static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3851                                      const struct auto_pin_cfg *cfg)
3852 {
3853         int i;
3854         hda_nid_t nid;
3855
3856         spec->multiout.num_dacs = cfg->line_outs;
3857
3858         spec->multiout.dac_nids = spec->private_dac_nids;
3859
3860         for (i = 0; i < 4; i++) {
3861                 nid = cfg->line_out_pins[i];
3862                 if (nid) {
3863                         /* config dac list */
3864                         switch (i) {
3865                         case AUTO_SEQ_FRONT:
3866                                 spec->multiout.dac_nids[i] = 0x10;
3867                                 break;
3868                         case AUTO_SEQ_CENLFE:
3869                                 spec->multiout.dac_nids[i] = 0x24;
3870                                 break;
3871                         case AUTO_SEQ_SURROUND:
3872                                 spec->multiout.dac_nids[i] = 0x11;
3873                                 break;
3874                         case AUTO_SEQ_SIDE:
3875                                 spec->multiout.dac_nids[i] = 0x25;
3876                                 break;
3877                         }
3878                 }
3879         }
3880
3881         /* for Smart 5.1, line/mic inputs double as output pins */
3882         if (cfg->line_outs == 1) {
3883                 spec->multiout.num_dacs = 3;
3884                 spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3885                 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3886         }
3887
3888         return 0;
3889 }
3890
3891 /* add playback controls from the parsed DAC table */
3892 static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3893                                              const struct auto_pin_cfg *cfg)
3894 {
3895         char name[32];
3896         static const char * const chname[4] = {
3897                 "Front", "Surround", "C/LFE", "Side"
3898         };
3899         hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
3900         hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
3901         hda_nid_t nid, nid_vol, nid_mute;
3902         int i, err;
3903
3904         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3905                 nid = cfg->line_out_pins[i];
3906
3907                 /* for Smart 5.1, there are always at least six channels */
3908                 if (!nid && i > AUTO_SEQ_CENLFE)
3909                         continue;
3910
3911                 nid_vol = nid_vols[i];
3912                 nid_mute = nid_mutes[i];
3913
3914                 if (i == AUTO_SEQ_CENLFE) {
3915                         /* Center/LFE */
3916                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3917                                               "Center Playback Volume",
3918                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3919                                                                   HDA_OUTPUT));
3920                         if (err < 0)
3921                                 return err;
3922                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3923                                               "LFE Playback Volume",
3924                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3925                                                                   HDA_OUTPUT));
3926                         if (err < 0)
3927                                 return err;
3928                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3929                                               "Center Playback Switch",
3930                                               HDA_COMPOSE_AMP_VAL(nid_mute,
3931                                                                   1, 0,
3932                                                                   HDA_OUTPUT));
3933                         if (err < 0)
3934                                 return err;
3935                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3936                                               "LFE Playback Switch",
3937                                               HDA_COMPOSE_AMP_VAL(nid_mute,
3938                                                                   2, 0,
3939                                                                   HDA_OUTPUT));
3940                         if (err < 0)
3941                                 return err;
3942                 } else if (i == AUTO_SEQ_FRONT) {
3943                         /* add control to mixer index 0 */
3944                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3945                                               "Master Front Playback Volume",
3946                                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3947                                                                   HDA_INPUT));
3948                         if (err < 0)
3949                                 return err;
3950                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3951                                               "Master Front Playback Switch",
3952                                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3953                                                                   HDA_INPUT));
3954                         if (err < 0)
3955                                 return err;
3956
3957                         /* Front */
3958                         sprintf(name, "%s Playback Volume", chname[i]);
3959                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3960                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3961                                                                   HDA_OUTPUT));
3962                         if (err < 0)
3963                                 return err;
3964                         sprintf(name, "%s Playback Switch", chname[i]);
3965                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3966                                               HDA_COMPOSE_AMP_VAL(nid_mute,
3967                                                                   3, 0,
3968                                                                   HDA_OUTPUT));
3969                         if (err < 0)
3970                                 return err;
3971                 } else {
3972                         sprintf(name, "%s Playback Volume", chname[i]);
3973                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3974                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3975                                                                   HDA_OUTPUT));
3976                         if (err < 0)
3977                                 return err;
3978                         sprintf(name, "%s Playback Switch", chname[i]);
3979                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3980                                               HDA_COMPOSE_AMP_VAL(nid_mute,
3981                                                                   3, 0,
3982                                                                   HDA_OUTPUT));
3983                         if (err < 0)
3984                                 return err;
3985                 }
3986         }
3987
3988         return 0;
3989 }
3990
3991 static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3992 {
3993         int err;
3994
3995         if (!pin)
3996                 return 0;
3997
3998         spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
3999         spec->hp_independent_mode_index = 1;
4000
4001         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4002                               "Headphone Playback Volume",
4003                               HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
4004         if (err < 0)
4005                 return err;
4006
4007         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4008                               "Headphone Playback Switch",
4009                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4010         if (err < 0)
4011                 return err;
4012
4013         create_hp_imux(spec);
4014
4015         return 0;
4016 }
4017
4018 /* create playback/capture controls for input pins */
4019 static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
4020                                                 const struct auto_pin_cfg *cfg)
4021 {
4022         static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
4023         return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
4024                                                 ARRAY_SIZE(pin_idxs));
4025 }
4026
4027 /* fill out digital output widgets; one for master and one for slave outputs */
4028 static void fill_dig_outs(struct hda_codec *codec)
4029 {
4030         struct via_spec *spec = codec->spec;
4031         int i;
4032
4033         for (i = 0; i < spec->autocfg.dig_outs; i++) {
4034                 hda_nid_t nid;
4035                 int conn;
4036
4037                 nid = spec->autocfg.dig_out_pins[i];
4038                 if (!nid)
4039                         continue;
4040                 conn = snd_hda_get_connections(codec, nid, &nid, 1);
4041                 if (conn < 1)
4042                         continue;
4043                 if (!spec->multiout.dig_out_nid)
4044                         spec->multiout.dig_out_nid = nid;
4045                 else {
4046                         spec->slave_dig_outs[0] = nid;
4047                         break; /* at most two dig outs */
4048                 }
4049         }
4050 }
4051
4052 static int vt1708S_parse_auto_config(struct hda_codec *codec)
4053 {
4054         struct via_spec *spec = codec->spec;
4055         int err;
4056
4057         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4058         if (err < 0)
4059                 return err;
4060         err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
4061         if (err < 0)
4062                 return err;
4063         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4064                 return 0; /* can't find valid BIOS pin config */
4065
4066         err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4067         if (err < 0)
4068                 return err;
4069         err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4070         if (err < 0)
4071                 return err;
4072         err = vt1708S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4073         if (err < 0)
4074                 return err;
4075
4076         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4077
4078         fill_dig_outs(codec);
4079
4080         if (spec->kctls.list)
4081                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4082
4083         spec->input_mux = &spec->private_imux[0];
4084
4085         if (spec->hp_mux)
4086                 via_hp_build(codec);
4087
4088         via_smart51_build(spec);
4089         return 1;
4090 }
4091
4092 #ifdef CONFIG_SND_HDA_POWER_SAVE
4093 static struct hda_amp_list vt1708S_loopbacks[] = {
4094         { 0x16, HDA_INPUT, 1 },
4095         { 0x16, HDA_INPUT, 2 },
4096         { 0x16, HDA_INPUT, 3 },
4097         { 0x16, HDA_INPUT, 4 },
4098         { } /* end */
4099 };
4100 #endif
4101
4102 static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
4103                                int offset, int num_steps, int step_size)
4104 {
4105         snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
4106                                   (offset << AC_AMPCAP_OFFSET_SHIFT) |
4107                                   (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
4108                                   (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
4109                                   (0 << AC_AMPCAP_MUTE_SHIFT));
4110 }
4111
4112 static int patch_vt1708S(struct hda_codec *codec)
4113 {
4114         struct via_spec *spec;
4115         int err;
4116
4117         /* create a codec specific record */
4118         spec = via_new_spec(codec);
4119         if (spec == NULL)
4120                 return -ENOMEM;
4121
4122         /* automatic parse from the BIOS config */
4123         err = vt1708S_parse_auto_config(codec);
4124         if (err < 0) {
4125                 via_free(codec);
4126                 return err;
4127         } else if (!err) {
4128                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4129                        "from BIOS.  Using genenic mode...\n");
4130         }
4131
4132         spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
4133         spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
4134
4135         if (codec->vendor_id == 0x11060440)
4136                 spec->stream_name_analog = "VT1818S Analog";
4137         else
4138                 spec->stream_name_analog = "VT1708S Analog";
4139         spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
4140         spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
4141
4142         if (codec->vendor_id == 0x11060440)
4143                 spec->stream_name_digital = "VT1818S Digital";
4144         else
4145                 spec->stream_name_digital = "VT1708S Digital";
4146         spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
4147
4148         if (!spec->adc_nids && spec->input_mux) {
4149                 spec->adc_nids = vt1708S_adc_nids;
4150                 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
4151                 get_mux_nids(codec);
4152                 override_mic_boost(codec, 0x1a, 0, 3, 40);
4153                 override_mic_boost(codec, 0x1e, 0, 3, 40);
4154                 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
4155                 spec->num_mixers++;
4156         }
4157
4158         codec->patch_ops = via_patch_ops;
4159
4160         codec->patch_ops.init = via_auto_init;
4161         codec->patch_ops.unsol_event = via_unsol_event;
4162 #ifdef CONFIG_SND_HDA_POWER_SAVE
4163         spec->loopback.amplist = vt1708S_loopbacks;
4164 #endif
4165
4166         /* correct names for VT1708BCE */
4167         if (get_codec_type(codec) == VT1708BCE) {
4168                 kfree(codec->chip_name);
4169                 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
4170                 snprintf(codec->bus->card->mixername,
4171                          sizeof(codec->bus->card->mixername),
4172                          "%s %s", codec->vendor_name, codec->chip_name);
4173                 spec->stream_name_analog = "VT1708BCE Analog";
4174                 spec->stream_name_digital = "VT1708BCE Digital";
4175         }
4176         return 0;
4177 }
4178
4179 /* Patch for VT1702 */
4180
4181 /* capture mixer elements */
4182 static struct snd_kcontrol_new vt1702_capture_mixer[] = {
4183         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
4184         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
4185         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
4186         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
4187         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
4188         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
4189         HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
4190                          HDA_INPUT),
4191         {
4192                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4193                 /* The multiple "Capture Source" controls confuse alsamixer
4194                  * So call somewhat different..
4195                  */
4196                 /* .name = "Capture Source", */
4197                 .name = "Input Source",
4198                 .count = 1,
4199                 .info = via_mux_enum_info,
4200                 .get = via_mux_enum_get,
4201                 .put = via_mux_enum_put,
4202         },
4203         { } /* end */
4204 };
4205
4206 static struct hda_verb vt1702_volume_init_verbs[] = {
4207         /*
4208          * Unmute ADC0-1 and set the default input to mic-in
4209          */
4210         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4211         {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4212         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4213
4214
4215         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4216          * mixer widget
4217          */
4218         /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
4219         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4220         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4221         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4222         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4223         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4224
4225         /* Setup default input of PW4 to MW0 */
4226         {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
4227         /* PW6 PW7 Output enable */
4228         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4229         {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4230         /* mixer enable */
4231         {0x1, 0xF88, 0x3},
4232         /* GPIO 0~2 */
4233         {0x1, 0xF82, 0x3F},
4234         { }
4235 };
4236
4237 static struct hda_verb vt1702_uniwill_init_verbs[] = {
4238         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
4239          AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4240         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4241         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4242         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4243         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4244         { }
4245 };
4246
4247 static struct hda_pcm_stream vt1702_pcm_analog_playback = {
4248         .substreams = 2,
4249         .channels_min = 2,
4250         .channels_max = 2,
4251         .nid = 0x10, /* NID to query formats and rates */
4252         .ops = {
4253                 .open = via_playback_pcm_open,
4254                 .prepare = via_playback_multi_pcm_prepare,
4255                 .cleanup = via_playback_multi_pcm_cleanup,
4256                 .close = via_pcm_open_close
4257         },
4258 };
4259
4260 static struct hda_pcm_stream vt1702_pcm_analog_capture = {
4261         .substreams = 3,
4262         .channels_min = 2,
4263         .channels_max = 2,
4264         .nid = 0x12, /* NID to query formats and rates */
4265         .ops = {
4266                 .open = via_pcm_open_close,
4267                 .prepare = via_capture_pcm_prepare,
4268                 .cleanup = via_capture_pcm_cleanup,
4269                 .close = via_pcm_open_close
4270         },
4271 };
4272
4273 static struct hda_pcm_stream vt1702_pcm_digital_playback = {
4274         .substreams = 2,
4275         .channels_min = 2,
4276         .channels_max = 2,
4277         /* NID is set in via_build_pcms */
4278         .ops = {
4279                 .open = via_dig_playback_pcm_open,
4280                 .close = via_dig_playback_pcm_close,
4281                 .prepare = via_dig_playback_pcm_prepare,
4282                 .cleanup = via_dig_playback_pcm_cleanup
4283         },
4284 };
4285
4286 /* fill in the dac_nids table from the parsed pin configuration */
4287 static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
4288                                      const struct auto_pin_cfg *cfg)
4289 {
4290         spec->multiout.num_dacs = 1;
4291         spec->multiout.dac_nids = spec->private_dac_nids;
4292
4293         if (cfg->line_out_pins[0]) {
4294                 /* config dac list */
4295                 spec->multiout.dac_nids[0] = 0x10;
4296         }
4297
4298         return 0;
4299 }
4300
4301 /* add playback controls from the parsed DAC table */
4302 static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
4303                                              const struct auto_pin_cfg *cfg)
4304 {
4305         int err;
4306
4307         if (!cfg->line_out_pins[0])
4308                 return -1;
4309
4310         /* add control to mixer index 0 */
4311         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4312                               "Master Front Playback Volume",
4313                               HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4314         if (err < 0)
4315                 return err;
4316         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4317                               "Master Front Playback Switch",
4318                               HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4319         if (err < 0)
4320                 return err;
4321
4322         /* Front */
4323         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4324                               "Front Playback Volume",
4325                               HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
4326         if (err < 0)
4327                 return err;
4328         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4329                               "Front Playback Switch",
4330                               HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
4331         if (err < 0)
4332                 return err;
4333
4334         return 0;
4335 }
4336
4337 static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4338 {
4339         int err, i;
4340         struct hda_input_mux *imux;
4341         static const char * const texts[] = { "ON", "OFF", NULL};
4342         if (!pin)
4343                 return 0;
4344         spec->multiout.hp_nid = 0x1D;
4345         spec->hp_independent_mode_index = 0;
4346
4347         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4348                               "Headphone Playback Volume",
4349                               HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
4350         if (err < 0)
4351                 return err;
4352
4353         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4354                               "Headphone Playback Switch",
4355                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4356         if (err < 0)
4357                 return err;
4358
4359         imux = &spec->private_imux[1];
4360
4361         /* for hp mode select */
4362         for (i = 0; texts[i]; i++)
4363                 snd_hda_add_imux_item(imux, texts[i], i, NULL);
4364
4365         spec->hp_mux = &spec->private_imux[1];
4366         return 0;
4367 }
4368
4369 /* create playback/capture controls for input pins */
4370 static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec,
4371                                                 const struct auto_pin_cfg *cfg)
4372 {
4373         static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
4374         return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs,
4375                                                 ARRAY_SIZE(pin_idxs));
4376 }
4377
4378 static int vt1702_parse_auto_config(struct hda_codec *codec)
4379 {
4380         struct via_spec *spec = codec->spec;
4381         int err;
4382
4383         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4384         if (err < 0)
4385                 return err;
4386         err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
4387         if (err < 0)
4388                 return err;
4389         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4390                 return 0; /* can't find valid BIOS pin config */
4391
4392         err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
4393         if (err < 0)
4394                 return err;
4395         err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4396         if (err < 0)
4397                 return err;
4398         /* limit AA path volume to 0 dB */
4399         snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
4400                                   (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4401                                   (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4402                                   (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4403                                   (1 << AC_AMPCAP_MUTE_SHIFT));
4404         err = vt1702_auto_create_analog_input_ctls(codec, &spec->autocfg);
4405         if (err < 0)
4406                 return err;
4407
4408         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4409
4410         fill_dig_outs(codec);
4411
4412         if (spec->kctls.list)
4413                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4414
4415         spec->input_mux = &spec->private_imux[0];
4416
4417         if (spec->hp_mux)
4418                 via_hp_build(codec);
4419
4420         return 1;
4421 }
4422
4423 #ifdef CONFIG_SND_HDA_POWER_SAVE
4424 static struct hda_amp_list vt1702_loopbacks[] = {
4425         { 0x1A, HDA_INPUT, 1 },
4426         { 0x1A, HDA_INPUT, 2 },
4427         { 0x1A, HDA_INPUT, 3 },
4428         { 0x1A, HDA_INPUT, 4 },
4429         { } /* end */
4430 };
4431 #endif
4432
4433 static int patch_vt1702(struct hda_codec *codec)
4434 {
4435         struct via_spec *spec;
4436         int err;
4437
4438         /* create a codec specific record */
4439         spec = via_new_spec(codec);
4440         if (spec == NULL)
4441                 return -ENOMEM;
4442
4443         /* automatic parse from the BIOS config */
4444         err = vt1702_parse_auto_config(codec);
4445         if (err < 0) {
4446                 via_free(codec);
4447                 return err;
4448         } else if (!err) {
4449                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4450                        "from BIOS.  Using genenic mode...\n");
4451         }
4452
4453         spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
4454         spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
4455
4456         spec->stream_name_analog = "VT1702 Analog";
4457         spec->stream_analog_playback = &vt1702_pcm_analog_playback;
4458         spec->stream_analog_capture = &vt1702_pcm_analog_capture;
4459
4460         spec->stream_name_digital = "VT1702 Digital";
4461         spec->stream_digital_playback = &vt1702_pcm_digital_playback;
4462
4463         if (!spec->adc_nids && spec->input_mux) {
4464                 spec->adc_nids = vt1702_adc_nids;
4465                 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
4466                 get_mux_nids(codec);
4467                 spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
4468                 spec->num_mixers++;
4469         }
4470
4471         codec->patch_ops = via_patch_ops;
4472
4473         codec->patch_ops.init = via_auto_init;
4474         codec->patch_ops.unsol_event = via_unsol_event;
4475 #ifdef CONFIG_SND_HDA_POWER_SAVE
4476         spec->loopback.amplist = vt1702_loopbacks;
4477 #endif
4478
4479         return 0;
4480 }
4481
4482 /* Patch for VT1718S */
4483
4484 /* capture mixer elements */
4485 static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4486         HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4487         HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4488         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
4489         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
4490         HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
4491         HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
4492                          HDA_INPUT),
4493         {
4494                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4495                 /* The multiple "Capture Source" controls confuse alsamixer
4496                  * So call somewhat different..
4497                  */
4498                 .name = "Input Source",
4499                 .count = 2,
4500                 .info = via_mux_enum_info,
4501                 .get = via_mux_enum_get,
4502                 .put = via_mux_enum_put,
4503         },
4504         { } /* end */
4505 };
4506
4507 static struct hda_verb vt1718S_volume_init_verbs[] = {
4508         /*
4509          * Unmute ADC0-1 and set the default input to mic-in
4510          */
4511         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4512         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4513
4514
4515         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4516          * mixer widget
4517          */
4518         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4519         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4520         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4521         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4522         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4523         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4524
4525         /* Setup default input of Front HP to MW9 */
4526         {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4527         /* PW9 PW10 Output enable */
4528         {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4529         {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4530         /* PW11 Input enable */
4531         {0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN},
4532         /* Enable Boost Volume backdoor */
4533         {0x1, 0xf88, 0x8},
4534         /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4535         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4536         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4537         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4538         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4539         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4540         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4541         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4542         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4543         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4544         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4545         /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4546         {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4547         {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4548         /* Unmute MW4's index 0 */
4549         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4550         { }
4551 };
4552
4553
4554 static struct hda_verb vt1718S_uniwill_init_verbs[] = {
4555         {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4556          AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4557         {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4558         {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4559         {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4560         {0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4561         {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4562         {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4563         {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4564         { }
4565 };
4566
4567 static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4568         .substreams = 2,
4569         .channels_min = 2,
4570         .channels_max = 10,
4571         .nid = 0x8, /* NID to query formats and rates */
4572         .ops = {
4573                 .open = via_playback_pcm_open,
4574                 .prepare = via_playback_multi_pcm_prepare,
4575                 .cleanup = via_playback_multi_pcm_cleanup,
4576                 .close = via_pcm_open_close,
4577         },
4578 };
4579
4580 static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4581         .substreams = 2,
4582         .channels_min = 2,
4583         .channels_max = 2,
4584         .nid = 0x10, /* NID to query formats and rates */
4585         .ops = {
4586                 .open = via_pcm_open_close,
4587                 .prepare = via_capture_pcm_prepare,
4588                 .cleanup = via_capture_pcm_cleanup,
4589                 .close = via_pcm_open_close,
4590         },
4591 };
4592
4593 static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4594         .substreams = 2,
4595         .channels_min = 2,
4596         .channels_max = 2,
4597         /* NID is set in via_build_pcms */
4598         .ops = {
4599                 .open = via_dig_playback_pcm_open,
4600                 .close = via_dig_playback_pcm_close,
4601                 .prepare = via_dig_playback_pcm_prepare,
4602                 .cleanup = via_dig_playback_pcm_cleanup
4603         },
4604 };
4605
4606 static struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4607         .substreams = 1,
4608         .channels_min = 2,
4609         .channels_max = 2,
4610 };
4611
4612 /* fill in the dac_nids table from the parsed pin configuration */
4613 static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4614                                      const struct auto_pin_cfg *cfg)
4615 {
4616         int i;
4617         hda_nid_t nid;
4618
4619         spec->multiout.num_dacs = cfg->line_outs;
4620
4621         spec->multiout.dac_nids = spec->private_dac_nids;
4622
4623         for (i = 0; i < 4; i++) {
4624                 nid = cfg->line_out_pins[i];
4625                 if (nid) {
4626                         /* config dac list */
4627                         switch (i) {
4628                         case AUTO_SEQ_FRONT:
4629                                 spec->multiout.dac_nids[i] = 0x8;
4630                                 break;
4631                         case AUTO_SEQ_CENLFE:
4632                                 spec->multiout.dac_nids[i] = 0xa;
4633                                 break;
4634                         case AUTO_SEQ_SURROUND:
4635                                 spec->multiout.dac_nids[i] = 0x9;
4636                                 break;
4637                         case AUTO_SEQ_SIDE:
4638                                 spec->multiout.dac_nids[i] = 0xb;
4639                                 break;
4640                         }
4641                 }
4642         }
4643
4644         return 0;
4645 }
4646
4647 /* add playback controls from the parsed DAC table */
4648 static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4649                                              const struct auto_pin_cfg *cfg)
4650 {
4651         char name[32];
4652         static const char * const chname[4] = {
4653                 "Front", "Surround", "C/LFE", "Side"
4654         };
4655         hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4656         hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4657         hda_nid_t nid, nid_vol, nid_mute = 0;
4658         int i, err;
4659
4660         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
4661                 nid = cfg->line_out_pins[i];
4662
4663                 if (!nid)
4664                         continue;
4665                 nid_vol = nid_vols[i];
4666                 nid_mute = nid_mutes[i];
4667
4668                 if (i == AUTO_SEQ_CENLFE) {
4669                         /* Center/LFE */
4670                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4671                                               "Center Playback Volume",
4672                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
4673                                                                   HDA_OUTPUT));
4674                         if (err < 0)
4675                                 return err;
4676                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4677                                               "LFE Playback Volume",
4678                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
4679                                                                   HDA_OUTPUT));
4680                         if (err < 0)
4681                                 return err;
4682                         err = via_add_control(
4683                                 spec, VIA_CTL_WIDGET_MUTE,
4684                                 "Center Playback Switch",
4685                                 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4686                                                     HDA_OUTPUT));
4687                         if (err < 0)
4688                                 return err;
4689                         err = via_add_control(
4690                                 spec, VIA_CTL_WIDGET_MUTE,
4691                                 "LFE Playback Switch",
4692                                 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4693                                                     HDA_OUTPUT));
4694                         if (err < 0)
4695                                 return err;
4696                 } else if (i == AUTO_SEQ_FRONT) {
4697                         /* Front */
4698                         sprintf(name, "%s Playback Volume", chname[i]);
4699                         err = via_add_control(
4700                                 spec, VIA_CTL_WIDGET_VOL, name,
4701                                 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4702                         if (err < 0)
4703                                 return err;
4704                         sprintf(name, "%s Playback Switch", chname[i]);
4705                         err = via_add_control(
4706                                 spec, VIA_CTL_WIDGET_MUTE, name,
4707                                 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4708                                                     HDA_OUTPUT));
4709                         if (err < 0)
4710                                 return err;
4711                 } else {
4712                         sprintf(name, "%s Playback Volume", chname[i]);
4713                         err = via_add_control(
4714                                 spec, VIA_CTL_WIDGET_VOL, name,
4715                                 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4716                         if (err < 0)
4717                                 return err;
4718                         sprintf(name, "%s Playback Switch", chname[i]);
4719                         err = via_add_control(
4720                                 spec, VIA_CTL_WIDGET_MUTE, name,
4721                                 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4722                                                     HDA_OUTPUT));
4723                         if (err < 0)
4724                                 return err;
4725                 }
4726         }
4727         return 0;
4728 }
4729
4730 static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4731 {
4732         int err;
4733
4734         if (!pin)
4735                 return 0;
4736
4737         spec->multiout.hp_nid = 0xc; /* AOW4 */
4738         spec->hp_independent_mode_index = 1;
4739
4740         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4741                               "Headphone Playback Volume",
4742                               HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT));
4743         if (err < 0)
4744                 return err;
4745
4746         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4747                               "Headphone Playback Switch",
4748                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4749         if (err < 0)
4750                 return err;
4751
4752         create_hp_imux(spec);
4753         return 0;
4754 }
4755
4756 /* create playback/capture controls for input pins */
4757 static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec,
4758                                                 const struct auto_pin_cfg *cfg)
4759 {
4760         static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
4761         return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
4762                                                 ARRAY_SIZE(pin_idxs));
4763 }
4764
4765 static int vt1718S_parse_auto_config(struct hda_codec *codec)
4766 {
4767         struct via_spec *spec = codec->spec;
4768         int err;
4769
4770         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4771
4772         if (err < 0)
4773                 return err;
4774         err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg);
4775         if (err < 0)
4776                 return err;
4777         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4778                 return 0; /* can't find valid BIOS pin config */
4779
4780         err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4781         if (err < 0)
4782                 return err;
4783         err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4784         if (err < 0)
4785                 return err;
4786         err = vt1718S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4787         if (err < 0)
4788                 return err;
4789
4790         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4791
4792         fill_dig_outs(codec);
4793
4794         if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428)
4795                 spec->dig_in_nid = 0x13;
4796
4797         if (spec->kctls.list)
4798                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4799
4800         spec->input_mux = &spec->private_imux[0];
4801
4802         if (spec->hp_mux)
4803                 via_hp_build(codec);
4804
4805         via_smart51_build(spec);
4806
4807         return 1;
4808 }
4809
4810 #ifdef CONFIG_SND_HDA_POWER_SAVE
4811 static struct hda_amp_list vt1718S_loopbacks[] = {
4812         { 0x21, HDA_INPUT, 1 },
4813         { 0x21, HDA_INPUT, 2 },
4814         { 0x21, HDA_INPUT, 3 },
4815         { 0x21, HDA_INPUT, 4 },
4816         { } /* end */
4817 };
4818 #endif
4819
4820 static int patch_vt1718S(struct hda_codec *codec)
4821 {
4822         struct via_spec *spec;
4823         int err;
4824
4825         /* create a codec specific record */
4826         spec = via_new_spec(codec);
4827         if (spec == NULL)
4828                 return -ENOMEM;
4829
4830         /* automatic parse from the BIOS config */
4831         err = vt1718S_parse_auto_config(codec);
4832         if (err < 0) {
4833                 via_free(codec);
4834                 return err;
4835         } else if (!err) {
4836                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4837                        "from BIOS.  Using genenic mode...\n");
4838         }
4839
4840         spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs;
4841         spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs;
4842
4843         if (codec->vendor_id == 0x11060441)
4844                 spec->stream_name_analog = "VT2020 Analog";
4845         else if (codec->vendor_id == 0x11064441)
4846                 spec->stream_name_analog = "VT1828S Analog";
4847         else
4848                 spec->stream_name_analog = "VT1718S Analog";
4849         spec->stream_analog_playback = &vt1718S_pcm_analog_playback;
4850         spec->stream_analog_capture = &vt1718S_pcm_analog_capture;
4851
4852         if (codec->vendor_id == 0x11060441)
4853                 spec->stream_name_digital = "VT2020 Digital";
4854         else if (codec->vendor_id == 0x11064441)
4855                 spec->stream_name_digital = "VT1828S Digital";
4856         else
4857                 spec->stream_name_digital = "VT1718S Digital";
4858         spec->stream_digital_playback = &vt1718S_pcm_digital_playback;
4859         if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441)
4860                 spec->stream_digital_capture = &vt1718S_pcm_digital_capture;
4861
4862         if (!spec->adc_nids && spec->input_mux) {
4863                 spec->adc_nids = vt1718S_adc_nids;
4864                 spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
4865                 get_mux_nids(codec);
4866                 override_mic_boost(codec, 0x2b, 0, 3, 40);
4867                 override_mic_boost(codec, 0x29, 0, 3, 40);
4868                 spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
4869                 spec->num_mixers++;
4870         }
4871
4872         codec->patch_ops = via_patch_ops;
4873
4874         codec->patch_ops.init = via_auto_init;
4875         codec->patch_ops.unsol_event = via_unsol_event;
4876
4877 #ifdef CONFIG_SND_HDA_POWER_SAVE
4878         spec->loopback.amplist = vt1718S_loopbacks;
4879 #endif
4880
4881         return 0;
4882 }
4883
4884 /* Patch for VT1716S */
4885
4886 static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
4887                             struct snd_ctl_elem_info *uinfo)
4888 {
4889         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
4890         uinfo->count = 1;
4891         uinfo->value.integer.min = 0;
4892         uinfo->value.integer.max = 1;
4893         return 0;
4894 }
4895
4896 static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
4897                            struct snd_ctl_elem_value *ucontrol)
4898 {
4899         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4900         int index = 0;
4901
4902         index = snd_hda_codec_read(codec, 0x26, 0,
4903                                                AC_VERB_GET_CONNECT_SEL, 0);
4904         if (index != -1)
4905                 *ucontrol->value.integer.value = index;
4906
4907         return 0;
4908 }
4909
4910 static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4911                            struct snd_ctl_elem_value *ucontrol)
4912 {
4913         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4914         struct via_spec *spec = codec->spec;
4915         int index = *ucontrol->value.integer.value;
4916
4917         snd_hda_codec_write(codec, 0x26, 0,
4918                                                AC_VERB_SET_CONNECT_SEL, index);
4919         spec->dmic_enabled = index;
4920         set_jack_power_state(codec);
4921
4922         return 1;
4923 }
4924
4925 /* capture mixer elements */
4926 static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
4927         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
4928         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
4929         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
4930         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
4931         HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
4932         HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
4933                          HDA_INPUT),
4934         {
4935                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4936                 .name = "Input Source",
4937                 .count = 1,
4938                 .info = via_mux_enum_info,
4939                 .get = via_mux_enum_get,
4940                 .put = via_mux_enum_put,
4941         },
4942         { } /* end */
4943 };
4944
4945 static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4946         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
4947         {
4948          .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4949          .name = "Digital Mic Capture Switch",
4950          .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
4951          .count = 1,
4952          .info = vt1716s_dmic_info,
4953          .get = vt1716s_dmic_get,
4954          .put = vt1716s_dmic_put,
4955          },
4956         {}                      /* end */
4957 };
4958
4959
4960 /* mono-out mixer elements */
4961 static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
4962         HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
4963         { } /* end */
4964 };
4965
4966 static struct hda_verb vt1716S_volume_init_verbs[] = {
4967         /*
4968          * Unmute ADC0-1 and set the default input to mic-in
4969          */
4970         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4971         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4972
4973
4974         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4975          * mixer widget
4976          */
4977         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4978         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4979         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4980         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4981         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4982         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4983
4984         /* MUX Indices: Stereo Mixer = 5 */
4985         {0x17, AC_VERB_SET_CONNECT_SEL, 0x5},
4986
4987         /* Setup default input of PW4 to MW0 */
4988         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
4989
4990         /* Setup default input of SW1 as MW0 */
4991         {0x18, AC_VERB_SET_CONNECT_SEL, 0x1},
4992
4993         /* Setup default input of SW4 as AOW0 */
4994         {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4995
4996         /* PW9 PW10 Output enable */
4997         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4998         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4999
5000         /* Unmute SW1, PW12 */
5001         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5002         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5003         /* PW12 Output enable */
5004         {0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5005         /* Enable Boost Volume backdoor */
5006         {0x1, 0xf8a, 0x80},
5007         /* don't bybass mixer */
5008         {0x1, 0xf88, 0xc0},
5009         /* Enable mono output */
5010         {0x1, 0xf90, 0x08},
5011         { }
5012 };
5013
5014
5015 static struct hda_verb vt1716S_uniwill_init_verbs[] = {
5016         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
5017          AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
5018         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5019         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5020         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5021         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE,
5022          AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT},
5023         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5024         {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5025         { }
5026 };
5027
5028 static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5029         .substreams = 2,
5030         .channels_min = 2,
5031         .channels_max = 6,
5032         .nid = 0x10, /* NID to query formats and rates */
5033         .ops = {
5034                 .open = via_playback_pcm_open,
5035                 .prepare = via_playback_multi_pcm_prepare,
5036                 .cleanup = via_playback_multi_pcm_cleanup,
5037                 .close = via_pcm_open_close,
5038         },
5039 };
5040
5041 static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5042         .substreams = 2,
5043         .channels_min = 2,
5044         .channels_max = 2,
5045         .nid = 0x13, /* NID to query formats and rates */
5046         .ops = {
5047                 .open = via_pcm_open_close,
5048                 .prepare = via_capture_pcm_prepare,
5049                 .cleanup = via_capture_pcm_cleanup,
5050                 .close = via_pcm_open_close,
5051         },
5052 };
5053
5054 static struct hda_pcm_stream vt1716S_pcm_digital_playback = {
5055         .substreams = 2,
5056         .channels_min = 2,
5057         .channels_max = 2,
5058         /* NID is set in via_build_pcms */
5059         .ops = {
5060                 .open = via_dig_playback_pcm_open,
5061                 .close = via_dig_playback_pcm_close,
5062                 .prepare = via_dig_playback_pcm_prepare,
5063                 .cleanup = via_dig_playback_pcm_cleanup
5064         },
5065 };
5066
5067 /* fill in the dac_nids table from the parsed pin configuration */
5068 static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
5069                                       const struct auto_pin_cfg *cfg)
5070 {       int i;
5071         hda_nid_t nid;
5072
5073         spec->multiout.num_dacs = cfg->line_outs;
5074
5075         spec->multiout.dac_nids = spec->private_dac_nids;
5076
5077         for (i = 0; i < 3; i++) {
5078                 nid = cfg->line_out_pins[i];
5079                 if (nid) {
5080                         /* config dac list */
5081                         switch (i) {
5082                         case AUTO_SEQ_FRONT:
5083                                 spec->multiout.dac_nids[i] = 0x10;
5084                                 break;
5085                         case AUTO_SEQ_CENLFE:
5086                                 spec->multiout.dac_nids[i] = 0x25;
5087                                 break;
5088                         case AUTO_SEQ_SURROUND:
5089                                 spec->multiout.dac_nids[i] = 0x11;
5090                                 break;
5091                         }
5092                 }
5093         }
5094
5095         return 0;
5096 }
5097
5098 /* add playback controls from the parsed DAC table */
5099 static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
5100                                               const struct auto_pin_cfg *cfg)
5101 {
5102         char name[32];
5103         static const char * const chname[3] = {
5104                 "Front", "Surround", "C/LFE"
5105         };
5106         hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
5107         hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
5108         hda_nid_t nid, nid_vol, nid_mute;
5109         int i, err;
5110
5111         for (i = 0; i <= AUTO_SEQ_CENLFE; i++) {
5112                 nid = cfg->line_out_pins[i];
5113
5114                 if (!nid)
5115                         continue;
5116
5117                 nid_vol = nid_vols[i];
5118                 nid_mute = nid_mutes[i];
5119
5120                 if (i == AUTO_SEQ_CENLFE) {
5121                         err = via_add_control(
5122                                 spec, VIA_CTL_WIDGET_VOL,
5123                                 "Center Playback Volume",
5124                                 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
5125                         if (err < 0)
5126                                 return err;
5127                         err = via_add_control(
5128                                 spec, VIA_CTL_WIDGET_VOL,
5129                                 "LFE Playback Volume",
5130                                 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
5131                         if (err < 0)
5132                                 return err;
5133                         err = via_add_control(
5134                                 spec, VIA_CTL_WIDGET_MUTE,
5135                                 "Center Playback Switch",
5136                                 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
5137                                                     HDA_OUTPUT));
5138                         if (err < 0)
5139                                 return err;
5140                         err = via_add_control(
5141                                 spec, VIA_CTL_WIDGET_MUTE,
5142                                 "LFE Playback Switch",
5143                                 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
5144                                                     HDA_OUTPUT));
5145                         if (err < 0)
5146                                 return err;
5147                 } else if (i == AUTO_SEQ_FRONT) {
5148
5149                         err = via_add_control(
5150                                 spec, VIA_CTL_WIDGET_VOL,
5151                                 "Master Front Playback Volume",
5152                                 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5153                         if (err < 0)
5154                                 return err;
5155                         err = via_add_control(
5156                                 spec, VIA_CTL_WIDGET_MUTE,
5157                                 "Master Front Playback Switch",
5158                                 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5159                         if (err < 0)
5160                                 return err;
5161
5162                         sprintf(name, "%s Playback Volume", chname[i]);
5163                         err = via_add_control(
5164                                 spec, VIA_CTL_WIDGET_VOL, name,
5165                                 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5166                         if (err < 0)
5167                                 return err;
5168                         sprintf(name, "%s Playback Switch", chname[i]);
5169                         err = via_add_control(
5170                                 spec, VIA_CTL_WIDGET_MUTE, name,
5171                                 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5172                                                     HDA_OUTPUT));
5173                         if (err < 0)
5174                                 return err;
5175                 } else {
5176                         sprintf(name, "%s Playback Volume", chname[i]);
5177                         err = via_add_control(
5178                                 spec, VIA_CTL_WIDGET_VOL, name,
5179                                 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5180                         if (err < 0)
5181                                 return err;
5182                         sprintf(name, "%s Playback Switch", chname[i]);
5183                         err = via_add_control(
5184                                 spec, VIA_CTL_WIDGET_MUTE, name,
5185                                 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5186                                                     HDA_OUTPUT));
5187                         if (err < 0)
5188                                 return err;
5189                 }
5190         }
5191         return 0;
5192 }
5193
5194 static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5195 {
5196         int err;
5197
5198         if (!pin)
5199                 return 0;
5200
5201         spec->multiout.hp_nid = 0x25; /* AOW3 */
5202         spec->hp_independent_mode_index = 1;
5203
5204         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5205                               "Headphone Playback Volume",
5206                               HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5207         if (err < 0)
5208                 return err;
5209
5210         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5211                               "Headphone Playback Switch",
5212                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5213         if (err < 0)
5214                 return err;
5215
5216         create_hp_imux(spec);
5217         return 0;
5218 }
5219
5220 /* create playback/capture controls for input pins */
5221 static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec,
5222                                                 const struct auto_pin_cfg *cfg)
5223 {
5224         static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
5225         return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
5226                                                 ARRAY_SIZE(pin_idxs));
5227 }
5228
5229 static int vt1716S_parse_auto_config(struct hda_codec *codec)
5230 {
5231         struct via_spec *spec = codec->spec;
5232         int err;
5233
5234         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5235         if (err < 0)
5236                 return err;
5237         err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg);
5238         if (err < 0)
5239                 return err;
5240         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5241                 return 0; /* can't find valid BIOS pin config */
5242
5243         err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg);
5244         if (err < 0)
5245                 return err;
5246         err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5247         if (err < 0)
5248                 return err;
5249         err = vt1716S_auto_create_analog_input_ctls(codec, &spec->autocfg);
5250         if (err < 0)
5251                 return err;
5252
5253         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5254
5255         fill_dig_outs(codec);
5256
5257         if (spec->kctls.list)
5258                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5259
5260         spec->input_mux = &spec->private_imux[0];
5261
5262         if (spec->hp_mux)
5263                 via_hp_build(codec);
5264
5265         via_smart51_build(spec);
5266
5267         return 1;
5268 }
5269
5270 #ifdef CONFIG_SND_HDA_POWER_SAVE
5271 static struct hda_amp_list vt1716S_loopbacks[] = {
5272         { 0x16, HDA_INPUT, 1 },
5273         { 0x16, HDA_INPUT, 2 },
5274         { 0x16, HDA_INPUT, 3 },
5275         { 0x16, HDA_INPUT, 4 },
5276         { } /* end */
5277 };
5278 #endif
5279
5280 static int patch_vt1716S(struct hda_codec *codec)
5281 {
5282         struct via_spec *spec;
5283         int err;
5284
5285         /* create a codec specific record */
5286         spec = via_new_spec(codec);
5287         if (spec == NULL)
5288                 return -ENOMEM;
5289
5290         /* automatic parse from the BIOS config */
5291         err = vt1716S_parse_auto_config(codec);
5292         if (err < 0) {
5293                 via_free(codec);
5294                 return err;
5295         } else if (!err) {
5296                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5297                        "from BIOS.  Using genenic mode...\n");
5298         }
5299
5300         spec->init_verbs[spec->num_iverbs++]  = vt1716S_volume_init_verbs;
5301         spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs;
5302
5303         spec->stream_name_analog = "VT1716S Analog";
5304         spec->stream_analog_playback = &vt1716S_pcm_analog_playback;
5305         spec->stream_analog_capture = &vt1716S_pcm_analog_capture;
5306
5307         spec->stream_name_digital = "VT1716S Digital";
5308         spec->stream_digital_playback = &vt1716S_pcm_digital_playback;
5309
5310         if (!spec->adc_nids && spec->input_mux) {
5311                 spec->adc_nids = vt1716S_adc_nids;
5312                 spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids);
5313                 get_mux_nids(codec);
5314                 override_mic_boost(codec, 0x1a, 0, 3, 40);
5315                 override_mic_boost(codec, 0x1e, 0, 3, 40);
5316                 spec->mixers[spec->num_mixers] = vt1716S_capture_mixer;
5317                 spec->num_mixers++;
5318         }
5319
5320         spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
5321         spec->num_mixers++;
5322
5323         spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
5324
5325         codec->patch_ops = via_patch_ops;
5326
5327         codec->patch_ops.init = via_auto_init;
5328         codec->patch_ops.unsol_event = via_unsol_event;
5329
5330 #ifdef CONFIG_SND_HDA_POWER_SAVE
5331         spec->loopback.amplist = vt1716S_loopbacks;
5332 #endif
5333
5334         return 0;
5335 }
5336
5337 /* for vt2002P */
5338
5339 /* capture mixer elements */
5340 static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5341         HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5342         HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5343         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5344         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5345         HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5346         HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
5347                          HDA_INPUT),
5348         {
5349                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5350                 /* The multiple "Capture Source" controls confuse alsamixer
5351                  * So call somewhat different..
5352                  */
5353                 /* .name = "Capture Source", */
5354                 .name = "Input Source",
5355                 .count = 2,
5356                 .info = via_mux_enum_info,
5357                 .get = via_mux_enum_get,
5358                 .put = via_mux_enum_put,
5359         },
5360         { } /* end */
5361 };
5362
5363 static struct hda_verb vt2002P_volume_init_verbs[] = {
5364         /*
5365          * Unmute ADC0-1 and set the default input to mic-in
5366          */
5367         {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5368         {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5369
5370
5371         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5372          * mixer widget
5373          */
5374         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5375         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5376         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5377         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5378         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5379         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5380
5381         /* MUX Indices: Mic = 0 */
5382         {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5383         {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5384
5385         /* PW9 Output enable */
5386         {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5387
5388         /* Enable Boost Volume backdoor */
5389         {0x1, 0xfb9, 0x24},
5390
5391         /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5392         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5393         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5394         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5395         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5396         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5397         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5398         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5399         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5400
5401         /* set MUX0/1/4/8 = 0 (AOW0) */
5402         {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5403         {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5404         {0x37, AC_VERB_SET_CONNECT_SEL, 0},
5405         {0x3b, AC_VERB_SET_CONNECT_SEL, 0},
5406
5407         /* set PW0 index=0 (MW0) */
5408         {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5409
5410         /* Enable AOW0 to MW9 */
5411         {0x1, 0xfb8, 0x88},
5412         { }
5413 };
5414
5415
5416 static struct hda_verb vt2002P_uniwill_init_verbs[] = {
5417         {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5418          AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5419         {0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
5420          AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5421         {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5422         {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5423         {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5424         { }
5425 };
5426
5427 static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5428         .substreams = 2,
5429         .channels_min = 2,
5430         .channels_max = 2,
5431         .nid = 0x8, /* NID to query formats and rates */
5432         .ops = {
5433                 .open = via_playback_pcm_open,
5434                 .prepare = via_playback_multi_pcm_prepare,
5435                 .cleanup = via_playback_multi_pcm_cleanup,
5436                 .close = via_pcm_open_close,
5437         },
5438 };
5439
5440 static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5441         .substreams = 2,
5442         .channels_min = 2,
5443         .channels_max = 2,
5444         .nid = 0x10, /* NID to query formats and rates */
5445         .ops = {
5446                 .open = via_pcm_open_close,
5447                 .prepare = via_capture_pcm_prepare,
5448                 .cleanup = via_capture_pcm_cleanup,
5449                 .close = via_pcm_open_close,
5450         },
5451 };
5452
5453 static struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5454         .substreams = 1,
5455         .channels_min = 2,
5456         .channels_max = 2,
5457         /* NID is set in via_build_pcms */
5458         .ops = {
5459                 .open = via_dig_playback_pcm_open,
5460                 .close = via_dig_playback_pcm_close,
5461                 .prepare = via_dig_playback_pcm_prepare,
5462                 .cleanup = via_dig_playback_pcm_cleanup
5463         },
5464 };
5465
5466 /* fill in the dac_nids table from the parsed pin configuration */
5467 static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5468                                       const struct auto_pin_cfg *cfg)
5469 {
5470         spec->multiout.num_dacs = 1;
5471         spec->multiout.dac_nids = spec->private_dac_nids;
5472         if (cfg->line_out_pins[0])
5473                 spec->multiout.dac_nids[0] = 0x8;
5474         return 0;
5475 }
5476
5477 /* add playback controls from the parsed DAC table */
5478 static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5479                                              const struct auto_pin_cfg *cfg)
5480 {
5481         int err;
5482
5483         if (!cfg->line_out_pins[0])
5484                 return -1;
5485
5486
5487         /* Line-Out: PortE */
5488         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5489                               "Master Front Playback Volume",
5490                               HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5491         if (err < 0)
5492                 return err;
5493         err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5494                               "Master Front Playback Switch",
5495                               HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT));
5496         if (err < 0)
5497                 return err;
5498
5499         return 0;
5500 }
5501
5502 static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5503 {
5504         int err;
5505
5506         if (!pin)
5507                 return 0;
5508
5509         spec->multiout.hp_nid = 0x9;
5510         spec->hp_independent_mode_index = 1;
5511
5512         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5513                               "Headphone Playback Volume",
5514                               HDA_COMPOSE_AMP_VAL(
5515                                       spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5516         if (err < 0)
5517                 return err;
5518
5519         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5520                               "Headphone Playback Switch",
5521                               HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5522         if (err < 0)
5523                 return err;
5524
5525         create_hp_imux(spec);
5526         return 0;
5527 }
5528
5529 /* create playback/capture controls for input pins */
5530 static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec,
5531                                                 const struct auto_pin_cfg *cfg)
5532 {
5533         struct via_spec *spec = codec->spec;
5534         struct hda_input_mux *imux = &spec->private_imux[0];
5535         static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
5536         int err;
5537
5538         err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5539                                                ARRAY_SIZE(pin_idxs));
5540         if (err < 0)
5541                 return err;
5542         /* build volume/mute control of loopback */
5543         err = via_new_analog_input(spec, "Stereo Mixer", 0, 3, 0x21);
5544         if (err < 0)
5545                 return err;
5546
5547         /* for digital mic select */
5548         snd_hda_add_imux_item(imux, "Digital Mic", 4, NULL);
5549
5550         return 0;
5551 }
5552
5553 static int vt2002P_parse_auto_config(struct hda_codec *codec)
5554 {
5555         struct via_spec *spec = codec->spec;
5556         int err;
5557
5558
5559         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5560         if (err < 0)
5561                 return err;
5562
5563         err = vt2002P_auto_fill_dac_nids(spec, &spec->autocfg);
5564         if (err < 0)
5565                 return err;
5566
5567         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5568                 return 0; /* can't find valid BIOS pin config */
5569
5570         err = vt2002P_auto_create_multi_out_ctls(spec, &spec->autocfg);
5571         if (err < 0)
5572                 return err;
5573         err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5574         if (err < 0)
5575                 return err;
5576         err = vt2002P_auto_create_analog_input_ctls(codec, &spec->autocfg);
5577         if (err < 0)
5578                 return err;
5579
5580         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5581
5582         fill_dig_outs(codec);
5583
5584         if (spec->kctls.list)
5585                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5586
5587         spec->input_mux = &spec->private_imux[0];
5588
5589         if (spec->hp_mux)
5590                 via_hp_build(codec);
5591
5592         return 1;
5593 }
5594
5595 #ifdef CONFIG_SND_HDA_POWER_SAVE
5596 static struct hda_amp_list vt2002P_loopbacks[] = {
5597         { 0x21, HDA_INPUT, 0 },
5598         { 0x21, HDA_INPUT, 1 },
5599         { 0x21, HDA_INPUT, 2 },
5600         { } /* end */
5601 };
5602 #endif
5603
5604
5605 /* patch for vt2002P */
5606 static int patch_vt2002P(struct hda_codec *codec)
5607 {
5608         struct via_spec *spec;
5609         int err;
5610
5611         /* create a codec specific record */
5612         spec = via_new_spec(codec);
5613         if (spec == NULL)
5614                 return -ENOMEM;
5615
5616         /* automatic parse from the BIOS config */
5617         err = vt2002P_parse_auto_config(codec);
5618         if (err < 0) {
5619                 via_free(codec);
5620                 return err;
5621         } else if (!err) {
5622                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5623                        "from BIOS.  Using genenic mode...\n");
5624         }
5625
5626         spec->init_verbs[spec->num_iverbs++]  = vt2002P_volume_init_verbs;
5627         spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs;
5628
5629         spec->stream_name_analog = "VT2002P Analog";
5630         spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5631         spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5632
5633         spec->stream_name_digital = "VT2002P Digital";
5634         spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5635
5636         if (!spec->adc_nids && spec->input_mux) {
5637                 spec->adc_nids = vt2002P_adc_nids;
5638                 spec->num_adc_nids = ARRAY_SIZE(vt2002P_adc_nids);
5639                 get_mux_nids(codec);
5640                 override_mic_boost(codec, 0x2b, 0, 3, 40);
5641                 override_mic_boost(codec, 0x29, 0, 3, 40);
5642                 spec->mixers[spec->num_mixers] = vt2002P_capture_mixer;
5643                 spec->num_mixers++;
5644         }
5645
5646         codec->patch_ops = via_patch_ops;
5647
5648         codec->patch_ops.init = via_auto_init;
5649         codec->patch_ops.unsol_event = via_unsol_event;
5650
5651 #ifdef CONFIG_SND_HDA_POWER_SAVE
5652         spec->loopback.amplist = vt2002P_loopbacks;
5653 #endif
5654
5655         return 0;
5656 }
5657
5658 /* for vt1812 */
5659
5660 /* capture mixer elements */
5661 static struct snd_kcontrol_new vt1812_capture_mixer[] = {
5662         HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5663         HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5664         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5665         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5666         HDA_CODEC_MUTE("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5667         HDA_CODEC_MUTE("Front Mic Boost Capture Volume", 0x29, 0x0,
5668                        HDA_INPUT),
5669         {
5670                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5671                 /* The multiple "Capture Source" controls confuse alsamixer
5672                  * So call somewhat different..
5673                  */
5674                 .name = "Input Source",
5675                 .count = 2,
5676                 .info = via_mux_enum_info,
5677                 .get = via_mux_enum_get,
5678                 .put = via_mux_enum_put,
5679         },
5680         { } /* end */
5681 };
5682
5683 static struct hda_verb vt1812_volume_init_verbs[] = {
5684         /*
5685          * Unmute ADC0-1 and set the default input to mic-in
5686          */
5687         {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5688         {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5689
5690
5691         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5692          * mixer widget
5693          */
5694         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5695         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5696         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5697         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5698         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5699         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5700
5701         /* MUX Indices: Mic = 0 */
5702         {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5703         {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5704
5705         /* PW9 Output enable */
5706         {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5707
5708         /* Enable Boost Volume backdoor */
5709         {0x1, 0xfb9, 0x24},
5710
5711         /* MW0/1/4/13/15: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5712         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5713         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5714         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5715         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5716         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5717         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5718         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5719         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5720         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5721         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5722
5723         /* set MUX0/1/4/13/15 = 0 (AOW0) */
5724         {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5725         {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5726         {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5727         {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5728         {0x3d, AC_VERB_SET_CONNECT_SEL, 0},
5729
5730         /* Enable AOW0 to MW9 */
5731         {0x1, 0xfb8, 0xa8},
5732         { }
5733 };
5734
5735
5736 static struct hda_verb vt1812_uniwill_init_verbs[] = {
5737         {0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5738          AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5739         {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
5740         {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5741          AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5742         {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5743         {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5744         {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5745         { }
5746 };
5747
5748 static struct hda_pcm_stream vt1812_pcm_analog_playback = {
5749         .substreams = 2,
5750         .channels_min = 2,
5751         .channels_max = 2,
5752         .nid = 0x8, /* NID to query formats and rates */
5753         .ops = {
5754                 .open = via_playback_pcm_open,
5755                 .prepare = via_playback_multi_pcm_prepare,
5756                 .cleanup = via_playback_multi_pcm_cleanup,
5757                 .close = via_pcm_open_close,
5758         },
5759 };
5760
5761 static struct hda_pcm_stream vt1812_pcm_analog_capture = {
5762         .substreams = 2,
5763         .channels_min = 2,
5764         .channels_max = 2,
5765         .nid = 0x10, /* NID to query formats and rates */
5766         .ops = {
5767                 .open = via_pcm_open_close,
5768                 .prepare = via_capture_pcm_prepare,
5769                 .cleanup = via_capture_pcm_cleanup,
5770                 .close = via_pcm_open_close,
5771         },
5772 };
5773
5774 static struct hda_pcm_stream vt1812_pcm_digital_playback = {
5775         .substreams = 1,
5776         .channels_min = 2,
5777         .channels_max = 2,
5778         /* NID is set in via_build_pcms */
5779         .ops = {
5780                 .open = via_dig_playback_pcm_open,
5781                 .close = via_dig_playback_pcm_close,
5782                 .prepare = via_dig_playback_pcm_prepare,
5783                 .cleanup = via_dig_playback_pcm_cleanup
5784         },
5785 };
5786 /* fill in the dac_nids table from the parsed pin configuration */
5787 static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
5788                                      const struct auto_pin_cfg *cfg)
5789 {
5790         spec->multiout.num_dacs = 1;
5791         spec->multiout.dac_nids = spec->private_dac_nids;
5792         if (cfg->line_out_pins[0])
5793                 spec->multiout.dac_nids[0] = 0x8;
5794         return 0;
5795 }
5796
5797
5798 /* add playback controls from the parsed DAC table */
5799 static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
5800                                              const struct auto_pin_cfg *cfg)
5801 {
5802         int err;
5803
5804         if (!cfg->line_out_pins[0])
5805                 return -1;
5806
5807         /* Line-Out: PortE */
5808         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5809                               "Front Playback Volume",
5810                               HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5811         if (err < 0)
5812                 return err;
5813         err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5814                               "Front Playback Switch",
5815                               HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
5816         if (err < 0)
5817                 return err;
5818
5819         return 0;
5820 }
5821
5822 static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5823 {
5824         int err;
5825
5826         if (!pin)
5827                 return 0;
5828
5829         spec->multiout.hp_nid = 0x9;
5830         spec->hp_independent_mode_index = 1;
5831
5832
5833         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5834                               "Headphone Playback Volume",
5835                               HDA_COMPOSE_AMP_VAL(
5836                                       spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5837         if (err < 0)
5838                 return err;
5839
5840         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5841                               "Headphone Playback Switch",
5842                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5843         if (err < 0)
5844                 return err;
5845
5846         create_hp_imux(spec);
5847         return 0;
5848 }
5849
5850 /* create playback/capture controls for input pins */
5851 static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec,
5852                                                 const struct auto_pin_cfg *cfg)
5853 {
5854         struct via_spec *spec = codec->spec;
5855         struct hda_input_mux *imux = &spec->private_imux[0];
5856         static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
5857         int err;
5858
5859         err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5860                                                ARRAY_SIZE(pin_idxs));
5861         if (err < 0)
5862                 return err;
5863
5864         /* build volume/mute control of loopback */
5865         err = via_new_analog_input(spec, "Stereo Mixer", 0, 5, 0x21);
5866         if (err < 0)
5867                 return err;
5868
5869         /* for digital mic select */
5870         snd_hda_add_imux_item(imux, "Digital Mic", 6, NULL);
5871
5872         return 0;
5873 }
5874
5875 static int vt1812_parse_auto_config(struct hda_codec *codec)
5876 {
5877         struct via_spec *spec = codec->spec;
5878         int err;
5879
5880
5881         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5882         if (err < 0)
5883                 return err;
5884         fill_dig_outs(codec);
5885         err = vt1812_auto_fill_dac_nids(spec, &spec->autocfg);
5886         if (err < 0)
5887                 return err;
5888
5889         if (!spec->autocfg.line_outs && !spec->autocfg.hp_outs)
5890                 return 0; /* can't find valid BIOS pin config */
5891
5892         err = vt1812_auto_create_multi_out_ctls(spec, &spec->autocfg);
5893         if (err < 0)
5894                 return err;
5895         err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5896         if (err < 0)
5897                 return err;
5898         err = vt1812_auto_create_analog_input_ctls(codec, &spec->autocfg);
5899         if (err < 0)
5900                 return err;
5901
5902         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5903
5904         fill_dig_outs(codec);
5905
5906         if (spec->kctls.list)
5907                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5908
5909         spec->input_mux = &spec->private_imux[0];
5910
5911         if (spec->hp_mux)
5912                 via_hp_build(codec);
5913
5914         return 1;
5915 }
5916
5917 #ifdef CONFIG_SND_HDA_POWER_SAVE
5918 static struct hda_amp_list vt1812_loopbacks[] = {
5919         { 0x21, HDA_INPUT, 0 },
5920         { 0x21, HDA_INPUT, 1 },
5921         { 0x21, HDA_INPUT, 2 },
5922         { } /* end */
5923 };
5924 #endif
5925
5926
5927 /* patch for vt1812 */
5928 static int patch_vt1812(struct hda_codec *codec)
5929 {
5930         struct via_spec *spec;
5931         int err;
5932
5933         /* create a codec specific record */
5934         spec = via_new_spec(codec);
5935         if (spec == NULL)
5936                 return -ENOMEM;
5937
5938         /* automatic parse from the BIOS config */
5939         err = vt1812_parse_auto_config(codec);
5940         if (err < 0) {
5941                 via_free(codec);
5942                 return err;
5943         } else if (!err) {
5944                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5945                        "from BIOS.  Using genenic mode...\n");
5946         }
5947
5948
5949         spec->init_verbs[spec->num_iverbs++]  = vt1812_volume_init_verbs;
5950         spec->init_verbs[spec->num_iverbs++] = vt1812_uniwill_init_verbs;
5951
5952         spec->stream_name_analog = "VT1812 Analog";
5953         spec->stream_analog_playback = &vt1812_pcm_analog_playback;
5954         spec->stream_analog_capture = &vt1812_pcm_analog_capture;
5955
5956         spec->stream_name_digital = "VT1812 Digital";
5957         spec->stream_digital_playback = &vt1812_pcm_digital_playback;
5958
5959
5960         if (!spec->adc_nids && spec->input_mux) {
5961                 spec->adc_nids = vt1812_adc_nids;
5962                 spec->num_adc_nids = ARRAY_SIZE(vt1812_adc_nids);
5963                 get_mux_nids(codec);
5964                 override_mic_boost(codec, 0x2b, 0, 3, 40);
5965                 override_mic_boost(codec, 0x29, 0, 3, 40);
5966                 spec->mixers[spec->num_mixers] = vt1812_capture_mixer;
5967                 spec->num_mixers++;
5968         }
5969
5970         codec->patch_ops = via_patch_ops;
5971
5972         codec->patch_ops.init = via_auto_init;
5973         codec->patch_ops.unsol_event = via_unsol_event;
5974
5975 #ifdef CONFIG_SND_HDA_POWER_SAVE
5976         spec->loopback.amplist = vt1812_loopbacks;
5977 #endif
5978
5979         return 0;
5980 }
5981
5982 /*
5983  * patch entries
5984  */
5985 static struct hda_codec_preset snd_hda_preset_via[] = {
5986         { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
5987         { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
5988         { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
5989         { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
5990         { .id = 0x1106e710, .name = "VT1709 10-Ch",
5991           .patch = patch_vt1709_10ch},
5992         { .id = 0x1106e711, .name = "VT1709 10-Ch",
5993           .patch = patch_vt1709_10ch},
5994         { .id = 0x1106e712, .name = "VT1709 10-Ch",
5995           .patch = patch_vt1709_10ch},
5996         { .id = 0x1106e713, .name = "VT1709 10-Ch",
5997           .patch = patch_vt1709_10ch},
5998         { .id = 0x1106e714, .name = "VT1709 6-Ch",
5999           .patch = patch_vt1709_6ch},
6000         { .id = 0x1106e715, .name = "VT1709 6-Ch",
6001           .patch = patch_vt1709_6ch},
6002         { .id = 0x1106e716, .name = "VT1709 6-Ch",
6003           .patch = patch_vt1709_6ch},
6004         { .id = 0x1106e717, .name = "VT1709 6-Ch",
6005           .patch = patch_vt1709_6ch},
6006         { .id = 0x1106e720, .name = "VT1708B 8-Ch",
6007           .patch = patch_vt1708B_8ch},
6008         { .id = 0x1106e721, .name = "VT1708B 8-Ch",
6009           .patch = patch_vt1708B_8ch},
6010         { .id = 0x1106e722, .name = "VT1708B 8-Ch",
6011           .patch = patch_vt1708B_8ch},
6012         { .id = 0x1106e723, .name = "VT1708B 8-Ch",
6013           .patch = patch_vt1708B_8ch},
6014         { .id = 0x1106e724, .name = "VT1708B 4-Ch",
6015           .patch = patch_vt1708B_4ch},
6016         { .id = 0x1106e725, .name = "VT1708B 4-Ch",
6017           .patch = patch_vt1708B_4ch},
6018         { .id = 0x1106e726, .name = "VT1708B 4-Ch",
6019           .patch = patch_vt1708B_4ch},
6020         { .id = 0x1106e727, .name = "VT1708B 4-Ch",
6021           .patch = patch_vt1708B_4ch},
6022         { .id = 0x11060397, .name = "VT1708S",
6023           .patch = patch_vt1708S},
6024         { .id = 0x11061397, .name = "VT1708S",
6025           .patch = patch_vt1708S},
6026         { .id = 0x11062397, .name = "VT1708S",
6027           .patch = patch_vt1708S},
6028         { .id = 0x11063397, .name = "VT1708S",
6029           .patch = patch_vt1708S},
6030         { .id = 0x11064397, .name = "VT1708S",
6031           .patch = patch_vt1708S},
6032         { .id = 0x11065397, .name = "VT1708S",
6033           .patch = patch_vt1708S},
6034         { .id = 0x11066397, .name = "VT1708S",
6035           .patch = patch_vt1708S},
6036         { .id = 0x11067397, .name = "VT1708S",
6037           .patch = patch_vt1708S},
6038         { .id = 0x11060398, .name = "VT1702",
6039           .patch = patch_vt1702},
6040         { .id = 0x11061398, .name = "VT1702",
6041           .patch = patch_vt1702},
6042         { .id = 0x11062398, .name = "VT1702",
6043           .patch = patch_vt1702},
6044         { .id = 0x11063398, .name = "VT1702",
6045           .patch = patch_vt1702},
6046         { .id = 0x11064398, .name = "VT1702",
6047           .patch = patch_vt1702},
6048         { .id = 0x11065398, .name = "VT1702",
6049           .patch = patch_vt1702},
6050         { .id = 0x11066398, .name = "VT1702",
6051           .patch = patch_vt1702},
6052         { .id = 0x11067398, .name = "VT1702",
6053           .patch = patch_vt1702},
6054         { .id = 0x11060428, .name = "VT1718S",
6055           .patch = patch_vt1718S},
6056         { .id = 0x11064428, .name = "VT1718S",
6057           .patch = patch_vt1718S},
6058         { .id = 0x11060441, .name = "VT2020",
6059           .patch = patch_vt1718S},
6060         { .id = 0x11064441, .name = "VT1828S",
6061           .patch = patch_vt1718S},
6062         { .id = 0x11060433, .name = "VT1716S",
6063           .patch = patch_vt1716S},
6064         { .id = 0x1106a721, .name = "VT1716S",
6065           .patch = patch_vt1716S},
6066         { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
6067         { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
6068         { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
6069         { .id = 0x11060440, .name = "VT1818S",
6070           .patch = patch_vt1708S},
6071         {} /* terminator */
6072 };
6073
6074 MODULE_ALIAS("snd-hda-codec-id:1106*");
6075
6076 static struct hda_codec_preset_list via_list = {
6077         .preset = snd_hda_preset_via,
6078         .owner = THIS_MODULE,
6079 };
6080
6081 MODULE_LICENSE("GPL");
6082 MODULE_DESCRIPTION("VIA HD-audio codec");
6083
6084 static int __init patch_via_init(void)
6085 {
6086         return snd_hda_add_codec_preset(&via_list);
6087 }
6088
6089 static void __exit patch_via_exit(void)
6090 {
6091         snd_hda_delete_codec_preset(&via_list);
6092 }
6093
6094 module_init(patch_via_init)
6095 module_exit(patch_via_exit)