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