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