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