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