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