[ALSA] Clean up with common snd_ctl_boolean_*_info callbacks
[linux-2.6-block.git] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_BENQ_ED8,
96         ALC262_SONY_ASSAMD,
97         ALC262_BENQ_T31,
98         ALC262_AUTO,
99         ALC262_MODEL_LAST /* last tag */
100 };
101
102 /* ALC268 models */
103 enum {
104         ALC268_3ST,
105         ALC268_AUTO,
106         ALC268_MODEL_LAST /* last tag */
107 };
108
109 /* ALC861 models */
110 enum {
111         ALC861_3ST,
112         ALC660_3ST,
113         ALC861_3ST_DIG,
114         ALC861_6ST_DIG,
115         ALC861_UNIWILL_M31,
116         ALC861_TOSHIBA,
117         ALC861_ASUS,
118         ALC861_ASUS_LAPTOP,
119         ALC861_AUTO,
120         ALC861_MODEL_LAST,
121 };
122
123 /* ALC861-VD models */
124 enum {
125         ALC660VD_3ST,
126         ALC660VD_3ST_DIG,
127         ALC861VD_3ST,
128         ALC861VD_3ST_DIG,
129         ALC861VD_6ST_DIG,
130         ALC861VD_LENOVO,
131         ALC861VD_DALLAS,
132         ALC861VD_AUTO,
133         ALC861VD_MODEL_LAST,
134 };
135
136 /* ALC662 models */
137 enum {
138         ALC662_3ST_2ch_DIG,
139         ALC662_3ST_6ch_DIG,
140         ALC662_3ST_6ch,
141         ALC662_5ST_DIG,
142         ALC662_LENOVO_101E,
143         ALC662_AUTO,
144         ALC662_MODEL_LAST,
145 };
146
147 /* ALC882 models */
148 enum {
149         ALC882_3ST_DIG,
150         ALC882_6ST_DIG,
151         ALC882_ARIMA,
152         ALC882_W2JC,
153         ALC882_TARGA,
154         ALC882_ASUS_A7J,
155         ALC885_MACPRO,
156         ALC885_IMAC24,
157         ALC882_AUTO,
158         ALC882_MODEL_LAST,
159 };
160
161 /* ALC883 models */
162 enum {
163         ALC883_3ST_2ch_DIG,
164         ALC883_3ST_6ch_DIG,
165         ALC883_3ST_6ch,
166         ALC883_6ST_DIG,
167         ALC883_TARGA_DIG,
168         ALC883_TARGA_2ch_DIG,
169         ALC883_ACER,
170         ALC883_MEDION,
171         ALC883_MEDION_MD2,      
172         ALC883_LAPTOP_EAPD,
173         ALC883_LENOVO_101E_2ch,
174         ALC883_LENOVO_NB0763,
175         ALC888_LENOVO_MS7195_DIG,               
176         ALC888_6ST_HP,
177         ALC888_3ST_HP,
178         ALC883_AUTO,
179         ALC883_MODEL_LAST,
180 };
181
182 /* for GPIO Poll */
183 #define GPIO_MASK       0x03
184
185 struct alc_spec {
186         /* codec parameterization */
187         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
188         unsigned int num_mixers;
189
190         const struct hda_verb *init_verbs[5];   /* initialization verbs
191                                                  * don't forget NULL
192                                                  * termination!
193                                                  */
194         unsigned int num_init_verbs;
195
196         char *stream_name_analog;       /* analog PCM stream */
197         struct hda_pcm_stream *stream_analog_playback;
198         struct hda_pcm_stream *stream_analog_capture;
199
200         char *stream_name_digital;      /* digital PCM stream */
201         struct hda_pcm_stream *stream_digital_playback;
202         struct hda_pcm_stream *stream_digital_capture;
203
204         /* playback */
205         struct hda_multi_out multiout;  /* playback set-up
206                                          * max_channels, dacs must be set
207                                          * dig_out_nid and hp_nid are optional
208                                          */
209
210         /* capture */
211         unsigned int num_adc_nids;
212         hda_nid_t *adc_nids;
213         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
214
215         /* capture source */
216         unsigned int num_mux_defs;
217         const struct hda_input_mux *input_mux;
218         unsigned int cur_mux[3];
219
220         /* channel model */
221         const struct hda_channel_mode *channel_mode;
222         int num_channel_mode;
223         int need_dac_fix;
224
225         /* PCM information */
226         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
227
228         /* dynamic controls, init_verbs and input_mux */
229         struct auto_pin_cfg autocfg;
230         unsigned int num_kctl_alloc, num_kctl_used;
231         struct snd_kcontrol_new *kctl_alloc;
232         struct hda_input_mux private_imux;
233         hda_nid_t private_dac_nids[5];
234
235         /* hooks */
236         void (*init_hook)(struct hda_codec *codec);
237         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
238
239         /* for pin sensing */
240         unsigned int sense_updated: 1;
241         unsigned int jack_present: 1;
242 };
243
244 /*
245  * configuration template - to be copied to the spec instance
246  */
247 struct alc_config_preset {
248         struct snd_kcontrol_new *mixers[5]; /* should be identical size
249                                              * with spec
250                                              */
251         const struct hda_verb *init_verbs[5];
252         unsigned int num_dacs;
253         hda_nid_t *dac_nids;
254         hda_nid_t dig_out_nid;          /* optional */
255         hda_nid_t hp_nid;               /* optional */
256         unsigned int num_adc_nids;
257         hda_nid_t *adc_nids;
258         hda_nid_t dig_in_nid;
259         unsigned int num_channel_mode;
260         const struct hda_channel_mode *channel_mode;
261         int need_dac_fix;
262         unsigned int num_mux_defs;
263         const struct hda_input_mux *input_mux;
264         void (*unsol_event)(struct hda_codec *, unsigned int);
265         void (*init_hook)(struct hda_codec *);
266 };
267
268
269 /*
270  * input MUX handling
271  */
272 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
273                              struct snd_ctl_elem_info *uinfo)
274 {
275         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
276         struct alc_spec *spec = codec->spec;
277         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
278         if (mux_idx >= spec->num_mux_defs)
279                 mux_idx = 0;
280         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
281 }
282
283 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
284                             struct snd_ctl_elem_value *ucontrol)
285 {
286         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
287         struct alc_spec *spec = codec->spec;
288         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
289
290         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
291         return 0;
292 }
293
294 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
295                             struct snd_ctl_elem_value *ucontrol)
296 {
297         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
298         struct alc_spec *spec = codec->spec;
299         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
300         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
301         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
302                                      spec->adc_nids[adc_idx],
303                                      &spec->cur_mux[adc_idx]);
304 }
305
306
307 /*
308  * channel mode setting
309  */
310 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
311                             struct snd_ctl_elem_info *uinfo)
312 {
313         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
314         struct alc_spec *spec = codec->spec;
315         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
316                                     spec->num_channel_mode);
317 }
318
319 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
320                            struct snd_ctl_elem_value *ucontrol)
321 {
322         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
323         struct alc_spec *spec = codec->spec;
324         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
325                                    spec->num_channel_mode,
326                                    spec->multiout.max_channels);
327 }
328
329 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
330                            struct snd_ctl_elem_value *ucontrol)
331 {
332         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
333         struct alc_spec *spec = codec->spec;
334         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
335                                       spec->num_channel_mode,
336                                       &spec->multiout.max_channels);
337         if (err >= 0 && spec->need_dac_fix)
338                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
339         return err;
340 }
341
342 /*
343  * Control the mode of pin widget settings via the mixer.  "pc" is used
344  * instead of "%" to avoid consequences of accidently treating the % as 
345  * being part of a format specifier.  Maximum allowed length of a value is
346  * 63 characters plus NULL terminator.
347  *
348  * Note: some retasking pin complexes seem to ignore requests for input
349  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
350  * are requested.  Therefore order this list so that this behaviour will not
351  * cause problems when mixer clients move through the enum sequentially.
352  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
353  * March 2006.
354  */
355 static char *alc_pin_mode_names[] = {
356         "Mic 50pc bias", "Mic 80pc bias",
357         "Line in", "Line out", "Headphone out",
358 };
359 static unsigned char alc_pin_mode_values[] = {
360         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
361 };
362 /* The control can present all 5 options, or it can limit the options based
363  * in the pin being assumed to be exclusively an input or an output pin.  In
364  * addition, "input" pins may or may not process the mic bias option
365  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
366  * accept requests for bias as of chip versions up to March 2006) and/or
367  * wiring in the computer.
368  */
369 #define ALC_PIN_DIR_IN              0x00
370 #define ALC_PIN_DIR_OUT             0x01
371 #define ALC_PIN_DIR_INOUT           0x02
372 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
373 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
374
375 /* Info about the pin modes supported by the different pin direction modes. 
376  * For each direction the minimum and maximum values are given.
377  */
378 static signed char alc_pin_mode_dir_info[5][2] = {
379         { 0, 2 },    /* ALC_PIN_DIR_IN */
380         { 3, 4 },    /* ALC_PIN_DIR_OUT */
381         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
382         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
383         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
384 };
385 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
386 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
387 #define alc_pin_mode_n_items(_dir) \
388         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
389
390 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
391                              struct snd_ctl_elem_info *uinfo)
392 {
393         unsigned int item_num = uinfo->value.enumerated.item;
394         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
395
396         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
397         uinfo->count = 1;
398         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
399
400         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
401                 item_num = alc_pin_mode_min(dir);
402         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
403         return 0;
404 }
405
406 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
407                             struct snd_ctl_elem_value *ucontrol)
408 {
409         unsigned int i;
410         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
411         hda_nid_t nid = kcontrol->private_value & 0xffff;
412         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
413         long *valp = ucontrol->value.integer.value;
414         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
415                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
416                                                  0x00);
417
418         /* Find enumerated value for current pinctl setting */
419         i = alc_pin_mode_min(dir);
420         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
421                 i++;
422         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
423         return 0;
424 }
425
426 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
427                             struct snd_ctl_elem_value *ucontrol)
428 {
429         signed int change;
430         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
431         hda_nid_t nid = kcontrol->private_value & 0xffff;
432         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
433         long val = *ucontrol->value.integer.value;
434         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
435                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
436                                                  0x00);
437
438         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
439                 val = alc_pin_mode_min(dir);
440
441         change = pinctl != alc_pin_mode_values[val];
442         if (change) {
443                 /* Set pin mode to that requested */
444                 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
445                                     alc_pin_mode_values[val]);
446
447                 /* Also enable the retasking pin's input/output as required 
448                  * for the requested pin mode.  Enum values of 2 or less are
449                  * input modes.
450                  *
451                  * Dynamically switching the input/output buffers probably
452                  * reduces noise slightly (particularly on input) so we'll
453                  * do it.  However, having both input and output buffers
454                  * enabled simultaneously doesn't seem to be problematic if
455                  * this turns out to be necessary in the future.
456                  */
457                 if (val <= 2) {
458                         snd_hda_codec_write(codec, nid, 0,
459                                             AC_VERB_SET_AMP_GAIN_MUTE,
460                                             AMP_OUT_MUTE);
461                         snd_hda_codec_write(codec, nid, 0,
462                                             AC_VERB_SET_AMP_GAIN_MUTE,
463                                             AMP_IN_UNMUTE(0));
464                 } else {
465                         snd_hda_codec_write(codec, nid, 0,
466                                             AC_VERB_SET_AMP_GAIN_MUTE,
467                                             AMP_IN_MUTE(0));
468                         snd_hda_codec_write(codec, nid, 0,
469                                             AC_VERB_SET_AMP_GAIN_MUTE,
470                                             AMP_OUT_UNMUTE);
471                 }
472         }
473         return change;
474 }
475
476 #define ALC_PIN_MODE(xname, nid, dir) \
477         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
478           .info = alc_pin_mode_info, \
479           .get = alc_pin_mode_get, \
480           .put = alc_pin_mode_put, \
481           .private_value = nid | (dir<<16) }
482
483 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
484  * together using a mask with more than one bit set.  This control is
485  * currently used only by the ALC260 test model.  At this stage they are not
486  * needed for any "production" models.
487  */
488 #ifdef CONFIG_SND_DEBUG
489 #define alc_gpio_data_info      snd_ctl_boolean_mono_info
490
491 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
492                              struct snd_ctl_elem_value *ucontrol)
493 {
494         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
495         hda_nid_t nid = kcontrol->private_value & 0xffff;
496         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
497         long *valp = ucontrol->value.integer.value;
498         unsigned int val = snd_hda_codec_read(codec, nid, 0,
499                                               AC_VERB_GET_GPIO_DATA, 0x00);
500
501         *valp = (val & mask) != 0;
502         return 0;
503 }
504 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
505                              struct snd_ctl_elem_value *ucontrol)
506 {
507         signed int change;
508         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
509         hda_nid_t nid = kcontrol->private_value & 0xffff;
510         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
511         long val = *ucontrol->value.integer.value;
512         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
513                                                     AC_VERB_GET_GPIO_DATA,
514                                                     0x00);
515
516         /* Set/unset the masked GPIO bit(s) as needed */
517         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
518         if (val == 0)
519                 gpio_data &= ~mask;
520         else
521                 gpio_data |= mask;
522         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
523
524         return change;
525 }
526 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
527         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
528           .info = alc_gpio_data_info, \
529           .get = alc_gpio_data_get, \
530           .put = alc_gpio_data_put, \
531           .private_value = nid | (mask<<16) }
532 #endif   /* CONFIG_SND_DEBUG */
533
534 /* A switch control to allow the enabling of the digital IO pins on the
535  * ALC260.  This is incredibly simplistic; the intention of this control is
536  * to provide something in the test model allowing digital outputs to be
537  * identified if present.  If models are found which can utilise these
538  * outputs a more complete mixer control can be devised for those models if
539  * necessary.
540  */
541 #ifdef CONFIG_SND_DEBUG
542 #define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
543
544 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
545                               struct snd_ctl_elem_value *ucontrol)
546 {
547         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548         hda_nid_t nid = kcontrol->private_value & 0xffff;
549         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
550         long *valp = ucontrol->value.integer.value;
551         unsigned int val = snd_hda_codec_read(codec, nid, 0,
552                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
553
554         *valp = (val & mask) != 0;
555         return 0;
556 }
557 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
558                               struct snd_ctl_elem_value *ucontrol)
559 {
560         signed int change;
561         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
562         hda_nid_t nid = kcontrol->private_value & 0xffff;
563         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
564         long val = *ucontrol->value.integer.value;
565         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
566                                                     AC_VERB_GET_DIGI_CONVERT,
567                                                     0x00);
568
569         /* Set/unset the masked control bit(s) as needed */
570         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
571         if (val==0)
572                 ctrl_data &= ~mask;
573         else
574                 ctrl_data |= mask;
575         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
576                             ctrl_data);
577
578         return change;
579 }
580 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
581         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
582           .info = alc_spdif_ctrl_info, \
583           .get = alc_spdif_ctrl_get, \
584           .put = alc_spdif_ctrl_put, \
585           .private_value = nid | (mask<<16) }
586 #endif   /* CONFIG_SND_DEBUG */
587
588 /*
589  * set up from the preset table
590  */
591 static void setup_preset(struct alc_spec *spec,
592                          const struct alc_config_preset *preset)
593 {
594         int i;
595
596         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
597                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
598         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
599              i++)
600                 spec->init_verbs[spec->num_init_verbs++] =
601                         preset->init_verbs[i];
602         
603         spec->channel_mode = preset->channel_mode;
604         spec->num_channel_mode = preset->num_channel_mode;
605         spec->need_dac_fix = preset->need_dac_fix;
606
607         spec->multiout.max_channels = spec->channel_mode[0].channels;
608
609         spec->multiout.num_dacs = preset->num_dacs;
610         spec->multiout.dac_nids = preset->dac_nids;
611         spec->multiout.dig_out_nid = preset->dig_out_nid;
612         spec->multiout.hp_nid = preset->hp_nid;
613         
614         spec->num_mux_defs = preset->num_mux_defs;
615         if (!spec->num_mux_defs)
616                 spec->num_mux_defs = 1;
617         spec->input_mux = preset->input_mux;
618
619         spec->num_adc_nids = preset->num_adc_nids;
620         spec->adc_nids = preset->adc_nids;
621         spec->dig_in_nid = preset->dig_in_nid;
622
623         spec->unsol_event = preset->unsol_event;
624         spec->init_hook = preset->init_hook;
625 }
626
627 /* Enable GPIO mask and set output */
628 static struct hda_verb alc_gpio1_init_verbs[] = {
629         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
630         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
631         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
632         { }
633 };
634
635 static struct hda_verb alc_gpio2_init_verbs[] = {
636         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
637         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
638         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
639         { }
640 };
641
642 static struct hda_verb alc_gpio3_init_verbs[] = {
643         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
644         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
645         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
646         { }
647 };
648
649 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
650  *      31 ~ 16 :       Manufacture ID
651  *      15 ~ 8  :       SKU ID
652  *      7  ~ 0  :       Assembly ID
653  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
654  */
655 static void alc_subsystem_id(struct hda_codec *codec,
656                              unsigned int porta, unsigned int porte,
657                              unsigned int portd)
658 {
659         unsigned int ass, tmp;
660
661         ass = codec->subsystem_id;
662         if (!(ass & 1))
663                 return;
664
665         /* Override */
666         tmp = (ass & 0x38) >> 3;        /* external Amp control */
667         switch (tmp) {
668         case 1:
669                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
670                 break;
671         case 3:
672                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
673                 break;
674         case 7:
675                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
676                 break;
677         case 5:
678                 switch (codec->vendor_id) {
679                 case 0x10ec0862:
680                 case 0x10ec0660:
681                 case 0x10ec0662:        
682                 case 0x10ec0267:
683                 case 0x10ec0268:
684                         snd_hda_codec_write(codec, 0x14, 0,
685                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
686                         snd_hda_codec_write(codec, 0x15, 0,
687                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
688                         return;
689                 }
690         case 6:
691                 if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
692                         hda_nid_t port = 0;
693                         tmp = (ass & 0x1800) >> 11;
694                         switch (tmp) {
695                         case 0: port = porta; break;
696                         case 1: port = porte; break;
697                         case 2: port = portd; break;
698                         }
699                         if (port)
700                                 snd_hda_codec_write(codec, port, 0,
701                                                     AC_VERB_SET_EAPD_BTLENABLE,
702                                                     2);
703                 }
704                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
705                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
706                                     (tmp == 5 ? 0x3040 : 0x3050));
707                 break;
708         }
709 }
710
711 /*
712  * Fix-up pin default configurations
713  */
714
715 struct alc_pincfg {
716         hda_nid_t nid;
717         u32 val;
718 };
719
720 static void alc_fix_pincfg(struct hda_codec *codec,
721                            const struct snd_pci_quirk *quirk,
722                            const struct alc_pincfg **pinfix)
723 {
724         const struct alc_pincfg *cfg;
725
726         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
727         if (!quirk)
728                 return;
729
730         cfg = pinfix[quirk->value];
731         for (; cfg->nid; cfg++) {
732                 int i;
733                 u32 val = cfg->val;
734                 for (i = 0; i < 4; i++) {
735                         snd_hda_codec_write(codec, cfg->nid, 0,
736                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
737                                     val & 0xff);
738                         val >>= 8;
739                 }
740         }
741 }
742
743 /*
744  * ALC880 3-stack model
745  *
746  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
747  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
748  *                 F-Mic = 0x1b, HP = 0x19
749  */
750
751 static hda_nid_t alc880_dac_nids[4] = {
752         /* front, rear, clfe, rear_surr */
753         0x02, 0x05, 0x04, 0x03
754 };
755
756 static hda_nid_t alc880_adc_nids[3] = {
757         /* ADC0-2 */
758         0x07, 0x08, 0x09,
759 };
760
761 /* The datasheet says the node 0x07 is connected from inputs,
762  * but it shows zero connection in the real implementation on some devices.
763  * Note: this is a 915GAV bug, fixed on 915GLV
764  */
765 static hda_nid_t alc880_adc_nids_alt[2] = {
766         /* ADC1-2 */
767         0x08, 0x09,
768 };
769
770 #define ALC880_DIGOUT_NID       0x06
771 #define ALC880_DIGIN_NID        0x0a
772
773 static struct hda_input_mux alc880_capture_source = {
774         .num_items = 4,
775         .items = {
776                 { "Mic", 0x0 },
777                 { "Front Mic", 0x3 },
778                 { "Line", 0x2 },
779                 { "CD", 0x4 },
780         },
781 };
782
783 /* channel source setting (2/6 channel selection for 3-stack) */
784 /* 2ch mode */
785 static struct hda_verb alc880_threestack_ch2_init[] = {
786         /* set line-in to input, mute it */
787         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
788         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
789         /* set mic-in to input vref 80%, mute it */
790         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
791         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
792         { } /* end */
793 };
794
795 /* 6ch mode */
796 static struct hda_verb alc880_threestack_ch6_init[] = {
797         /* set line-in to output, unmute it */
798         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
799         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
800         /* set mic-in to output, unmute it */
801         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
802         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
803         { } /* end */
804 };
805
806 static struct hda_channel_mode alc880_threestack_modes[2] = {
807         { 2, alc880_threestack_ch2_init },
808         { 6, alc880_threestack_ch6_init },
809 };
810
811 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
812         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
813         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
814         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
815         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
816         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
817         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
818         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
819         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
820         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
821         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
822         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
823         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
824         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
825         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
826         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
827         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
828         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
829         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
830         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
831         {
832                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
833                 .name = "Channel Mode",
834                 .info = alc_ch_mode_info,
835                 .get = alc_ch_mode_get,
836                 .put = alc_ch_mode_put,
837         },
838         { } /* end */
839 };
840
841 /* capture mixer elements */
842 static struct snd_kcontrol_new alc880_capture_mixer[] = {
843         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
844         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
845         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
846         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
847         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
848         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
849         {
850                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
851                 /* The multiple "Capture Source" controls confuse alsamixer
852                  * So call somewhat different..
853                  * FIXME: the controls appear in the "playback" view!
854                  */
855                 /* .name = "Capture Source", */
856                 .name = "Input Source",
857                 .count = 3,
858                 .info = alc_mux_enum_info,
859                 .get = alc_mux_enum_get,
860                 .put = alc_mux_enum_put,
861         },
862         { } /* end */
863 };
864
865 /* capture mixer elements (in case NID 0x07 not available) */
866 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
867         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
868         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
869         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
870         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
871         {
872                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
873                 /* The multiple "Capture Source" controls confuse alsamixer
874                  * So call somewhat different..
875                  * FIXME: the controls appear in the "playback" view!
876                  */
877                 /* .name = "Capture Source", */
878                 .name = "Input Source",
879                 .count = 2,
880                 .info = alc_mux_enum_info,
881                 .get = alc_mux_enum_get,
882                 .put = alc_mux_enum_put,
883         },
884         { } /* end */
885 };
886
887
888
889 /*
890  * ALC880 5-stack model
891  *
892  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
893  *      Side = 0x02 (0xd)
894  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
895  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
896  */
897
898 /* additional mixers to alc880_three_stack_mixer */
899 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
900         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
901         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
902         { } /* end */
903 };
904
905 /* channel source setting (6/8 channel selection for 5-stack) */
906 /* 6ch mode */
907 static struct hda_verb alc880_fivestack_ch6_init[] = {
908         /* set line-in to input, mute it */
909         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
910         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
911         { } /* end */
912 };
913
914 /* 8ch mode */
915 static struct hda_verb alc880_fivestack_ch8_init[] = {
916         /* set line-in to output, unmute it */
917         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
918         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
919         { } /* end */
920 };
921
922 static struct hda_channel_mode alc880_fivestack_modes[2] = {
923         { 6, alc880_fivestack_ch6_init },
924         { 8, alc880_fivestack_ch8_init },
925 };
926
927
928 /*
929  * ALC880 6-stack model
930  *
931  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
932  *      Side = 0x05 (0x0f)
933  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
934  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
935  */
936
937 static hda_nid_t alc880_6st_dac_nids[4] = {
938         /* front, rear, clfe, rear_surr */
939         0x02, 0x03, 0x04, 0x05
940 };
941
942 static struct hda_input_mux alc880_6stack_capture_source = {
943         .num_items = 4,
944         .items = {
945                 { "Mic", 0x0 },
946                 { "Front Mic", 0x1 },
947                 { "Line", 0x2 },
948                 { "CD", 0x4 },
949         },
950 };
951
952 /* fixed 8-channels */
953 static struct hda_channel_mode alc880_sixstack_modes[1] = {
954         { 8, NULL },
955 };
956
957 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
958         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
959         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
960         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
961         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
962         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
963         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
964         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
965         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
966         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
967         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
968         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
969         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
970         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
971         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
972         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
973         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
974         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
975         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
976         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
977         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
978         {
979                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
980                 .name = "Channel Mode",
981                 .info = alc_ch_mode_info,
982                 .get = alc_ch_mode_get,
983                 .put = alc_ch_mode_put,
984         },
985         { } /* end */
986 };
987
988
989 /*
990  * ALC880 W810 model
991  *
992  * W810 has rear IO for:
993  * Front (DAC 02)
994  * Surround (DAC 03)
995  * Center/LFE (DAC 04)
996  * Digital out (06)
997  *
998  * The system also has a pair of internal speakers, and a headphone jack.
999  * These are both connected to Line2 on the codec, hence to DAC 02.
1000  * 
1001  * There is a variable resistor to control the speaker or headphone
1002  * volume. This is a hardware-only device without a software API.
1003  *
1004  * Plugging headphones in will disable the internal speakers. This is
1005  * implemented in hardware, not via the driver using jack sense. In
1006  * a similar fashion, plugging into the rear socket marked "front" will
1007  * disable both the speakers and headphones.
1008  *
1009  * For input, there's a microphone jack, and an "audio in" jack.
1010  * These may not do anything useful with this driver yet, because I
1011  * haven't setup any initialization verbs for these yet...
1012  */
1013
1014 static hda_nid_t alc880_w810_dac_nids[3] = {
1015         /* front, rear/surround, clfe */
1016         0x02, 0x03, 0x04
1017 };
1018
1019 /* fixed 6 channels */
1020 static struct hda_channel_mode alc880_w810_modes[1] = {
1021         { 6, NULL }
1022 };
1023
1024 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1025 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1026         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1027         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1028         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1029         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1030         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1031         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1032         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1033         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1034         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1035         { } /* end */
1036 };
1037
1038
1039 /*
1040  * Z710V model
1041  *
1042  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1043  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1044  *                 Line = 0x1a
1045  */
1046
1047 static hda_nid_t alc880_z71v_dac_nids[1] = {
1048         0x02
1049 };
1050 #define ALC880_Z71V_HP_DAC      0x03
1051
1052 /* fixed 2 channels */
1053 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1054         { 2, NULL }
1055 };
1056
1057 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1058         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1059         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1060         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1061         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1062         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1063         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1064         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1065         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1066         { } /* end */
1067 };
1068
1069
1070 /* FIXME! */
1071 /*
1072  * ALC880 F1734 model
1073  *
1074  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1075  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1076  */
1077
1078 static hda_nid_t alc880_f1734_dac_nids[1] = {
1079         0x03
1080 };
1081 #define ALC880_F1734_HP_DAC     0x02
1082
1083 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1084         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1085         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1086         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1087         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1088         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1089         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1090         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1091         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1092         { } /* end */
1093 };
1094
1095
1096 /* FIXME! */
1097 /*
1098  * ALC880 ASUS model
1099  *
1100  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1101  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1102  *  Mic = 0x18, Line = 0x1a
1103  */
1104
1105 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1106 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1107
1108 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1109         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1110         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1111         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1112         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1113         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1114         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1115         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1116         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1117         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1118         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1119         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1120         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1121         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1122         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1123         {
1124                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1125                 .name = "Channel Mode",
1126                 .info = alc_ch_mode_info,
1127                 .get = alc_ch_mode_get,
1128                 .put = alc_ch_mode_put,
1129         },
1130         { } /* end */
1131 };
1132
1133 /* FIXME! */
1134 /*
1135  * ALC880 ASUS W1V model
1136  *
1137  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1138  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1139  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1140  */
1141
1142 /* additional mixers to alc880_asus_mixer */
1143 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1144         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1145         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1146         { } /* end */
1147 };
1148
1149 /* additional mixers to alc880_asus_mixer */
1150 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1151         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1152         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1153         { } /* end */
1154 };
1155
1156 /* TCL S700 */
1157 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1158         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1159         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1160         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1161         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1162         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1163         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1164         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1165         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1166         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1167         {
1168                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1169                 /* The multiple "Capture Source" controls confuse alsamixer
1170                  * So call somewhat different..
1171                  * FIXME: the controls appear in the "playback" view!
1172                  */
1173                 /* .name = "Capture Source", */
1174                 .name = "Input Source",
1175                 .count = 1,
1176                 .info = alc_mux_enum_info,
1177                 .get = alc_mux_enum_get,
1178                 .put = alc_mux_enum_put,
1179         },
1180         { } /* end */
1181 };
1182
1183 /* Uniwill */
1184 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1185         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1186         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1187         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1188         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1189         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1190         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1191         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1192         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1193         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1194         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1195         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1196         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1197         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1198         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1199         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1200         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1201         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1202         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1203         {
1204                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1205                 .name = "Channel Mode",
1206                 .info = alc_ch_mode_info,
1207                 .get = alc_ch_mode_get,
1208                 .put = alc_ch_mode_put,
1209         },
1210         { } /* end */
1211 };
1212
1213 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1214         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1215         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1216         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1217         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1218         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1219         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1220         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1221         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1222         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1223         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1224         { } /* end */
1225 };
1226
1227 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1228         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1229         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1230         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1231         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1232         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1233         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1234         { } /* end */
1235 };
1236
1237 /*
1238  * build control elements
1239  */
1240 static int alc_build_controls(struct hda_codec *codec)
1241 {
1242         struct alc_spec *spec = codec->spec;
1243         int err;
1244         int i;
1245
1246         for (i = 0; i < spec->num_mixers; i++) {
1247                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1248                 if (err < 0)
1249                         return err;
1250         }
1251
1252         if (spec->multiout.dig_out_nid) {
1253                 err = snd_hda_create_spdif_out_ctls(codec,
1254                                                     spec->multiout.dig_out_nid);
1255                 if (err < 0)
1256                         return err;
1257         }
1258         if (spec->dig_in_nid) {
1259                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1260                 if (err < 0)
1261                         return err;
1262         }
1263         return 0;
1264 }
1265
1266
1267 /*
1268  * initialize the codec volumes, etc
1269  */
1270
1271 /*
1272  * generic initialization of ADC, input mixers and output mixers
1273  */
1274 static struct hda_verb alc880_volume_init_verbs[] = {
1275         /*
1276          * Unmute ADC0-2 and set the default input to mic-in
1277          */
1278         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1279         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1280         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1281         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1282         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1283         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1284
1285         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1286          * mixer widget
1287          * Note: PASD motherboards uses the Line In 2 as the input for front
1288          * panel mic (mic 2)
1289          */
1290         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1291         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1292         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1293         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1294         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1295         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1296
1297         /*
1298          * Set up output mixers (0x0c - 0x0f)
1299          */
1300         /* set vol=0 to output mixers */
1301         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1302         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1303         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1304         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1305         /* set up input amps for analog loopback */
1306         /* Amp Indices: DAC = 0, mixer = 1 */
1307         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1308         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1309         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1310         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1311         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1312         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1313         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1314         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1315
1316         { }
1317 };
1318
1319 /*
1320  * 3-stack pin configuration:
1321  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1322  */
1323 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1324         /*
1325          * preset connection lists of input pins
1326          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1327          */
1328         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1329         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1330         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1331
1332         /*
1333          * Set pin mode and muting
1334          */
1335         /* set front pin widgets 0x14 for output */
1336         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1337         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1338         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1339         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1340         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1341         /* Mic2 (as headphone out) for HP output */
1342         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1343         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1344         /* Line In pin widget for input */
1345         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1346         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1347         /* Line2 (as front mic) pin widget for input and vref at 80% */
1348         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1349         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1350         /* CD pin widget for input */
1351         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1352
1353         { }
1354 };
1355
1356 /*
1357  * 5-stack pin configuration:
1358  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1359  * line-in/side = 0x1a, f-mic = 0x1b
1360  */
1361 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1362         /*
1363          * preset connection lists of input pins
1364          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1365          */
1366         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1367         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1368
1369         /*
1370          * Set pin mode and muting
1371          */
1372         /* set pin widgets 0x14-0x17 for output */
1373         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1374         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1375         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1377         /* unmute pins for output (no gain on this amp) */
1378         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1379         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1380         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1381         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1382
1383         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1384         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1385         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1386         /* Mic2 (as headphone out) for HP output */
1387         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1388         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1389         /* Line In pin widget for input */
1390         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1391         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1392         /* Line2 (as front mic) pin widget for input and vref at 80% */
1393         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1394         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1395         /* CD pin widget for input */
1396         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1397
1398         { }
1399 };
1400
1401 /*
1402  * W810 pin configuration:
1403  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1404  */
1405 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1406         /* hphone/speaker input selector: front DAC */
1407         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1408
1409         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1410         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1411         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1412         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1413         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1414         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1415
1416         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1417         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1418
1419         { }
1420 };
1421
1422 /*
1423  * Z71V pin configuration:
1424  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1425  */
1426 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1427         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1428         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1429         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1430         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1431
1432         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1433         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1434         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1435         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1436
1437         { }
1438 };
1439
1440 /*
1441  * 6-stack pin configuration:
1442  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1443  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1444  */
1445 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1446         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1447
1448         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1449         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1450         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1451         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1452         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1453         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1454         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1455         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1456
1457         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1458         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1459         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1460         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1461         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1462         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1463         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1464         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1466         
1467         { }
1468 };
1469
1470 /*
1471  * Uniwill pin configuration:
1472  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1473  * line = 0x1a
1474  */
1475 static struct hda_verb alc880_uniwill_init_verbs[] = {
1476         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1477
1478         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1479         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1480         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1481         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1482         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1483         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1484         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1485         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1486         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1487         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1488         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1489         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1490         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1491         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1492
1493         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1494         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1495         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1496         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1497         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1498         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1499         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1500         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1501         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1502
1503         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1504         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1505
1506         { }
1507 };
1508
1509 /*
1510 * Uniwill P53
1511 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1512  */
1513 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1514         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1515
1516         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1517         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1518         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1519         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1520         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1521         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1522         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1523         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1524         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1525         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1526         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1527         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1528
1529         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1530         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1531         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1532         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1533         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1534         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1535
1536         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1537         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1538
1539         { }
1540 };
1541
1542 static struct hda_verb alc880_beep_init_verbs[] = {
1543         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1544         { }
1545 };
1546
1547 /* toggle speaker-output according to the hp-jack state */
1548 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1549 {
1550         unsigned int present;
1551         unsigned char bits;
1552
1553         present = snd_hda_codec_read(codec, 0x14, 0,
1554                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1555         bits = present ? 0x80 : 0;
1556         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1557                                  0x80, bits);
1558         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1559                                  0x80, bits);
1560         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1561                                  0x80, bits);
1562         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1563                                  0x80, bits);
1564 }
1565
1566 /* auto-toggle front mic */
1567 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1568 {
1569         unsigned int present;
1570         unsigned char bits;
1571
1572         present = snd_hda_codec_read(codec, 0x18, 0,
1573                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1574         bits = present ? 0x80 : 0;
1575         snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
1576                                  0x80, bits);
1577         snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
1578                                  0x80, bits);
1579 }
1580
1581 static void alc880_uniwill_automute(struct hda_codec *codec)
1582 {
1583         alc880_uniwill_hp_automute(codec);
1584         alc880_uniwill_mic_automute(codec);
1585 }
1586
1587 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1588                                        unsigned int res)
1589 {
1590         /* Looks like the unsol event is incompatible with the standard
1591          * definition.  4bit tag is placed at 28 bit!
1592          */
1593         switch (res >> 28) {
1594         case ALC880_HP_EVENT:
1595                 alc880_uniwill_hp_automute(codec);
1596                 break;
1597         case ALC880_MIC_EVENT:
1598                 alc880_uniwill_mic_automute(codec);
1599                 break;
1600         }
1601 }
1602
1603 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1604 {
1605         unsigned int present;
1606         unsigned char bits;
1607
1608         present = snd_hda_codec_read(codec, 0x14, 0,
1609                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1610         bits = present ? 0x80 : 0;
1611         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1612                                  0x80, bits);
1613         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1614                                  0x80, bits);
1615 }
1616
1617 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1618 {
1619         unsigned int present;
1620         
1621         present = snd_hda_codec_read(codec, 0x21, 0,
1622                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1623
1624         snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1625                                  0x7f, present);
1626         snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1627                                  0x7f,  present);
1628
1629         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1630                                  0x7f,  present);
1631         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1632                                  0x7f, present);
1633
1634 }
1635 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1636                                            unsigned int res)
1637 {
1638         /* Looks like the unsol event is incompatible with the standard
1639          * definition.  4bit tag is placed at 28 bit!
1640          */
1641         if ((res >> 28) == ALC880_HP_EVENT)
1642                 alc880_uniwill_p53_hp_automute(codec);
1643         if ((res >> 28) == ALC880_DCVOL_EVENT)
1644                 alc880_uniwill_p53_dcvol_automute(codec);
1645 }
1646
1647 /* FIXME! */
1648 /*
1649  * F1734 pin configuration:
1650  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1651  */
1652 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1653         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1654         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1655         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1656         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1657
1658         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1659         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1660         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1661         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1662
1663         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1664         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1665         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1666         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1667         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1668         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1669         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1670         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1672
1673         { }
1674 };
1675
1676 /* FIXME! */
1677 /*
1678  * ASUS pin configuration:
1679  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1680  */
1681 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1682         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1683         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1684         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1685         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1686
1687         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1688         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1689         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1690         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1694         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1695
1696         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1697         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1698         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1699         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1700         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1701         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1702         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1703         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1705         
1706         { }
1707 };
1708
1709 /* Enable GPIO mask and set output */
1710 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1711 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1712
1713 /* Clevo m520g init */
1714 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1715         /* headphone output */
1716         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1717         /* line-out */
1718         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1719         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1720         /* Line-in */
1721         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1722         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1723         /* CD */
1724         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1725         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1726         /* Mic1 (rear panel) */
1727         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1728         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1729         /* Mic2 (front panel) */
1730         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1731         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732         /* headphone */
1733         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1734         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1735         /* change to EAPD mode */
1736         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1737         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1738
1739         { }
1740 };
1741
1742 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1743         /* change to EAPD mode */
1744         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1745         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1746
1747         /* Headphone output */
1748         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1749         /* Front output*/
1750         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1751         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1752
1753         /* Line In pin widget for input */
1754         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1755         /* CD pin widget for input */
1756         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1757         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1758         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1759
1760         /* change to EAPD mode */
1761         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1762         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1763
1764         { }
1765 };
1766
1767 /*
1768  * LG m1 express dual
1769  *
1770  * Pin assignment:
1771  *   Rear Line-In/Out (blue): 0x14
1772  *   Build-in Mic-In: 0x15
1773  *   Speaker-out: 0x17
1774  *   HP-Out (green): 0x1b
1775  *   Mic-In/Out (red): 0x19
1776  *   SPDIF-Out: 0x1e
1777  */
1778
1779 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1780 static hda_nid_t alc880_lg_dac_nids[3] = {
1781         0x05, 0x02, 0x03
1782 };
1783
1784 /* seems analog CD is not working */
1785 static struct hda_input_mux alc880_lg_capture_source = {
1786         .num_items = 3,
1787         .items = {
1788                 { "Mic", 0x1 },
1789                 { "Line", 0x5 },
1790                 { "Internal Mic", 0x6 },
1791         },
1792 };
1793
1794 /* 2,4,6 channel modes */
1795 static struct hda_verb alc880_lg_ch2_init[] = {
1796         /* set line-in and mic-in to input */
1797         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1798         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1799         { }
1800 };
1801
1802 static struct hda_verb alc880_lg_ch4_init[] = {
1803         /* set line-in to out and mic-in to input */
1804         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1805         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1806         { }
1807 };
1808
1809 static struct hda_verb alc880_lg_ch6_init[] = {
1810         /* set line-in and mic-in to output */
1811         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1812         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1813         { }
1814 };
1815
1816 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1817         { 2, alc880_lg_ch2_init },
1818         { 4, alc880_lg_ch4_init },
1819         { 6, alc880_lg_ch6_init },
1820 };
1821
1822 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1823         /* FIXME: it's not really "master" but front channels */
1824         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1825         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1826         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1827         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1828         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1829         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1830         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1831         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1832         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1833         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1834         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1835         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1836         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1837         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1838         {
1839                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1840                 .name = "Channel Mode",
1841                 .info = alc_ch_mode_info,
1842                 .get = alc_ch_mode_get,
1843                 .put = alc_ch_mode_put,
1844         },
1845         { } /* end */
1846 };
1847
1848 static struct hda_verb alc880_lg_init_verbs[] = {
1849         /* set capture source to mic-in */
1850         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1851         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1852         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1853         /* mute all amp mixer inputs */
1854         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1855         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1856         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1857         /* line-in to input */
1858         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1859         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1860         /* built-in mic */
1861         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1862         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863         /* speaker-out */
1864         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1865         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866         /* mic-in to input */
1867         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1868         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1869         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870         /* HP-out */
1871         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1872         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1873         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874         /* jack sense */
1875         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1876         { }
1877 };
1878
1879 /* toggle speaker-output according to the hp-jack state */
1880 static void alc880_lg_automute(struct hda_codec *codec)
1881 {
1882         unsigned int present;
1883         unsigned char bits;
1884
1885         present = snd_hda_codec_read(codec, 0x1b, 0,
1886                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1887         bits = present ? 0x80 : 0;
1888         snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1889                                  0x80, bits);
1890         snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1891                                  0x80, bits);
1892 }
1893
1894 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1895 {
1896         /* Looks like the unsol event is incompatible with the standard
1897          * definition.  4bit tag is placed at 28 bit!
1898          */
1899         if ((res >> 28) == 0x01)
1900                 alc880_lg_automute(codec);
1901 }
1902
1903 /*
1904  * LG LW20
1905  *
1906  * Pin assignment:
1907  *   Speaker-out: 0x14
1908  *   Mic-In: 0x18
1909  *   Built-in Mic-In: 0x19
1910  *   Line-In: 0x1b
1911  *   HP-Out: 0x1a
1912  *   SPDIF-Out: 0x1e
1913  */
1914
1915 static struct hda_input_mux alc880_lg_lw_capture_source = {
1916         .num_items = 3,
1917         .items = {
1918                 { "Mic", 0x0 },
1919                 { "Internal Mic", 0x1 },
1920                 { "Line In", 0x2 },
1921         },
1922 };
1923
1924 #define alc880_lg_lw_modes alc880_threestack_modes
1925
1926 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1927         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1928         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1929         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1930         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1931         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1932         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1933         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1934         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1935         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1936         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1937         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1938         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1939         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1940         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1941         {
1942                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1943                 .name = "Channel Mode",
1944                 .info = alc_ch_mode_info,
1945                 .get = alc_ch_mode_get,
1946                 .put = alc_ch_mode_put,
1947         },
1948         { } /* end */
1949 };
1950
1951 static struct hda_verb alc880_lg_lw_init_verbs[] = {
1952         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1953         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1954         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1955
1956         /* set capture source to mic-in */
1957         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1958         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1959         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1960         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1961         /* speaker-out */
1962         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1963         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1964         /* HP-out */
1965         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1966         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1967         /* mic-in to input */
1968         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1969         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1970         /* built-in mic */
1971         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1972         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1973         /* jack sense */
1974         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1975         { }
1976 };
1977
1978 /* toggle speaker-output according to the hp-jack state */
1979 static void alc880_lg_lw_automute(struct hda_codec *codec)
1980 {
1981         unsigned int present;
1982         unsigned char bits;
1983
1984         present = snd_hda_codec_read(codec, 0x1b, 0,
1985                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1986         bits = present ? 0x80 : 0;
1987         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1988                                  0x80, bits);
1989         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1990                                  0x80, bits);
1991 }
1992
1993 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1994 {
1995         /* Looks like the unsol event is incompatible with the standard
1996          * definition.  4bit tag is placed at 28 bit!
1997          */
1998         if ((res >> 28) == 0x01)
1999                 alc880_lg_lw_automute(codec);
2000 }
2001
2002 /*
2003  * Common callbacks
2004  */
2005
2006 static int alc_init(struct hda_codec *codec)
2007 {
2008         struct alc_spec *spec = codec->spec;
2009         unsigned int i;
2010
2011         for (i = 0; i < spec->num_init_verbs; i++)
2012                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2013
2014         if (spec->init_hook)
2015                 spec->init_hook(codec);
2016
2017         return 0;
2018 }
2019
2020 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2021 {
2022         struct alc_spec *spec = codec->spec;
2023
2024         if (spec->unsol_event)
2025                 spec->unsol_event(codec, res);
2026 }
2027
2028 #ifdef CONFIG_PM
2029 /*
2030  * resume
2031  */
2032 static int alc_resume(struct hda_codec *codec)
2033 {
2034         struct alc_spec *spec = codec->spec;
2035         int i;
2036
2037         alc_init(codec);
2038         for (i = 0; i < spec->num_mixers; i++)
2039                 snd_hda_resume_ctls(codec, spec->mixers[i]);
2040         if (spec->multiout.dig_out_nid)
2041                 snd_hda_resume_spdif_out(codec);
2042         if (spec->dig_in_nid)
2043                 snd_hda_resume_spdif_in(codec);
2044
2045         return 0;
2046 }
2047 #endif
2048
2049 /*
2050  * Analog playback callbacks
2051  */
2052 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2053                                     struct hda_codec *codec,
2054                                     struct snd_pcm_substream *substream)
2055 {
2056         struct alc_spec *spec = codec->spec;
2057         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2058 }
2059
2060 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2061                                        struct hda_codec *codec,
2062                                        unsigned int stream_tag,
2063                                        unsigned int format,
2064                                        struct snd_pcm_substream *substream)
2065 {
2066         struct alc_spec *spec = codec->spec;
2067         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2068                                                 stream_tag, format, substream);
2069 }
2070
2071 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2072                                        struct hda_codec *codec,
2073                                        struct snd_pcm_substream *substream)
2074 {
2075         struct alc_spec *spec = codec->spec;
2076         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2077 }
2078
2079 /*
2080  * Digital out
2081  */
2082 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2083                                         struct hda_codec *codec,
2084                                         struct snd_pcm_substream *substream)
2085 {
2086         struct alc_spec *spec = codec->spec;
2087         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2088 }
2089
2090 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2091                                            struct hda_codec *codec,
2092                                            unsigned int stream_tag,
2093                                            unsigned int format,
2094                                            struct snd_pcm_substream *substream)
2095 {
2096         struct alc_spec *spec = codec->spec;
2097         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2098                                              stream_tag, format, substream);
2099 }
2100
2101 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2102                                          struct hda_codec *codec,
2103                                          struct snd_pcm_substream *substream)
2104 {
2105         struct alc_spec *spec = codec->spec;
2106         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2107 }
2108
2109 /*
2110  * Analog capture
2111  */
2112 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2113                                       struct hda_codec *codec,
2114                                       unsigned int stream_tag,
2115                                       unsigned int format,
2116                                       struct snd_pcm_substream *substream)
2117 {
2118         struct alc_spec *spec = codec->spec;
2119
2120         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2121                                    stream_tag, 0, format);
2122         return 0;
2123 }
2124
2125 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2126                                       struct hda_codec *codec,
2127                                       struct snd_pcm_substream *substream)
2128 {
2129         struct alc_spec *spec = codec->spec;
2130
2131         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2132                                    0, 0, 0);
2133         return 0;
2134 }
2135
2136
2137 /*
2138  */
2139 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2140         .substreams = 1,
2141         .channels_min = 2,
2142         .channels_max = 8,
2143         /* NID is set in alc_build_pcms */
2144         .ops = {
2145                 .open = alc880_playback_pcm_open,
2146                 .prepare = alc880_playback_pcm_prepare,
2147                 .cleanup = alc880_playback_pcm_cleanup
2148         },
2149 };
2150
2151 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2152         .substreams = 2,
2153         .channels_min = 2,
2154         .channels_max = 2,
2155         /* NID is set in alc_build_pcms */
2156         .ops = {
2157                 .prepare = alc880_capture_pcm_prepare,
2158                 .cleanup = alc880_capture_pcm_cleanup
2159         },
2160 };
2161
2162 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2163         .substreams = 1,
2164         .channels_min = 2,
2165         .channels_max = 2,
2166         /* NID is set in alc_build_pcms */
2167         .ops = {
2168                 .open = alc880_dig_playback_pcm_open,
2169                 .close = alc880_dig_playback_pcm_close,
2170                 .prepare = alc880_dig_playback_pcm_prepare
2171         },
2172 };
2173
2174 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2175         .substreams = 1,
2176         .channels_min = 2,
2177         .channels_max = 2,
2178         /* NID is set in alc_build_pcms */
2179 };
2180
2181 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2182 static struct hda_pcm_stream alc_pcm_null_playback = {
2183         .substreams = 0,
2184         .channels_min = 0,
2185         .channels_max = 0,
2186 };
2187
2188 static int alc_build_pcms(struct hda_codec *codec)
2189 {
2190         struct alc_spec *spec = codec->spec;
2191         struct hda_pcm *info = spec->pcm_rec;
2192         int i;
2193
2194         codec->num_pcms = 1;
2195         codec->pcm_info = info;
2196
2197         info->name = spec->stream_name_analog;
2198         if (spec->stream_analog_playback) {
2199                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2200                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2201                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2202         }
2203         if (spec->stream_analog_capture) {
2204                 snd_assert(spec->adc_nids, return -EINVAL);
2205                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2206                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2207         }
2208
2209         if (spec->channel_mode) {
2210                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2211                 for (i = 0; i < spec->num_channel_mode; i++) {
2212                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2213                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2214                         }
2215                 }
2216         }
2217
2218         /* SPDIF for stream index #1 */
2219         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2220                 codec->num_pcms = 2;
2221                 info = spec->pcm_rec + 1;
2222                 info->name = spec->stream_name_digital;
2223                 if (spec->multiout.dig_out_nid &&
2224                     spec->stream_digital_playback) {
2225                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2226                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2227                 }
2228                 if (spec->dig_in_nid &&
2229                     spec->stream_digital_capture) {
2230                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2231                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2232                 }
2233         }
2234
2235         /* If the use of more than one ADC is requested for the current
2236          * model, configure a second analog capture-only PCM.
2237          */
2238         /* Additional Analaog capture for index #2 */
2239         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2240             spec->adc_nids) {
2241                 codec->num_pcms = 3;
2242                 info = spec->pcm_rec + 2;
2243                 info->name = spec->stream_name_analog;
2244                 /* No playback stream for second PCM */
2245                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2246                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2247                 if (spec->stream_analog_capture) {
2248                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2249                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2250                 }
2251         }
2252
2253         return 0;
2254 }
2255
2256 static void alc_free(struct hda_codec *codec)
2257 {
2258         struct alc_spec *spec = codec->spec;
2259         unsigned int i;
2260
2261         if (!spec)
2262                 return;
2263
2264         if (spec->kctl_alloc) {
2265                 for (i = 0; i < spec->num_kctl_used; i++)
2266                         kfree(spec->kctl_alloc[i].name);
2267                 kfree(spec->kctl_alloc);
2268         }
2269         kfree(spec);
2270 }
2271
2272 /*
2273  */
2274 static struct hda_codec_ops alc_patch_ops = {
2275         .build_controls = alc_build_controls,
2276         .build_pcms = alc_build_pcms,
2277         .init = alc_init,
2278         .free = alc_free,
2279         .unsol_event = alc_unsol_event,
2280 #ifdef CONFIG_PM
2281         .resume = alc_resume,
2282 #endif
2283 };
2284
2285
2286 /*
2287  * Test configuration for debugging
2288  *
2289  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2290  * enum controls.
2291  */
2292 #ifdef CONFIG_SND_DEBUG
2293 static hda_nid_t alc880_test_dac_nids[4] = {
2294         0x02, 0x03, 0x04, 0x05
2295 };
2296
2297 static struct hda_input_mux alc880_test_capture_source = {
2298         .num_items = 7,
2299         .items = {
2300                 { "In-1", 0x0 },
2301                 { "In-2", 0x1 },
2302                 { "In-3", 0x2 },
2303                 { "In-4", 0x3 },
2304                 { "CD", 0x4 },
2305                 { "Front", 0x5 },
2306                 { "Surround", 0x6 },
2307         },
2308 };
2309
2310 static struct hda_channel_mode alc880_test_modes[4] = {
2311         { 2, NULL },
2312         { 4, NULL },
2313         { 6, NULL },
2314         { 8, NULL },
2315 };
2316
2317 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2318                                  struct snd_ctl_elem_info *uinfo)
2319 {
2320         static char *texts[] = {
2321                 "N/A", "Line Out", "HP Out",
2322                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2323         };
2324         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2325         uinfo->count = 1;
2326         uinfo->value.enumerated.items = 8;
2327         if (uinfo->value.enumerated.item >= 8)
2328                 uinfo->value.enumerated.item = 7;
2329         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2330         return 0;
2331 }
2332
2333 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2334                                 struct snd_ctl_elem_value *ucontrol)
2335 {
2336         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2337         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2338         unsigned int pin_ctl, item = 0;
2339
2340         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2341                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2342         if (pin_ctl & AC_PINCTL_OUT_EN) {
2343                 if (pin_ctl & AC_PINCTL_HP_EN)
2344                         item = 2;
2345                 else
2346                         item = 1;
2347         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2348                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2349                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2350                 case AC_PINCTL_VREF_50:  item = 4; break;
2351                 case AC_PINCTL_VREF_GRD: item = 5; break;
2352                 case AC_PINCTL_VREF_80:  item = 6; break;
2353                 case AC_PINCTL_VREF_100: item = 7; break;
2354                 }
2355         }
2356         ucontrol->value.enumerated.item[0] = item;
2357         return 0;
2358 }
2359
2360 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2361                                 struct snd_ctl_elem_value *ucontrol)
2362 {
2363         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2364         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2365         static unsigned int ctls[] = {
2366                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2367                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2368                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2369                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2370                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2371                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2372         };
2373         unsigned int old_ctl, new_ctl;
2374
2375         old_ctl = snd_hda_codec_read(codec, nid, 0,
2376                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2377         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2378         if (old_ctl != new_ctl) {
2379                 snd_hda_codec_write(codec, nid, 0,
2380                                     AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2381                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2382                                     (ucontrol->value.enumerated.item[0] >= 3 ?
2383                                      0xb080 : 0xb000));
2384                 return 1;
2385         }
2386         return 0;
2387 }
2388
2389 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2390                                  struct snd_ctl_elem_info *uinfo)
2391 {
2392         static char *texts[] = {
2393                 "Front", "Surround", "CLFE", "Side"
2394         };
2395         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2396         uinfo->count = 1;
2397         uinfo->value.enumerated.items = 4;
2398         if (uinfo->value.enumerated.item >= 4)
2399                 uinfo->value.enumerated.item = 3;
2400         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2401         return 0;
2402 }
2403
2404 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2405                                 struct snd_ctl_elem_value *ucontrol)
2406 {
2407         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2408         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2409         unsigned int sel;
2410
2411         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2412         ucontrol->value.enumerated.item[0] = sel & 3;
2413         return 0;
2414 }
2415
2416 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2417                                 struct snd_ctl_elem_value *ucontrol)
2418 {
2419         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2420         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2421         unsigned int sel;
2422
2423         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2424         if (ucontrol->value.enumerated.item[0] != sel) {
2425                 sel = ucontrol->value.enumerated.item[0] & 3;
2426                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2427                 return 1;
2428         }
2429         return 0;
2430 }
2431
2432 #define PIN_CTL_TEST(xname,nid) {                       \
2433                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2434                         .name = xname,                 \
2435                         .info = alc_test_pin_ctl_info, \
2436                         .get = alc_test_pin_ctl_get,   \
2437                         .put = alc_test_pin_ctl_put,   \
2438                         .private_value = nid           \
2439                         }
2440
2441 #define PIN_SRC_TEST(xname,nid) {                       \
2442                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2443                         .name = xname,                 \
2444                         .info = alc_test_pin_src_info, \
2445                         .get = alc_test_pin_src_get,   \
2446                         .put = alc_test_pin_src_put,   \
2447                         .private_value = nid           \
2448                         }
2449
2450 static struct snd_kcontrol_new alc880_test_mixer[] = {
2451         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2452         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2453         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2454         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2455         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2456         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2457         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2458         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2459         PIN_CTL_TEST("Front Pin Mode", 0x14),
2460         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2461         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2462         PIN_CTL_TEST("Side Pin Mode", 0x17),
2463         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2464         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2465         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2466         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2467         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2468         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2469         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2470         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2471         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2472         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2473         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2474         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2475         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2476         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2477         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2478         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2479         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2480         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2481         {
2482                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2483                 .name = "Channel Mode",
2484                 .info = alc_ch_mode_info,
2485                 .get = alc_ch_mode_get,
2486                 .put = alc_ch_mode_put,
2487         },
2488         { } /* end */
2489 };
2490
2491 static struct hda_verb alc880_test_init_verbs[] = {
2492         /* Unmute inputs of 0x0c - 0x0f */
2493         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2494         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2495         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2496         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2497         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2498         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2499         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2500         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2501         /* Vol output for 0x0c-0x0f */
2502         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2503         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2504         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2505         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2506         /* Set output pins 0x14-0x17 */
2507         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2508         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2509         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2510         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2511         /* Unmute output pins 0x14-0x17 */
2512         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2513         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2514         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2515         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2516         /* Set input pins 0x18-0x1c */
2517         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2518         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2519         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2520         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2521         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2522         /* Mute input pins 0x18-0x1b */
2523         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2524         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2525         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2526         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2527         /* ADC set up */
2528         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2529         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2530         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2531         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2532         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2533         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2534         /* Analog input/passthru */
2535         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2536         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2537         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2538         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2539         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2540         { }
2541 };
2542 #endif
2543
2544 /*
2545  */
2546
2547 static const char *alc880_models[ALC880_MODEL_LAST] = {
2548         [ALC880_3ST]            = "3stack",
2549         [ALC880_TCL_S700]       = "tcl",
2550         [ALC880_3ST_DIG]        = "3stack-digout",
2551         [ALC880_CLEVO]          = "clevo",
2552         [ALC880_5ST]            = "5stack",
2553         [ALC880_5ST_DIG]        = "5stack-digout",
2554         [ALC880_W810]           = "w810",
2555         [ALC880_Z71V]           = "z71v",
2556         [ALC880_6ST]            = "6stack",
2557         [ALC880_6ST_DIG]        = "6stack-digout",
2558         [ALC880_ASUS]           = "asus",
2559         [ALC880_ASUS_W1V]       = "asus-w1v",
2560         [ALC880_ASUS_DIG]       = "asus-dig",
2561         [ALC880_ASUS_DIG2]      = "asus-dig2",
2562         [ALC880_UNIWILL_DIG]    = "uniwill",
2563         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2564         [ALC880_FUJITSU]        = "fujitsu",
2565         [ALC880_F1734]          = "F1734",
2566         [ALC880_LG]             = "lg",
2567         [ALC880_LG_LW]          = "lg-lw",
2568 #ifdef CONFIG_SND_DEBUG
2569         [ALC880_TEST]           = "test",
2570 #endif
2571         [ALC880_AUTO]           = "auto",
2572 };
2573
2574 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2575         /* Broken BIOS configuration */
2576         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2577         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2578
2579         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2580         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2581         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2582         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2583         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2584         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2585         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2586         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2587         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2588
2589         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2590         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2591
2592         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2593         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2594         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2595         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2596         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2597         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2598         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2599         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2600         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2601         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2602         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2603         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2604         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2605         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2606         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2607
2608         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2609         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2610         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2611         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2612         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2613         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2614         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2615         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2616         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2617         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2618         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2619         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2620         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2621         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2622         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2623         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2624         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2625         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2626
2627         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2628         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2629         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2630         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2631
2632         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2633         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2634         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2635         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2636
2637         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2638         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2639         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2640         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2641
2642         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2643         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2644         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2645         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2646         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2647         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2648         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2649         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2650         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2651         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2652         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2653
2654         {}
2655 };
2656
2657 /*
2658  * ALC880 codec presets
2659  */
2660 static struct alc_config_preset alc880_presets[] = {
2661         [ALC880_3ST] = {
2662                 .mixers = { alc880_three_stack_mixer },
2663                 .init_verbs = { alc880_volume_init_verbs,
2664                                 alc880_pin_3stack_init_verbs },
2665                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2666                 .dac_nids = alc880_dac_nids,
2667                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2668                 .channel_mode = alc880_threestack_modes,
2669                 .need_dac_fix = 1,
2670                 .input_mux = &alc880_capture_source,
2671         },
2672         [ALC880_3ST_DIG] = {
2673                 .mixers = { alc880_three_stack_mixer },
2674                 .init_verbs = { alc880_volume_init_verbs,
2675                                 alc880_pin_3stack_init_verbs },
2676                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2677                 .dac_nids = alc880_dac_nids,
2678                 .dig_out_nid = ALC880_DIGOUT_NID,
2679                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2680                 .channel_mode = alc880_threestack_modes,
2681                 .need_dac_fix = 1,
2682                 .input_mux = &alc880_capture_source,
2683         },
2684         [ALC880_TCL_S700] = {
2685                 .mixers = { alc880_tcl_s700_mixer },
2686                 .init_verbs = { alc880_volume_init_verbs,
2687                                 alc880_pin_tcl_S700_init_verbs,
2688                                 alc880_gpio2_init_verbs },
2689                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2690                 .dac_nids = alc880_dac_nids,
2691                 .hp_nid = 0x03,
2692                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2693                 .channel_mode = alc880_2_jack_modes,
2694                 .input_mux = &alc880_capture_source,
2695         },
2696         [ALC880_5ST] = {
2697                 .mixers = { alc880_three_stack_mixer,
2698                             alc880_five_stack_mixer},
2699                 .init_verbs = { alc880_volume_init_verbs,
2700                                 alc880_pin_5stack_init_verbs },
2701                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2702                 .dac_nids = alc880_dac_nids,
2703                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2704                 .channel_mode = alc880_fivestack_modes,
2705                 .input_mux = &alc880_capture_source,
2706         },
2707         [ALC880_5ST_DIG] = {
2708                 .mixers = { alc880_three_stack_mixer,
2709                             alc880_five_stack_mixer },
2710                 .init_verbs = { alc880_volume_init_verbs,
2711                                 alc880_pin_5stack_init_verbs },
2712                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2713                 .dac_nids = alc880_dac_nids,
2714                 .dig_out_nid = ALC880_DIGOUT_NID,
2715                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2716                 .channel_mode = alc880_fivestack_modes,
2717                 .input_mux = &alc880_capture_source,
2718         },
2719         [ALC880_6ST] = {
2720                 .mixers = { alc880_six_stack_mixer },
2721                 .init_verbs = { alc880_volume_init_verbs,
2722                                 alc880_pin_6stack_init_verbs },
2723                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2724                 .dac_nids = alc880_6st_dac_nids,
2725                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2726                 .channel_mode = alc880_sixstack_modes,
2727                 .input_mux = &alc880_6stack_capture_source,
2728         },
2729         [ALC880_6ST_DIG] = {
2730                 .mixers = { alc880_six_stack_mixer },
2731                 .init_verbs = { alc880_volume_init_verbs,
2732                                 alc880_pin_6stack_init_verbs },
2733                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2734                 .dac_nids = alc880_6st_dac_nids,
2735                 .dig_out_nid = ALC880_DIGOUT_NID,
2736                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2737                 .channel_mode = alc880_sixstack_modes,
2738                 .input_mux = &alc880_6stack_capture_source,
2739         },
2740         [ALC880_W810] = {
2741                 .mixers = { alc880_w810_base_mixer },
2742                 .init_verbs = { alc880_volume_init_verbs,
2743                                 alc880_pin_w810_init_verbs,
2744                                 alc880_gpio2_init_verbs },
2745                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2746                 .dac_nids = alc880_w810_dac_nids,
2747                 .dig_out_nid = ALC880_DIGOUT_NID,
2748                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2749                 .channel_mode = alc880_w810_modes,
2750                 .input_mux = &alc880_capture_source,
2751         },
2752         [ALC880_Z71V] = {
2753                 .mixers = { alc880_z71v_mixer },
2754                 .init_verbs = { alc880_volume_init_verbs,
2755                                 alc880_pin_z71v_init_verbs },
2756                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2757                 .dac_nids = alc880_z71v_dac_nids,
2758                 .dig_out_nid = ALC880_DIGOUT_NID,
2759                 .hp_nid = 0x03,
2760                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2761                 .channel_mode = alc880_2_jack_modes,
2762                 .input_mux = &alc880_capture_source,
2763         },
2764         [ALC880_F1734] = {
2765                 .mixers = { alc880_f1734_mixer },
2766                 .init_verbs = { alc880_volume_init_verbs,
2767                                 alc880_pin_f1734_init_verbs },
2768                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2769                 .dac_nids = alc880_f1734_dac_nids,
2770                 .hp_nid = 0x02,
2771                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2772                 .channel_mode = alc880_2_jack_modes,
2773                 .input_mux = &alc880_capture_source,
2774         },
2775         [ALC880_ASUS] = {
2776                 .mixers = { alc880_asus_mixer },
2777                 .init_verbs = { alc880_volume_init_verbs,
2778                                 alc880_pin_asus_init_verbs,
2779                                 alc880_gpio1_init_verbs },
2780                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2781                 .dac_nids = alc880_asus_dac_nids,
2782                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2783                 .channel_mode = alc880_asus_modes,
2784                 .need_dac_fix = 1,
2785                 .input_mux = &alc880_capture_source,
2786         },
2787         [ALC880_ASUS_DIG] = {
2788                 .mixers = { alc880_asus_mixer },
2789                 .init_verbs = { alc880_volume_init_verbs,
2790                                 alc880_pin_asus_init_verbs,
2791                                 alc880_gpio1_init_verbs },
2792                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2793                 .dac_nids = alc880_asus_dac_nids,
2794                 .dig_out_nid = ALC880_DIGOUT_NID,
2795                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2796                 .channel_mode = alc880_asus_modes,
2797                 .need_dac_fix = 1,
2798                 .input_mux = &alc880_capture_source,
2799         },
2800         [ALC880_ASUS_DIG2] = {
2801                 .mixers = { alc880_asus_mixer },
2802                 .init_verbs = { alc880_volume_init_verbs,
2803                                 alc880_pin_asus_init_verbs,
2804                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2805                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2806                 .dac_nids = alc880_asus_dac_nids,
2807                 .dig_out_nid = ALC880_DIGOUT_NID,
2808                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2809                 .channel_mode = alc880_asus_modes,
2810                 .need_dac_fix = 1,
2811                 .input_mux = &alc880_capture_source,
2812         },
2813         [ALC880_ASUS_W1V] = {
2814                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2815                 .init_verbs = { alc880_volume_init_verbs,
2816                                 alc880_pin_asus_init_verbs,
2817                                 alc880_gpio1_init_verbs },
2818                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2819                 .dac_nids = alc880_asus_dac_nids,
2820                 .dig_out_nid = ALC880_DIGOUT_NID,
2821                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2822                 .channel_mode = alc880_asus_modes,
2823                 .need_dac_fix = 1,
2824                 .input_mux = &alc880_capture_source,
2825         },
2826         [ALC880_UNIWILL_DIG] = {
2827                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2828                 .init_verbs = { alc880_volume_init_verbs,
2829                                 alc880_pin_asus_init_verbs },
2830                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2831                 .dac_nids = alc880_asus_dac_nids,
2832                 .dig_out_nid = ALC880_DIGOUT_NID,
2833                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2834                 .channel_mode = alc880_asus_modes,
2835                 .need_dac_fix = 1,
2836                 .input_mux = &alc880_capture_source,
2837         },
2838         [ALC880_UNIWILL] = {
2839                 .mixers = { alc880_uniwill_mixer },
2840                 .init_verbs = { alc880_volume_init_verbs,
2841                                 alc880_uniwill_init_verbs },
2842                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2843                 .dac_nids = alc880_asus_dac_nids,
2844                 .dig_out_nid = ALC880_DIGOUT_NID,
2845                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2846                 .channel_mode = alc880_threestack_modes,
2847                 .need_dac_fix = 1,
2848                 .input_mux = &alc880_capture_source,
2849                 .unsol_event = alc880_uniwill_unsol_event,
2850                 .init_hook = alc880_uniwill_automute,
2851         },
2852         [ALC880_UNIWILL_P53] = {
2853                 .mixers = { alc880_uniwill_p53_mixer },
2854                 .init_verbs = { alc880_volume_init_verbs,
2855                                 alc880_uniwill_p53_init_verbs },
2856                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2857                 .dac_nids = alc880_asus_dac_nids,
2858                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2859                 .channel_mode = alc880_threestack_modes,
2860                 .input_mux = &alc880_capture_source,
2861                 .unsol_event = alc880_uniwill_p53_unsol_event,
2862                 .init_hook = alc880_uniwill_p53_hp_automute,
2863         },
2864         [ALC880_FUJITSU] = {
2865                 .mixers = { alc880_fujitsu_mixer,
2866                             alc880_pcbeep_mixer, },
2867                 .init_verbs = { alc880_volume_init_verbs,
2868                                 alc880_uniwill_p53_init_verbs,
2869                                 alc880_beep_init_verbs },
2870                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2871                 .dac_nids = alc880_dac_nids,
2872                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2873                 .channel_mode = alc880_2_jack_modes,
2874                 .input_mux = &alc880_capture_source,
2875                 .unsol_event = alc880_uniwill_p53_unsol_event,
2876                 .init_hook = alc880_uniwill_p53_hp_automute,
2877         },
2878         [ALC880_CLEVO] = {
2879                 .mixers = { alc880_three_stack_mixer },
2880                 .init_verbs = { alc880_volume_init_verbs,
2881                                 alc880_pin_clevo_init_verbs },
2882                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2883                 .dac_nids = alc880_dac_nids,
2884                 .hp_nid = 0x03,
2885                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2886                 .channel_mode = alc880_threestack_modes,
2887                 .need_dac_fix = 1,
2888                 .input_mux = &alc880_capture_source,
2889         },
2890         [ALC880_LG] = {
2891                 .mixers = { alc880_lg_mixer },
2892                 .init_verbs = { alc880_volume_init_verbs,
2893                                 alc880_lg_init_verbs },
2894                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2895                 .dac_nids = alc880_lg_dac_nids,
2896                 .dig_out_nid = ALC880_DIGOUT_NID,
2897                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2898                 .channel_mode = alc880_lg_ch_modes,
2899                 .need_dac_fix = 1,
2900                 .input_mux = &alc880_lg_capture_source,
2901                 .unsol_event = alc880_lg_unsol_event,
2902                 .init_hook = alc880_lg_automute,
2903         },
2904         [ALC880_LG_LW] = {
2905                 .mixers = { alc880_lg_lw_mixer },
2906                 .init_verbs = { alc880_volume_init_verbs,
2907                                 alc880_lg_lw_init_verbs },
2908                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2909                 .dac_nids = alc880_dac_nids,
2910                 .dig_out_nid = ALC880_DIGOUT_NID,
2911                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2912                 .channel_mode = alc880_lg_lw_modes,
2913                 .input_mux = &alc880_lg_lw_capture_source,
2914                 .unsol_event = alc880_lg_lw_unsol_event,
2915                 .init_hook = alc880_lg_lw_automute,
2916         },
2917 #ifdef CONFIG_SND_DEBUG
2918         [ALC880_TEST] = {
2919                 .mixers = { alc880_test_mixer },
2920                 .init_verbs = { alc880_test_init_verbs },
2921                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2922                 .dac_nids = alc880_test_dac_nids,
2923                 .dig_out_nid = ALC880_DIGOUT_NID,
2924                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2925                 .channel_mode = alc880_test_modes,
2926                 .input_mux = &alc880_test_capture_source,
2927         },
2928 #endif
2929 };
2930
2931 /*
2932  * Automatic parse of I/O pins from the BIOS configuration
2933  */
2934
2935 #define NUM_CONTROL_ALLOC       32
2936 #define NUM_VERB_ALLOC          32
2937
2938 enum {
2939         ALC_CTL_WIDGET_VOL,
2940         ALC_CTL_WIDGET_MUTE,
2941         ALC_CTL_BIND_MUTE,
2942 };
2943 static struct snd_kcontrol_new alc880_control_templates[] = {
2944         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2945         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2946         HDA_BIND_MUTE(NULL, 0, 0, 0),
2947 };
2948
2949 /* add dynamic controls */
2950 static int add_control(struct alc_spec *spec, int type, const char *name,
2951                        unsigned long val)
2952 {
2953         struct snd_kcontrol_new *knew;
2954
2955         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2956                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2957
2958                 /* array + terminator */
2959                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2960                 if (!knew)
2961                         return -ENOMEM;
2962                 if (spec->kctl_alloc) {
2963                         memcpy(knew, spec->kctl_alloc,
2964                                sizeof(*knew) * spec->num_kctl_alloc);
2965                         kfree(spec->kctl_alloc);
2966                 }
2967                 spec->kctl_alloc = knew;
2968                 spec->num_kctl_alloc = num;
2969         }
2970
2971         knew = &spec->kctl_alloc[spec->num_kctl_used];
2972         *knew = alc880_control_templates[type];
2973         knew->name = kstrdup(name, GFP_KERNEL);
2974         if (!knew->name)
2975                 return -ENOMEM;
2976         knew->private_value = val;
2977         spec->num_kctl_used++;
2978         return 0;
2979 }
2980
2981 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
2982 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
2983 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
2984 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
2985 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
2986 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
2987 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
2988 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
2989 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
2990 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
2991 #define ALC880_PIN_CD_NID               0x1c
2992
2993 /* fill in the dac_nids table from the parsed pin configuration */
2994 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
2995                                      const struct auto_pin_cfg *cfg)
2996 {
2997         hda_nid_t nid;
2998         int assigned[4];
2999         int i, j;
3000
3001         memset(assigned, 0, sizeof(assigned));
3002         spec->multiout.dac_nids = spec->private_dac_nids;
3003
3004         /* check the pins hardwired to audio widget */
3005         for (i = 0; i < cfg->line_outs; i++) {
3006                 nid = cfg->line_out_pins[i];
3007                 if (alc880_is_fixed_pin(nid)) {
3008                         int idx = alc880_fixed_pin_idx(nid);
3009                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3010                         assigned[idx] = 1;
3011                 }
3012         }
3013         /* left pins can be connect to any audio widget */
3014         for (i = 0; i < cfg->line_outs; i++) {
3015                 nid = cfg->line_out_pins[i];
3016                 if (alc880_is_fixed_pin(nid))
3017                         continue;
3018                 /* search for an empty channel */
3019                 for (j = 0; j < cfg->line_outs; j++) {
3020                         if (!assigned[j]) {
3021                                 spec->multiout.dac_nids[i] =
3022                                         alc880_idx_to_dac(j);
3023                                 assigned[j] = 1;
3024                                 break;
3025                         }
3026                 }
3027         }
3028         spec->multiout.num_dacs = cfg->line_outs;
3029         return 0;
3030 }
3031
3032 /* add playback controls from the parsed DAC table */
3033 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3034                                              const struct auto_pin_cfg *cfg)
3035 {
3036         char name[32];
3037         static const char *chname[4] = {
3038                 "Front", "Surround", NULL /*CLFE*/, "Side"
3039         };
3040         hda_nid_t nid;
3041         int i, err;
3042
3043         for (i = 0; i < cfg->line_outs; i++) {
3044                 if (!spec->multiout.dac_nids[i])
3045                         continue;
3046                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3047                 if (i == 2) {
3048                         /* Center/LFE */
3049                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3050                                           "Center Playback Volume",
3051                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3052                                                               HDA_OUTPUT));
3053                         if (err < 0)
3054                                 return err;
3055                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3056                                           "LFE Playback Volume",
3057                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3058                                                               HDA_OUTPUT));
3059                         if (err < 0)
3060                                 return err;
3061                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3062                                           "Center Playback Switch",
3063                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3064                                                               HDA_INPUT));
3065                         if (err < 0)
3066                                 return err;
3067                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3068                                           "LFE Playback Switch",
3069                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3070                                                               HDA_INPUT));
3071                         if (err < 0)
3072                                 return err;
3073                 } else {
3074                         sprintf(name, "%s Playback Volume", chname[i]);
3075                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3076                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3077                                                               HDA_OUTPUT));
3078                         if (err < 0)
3079                                 return err;
3080                         sprintf(name, "%s Playback Switch", chname[i]);
3081                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3082                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3083                                                               HDA_INPUT));
3084                         if (err < 0)
3085                                 return err;
3086                 }
3087         }
3088         return 0;
3089 }
3090
3091 /* add playback controls for speaker and HP outputs */
3092 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3093                                         const char *pfx)
3094 {
3095         hda_nid_t nid;
3096         int err;
3097         char name[32];
3098
3099         if (!pin)
3100                 return 0;
3101
3102         if (alc880_is_fixed_pin(pin)) {
3103                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3104                 /* specify the DAC as the extra output */
3105                 if (!spec->multiout.hp_nid)
3106                         spec->multiout.hp_nid = nid;
3107                 else
3108                         spec->multiout.extra_out_nid[0] = nid;
3109                 /* control HP volume/switch on the output mixer amp */
3110                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3111                 sprintf(name, "%s Playback Volume", pfx);
3112                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3113                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3114                 if (err < 0)
3115                         return err;
3116                 sprintf(name, "%s Playback Switch", pfx);
3117                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3118                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3119                 if (err < 0)
3120                         return err;
3121         } else if (alc880_is_multi_pin(pin)) {
3122                 /* set manual connection */
3123                 /* we have only a switch on HP-out PIN */
3124                 sprintf(name, "%s Playback Switch", pfx);
3125                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3126                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3127                 if (err < 0)
3128                         return err;
3129         }
3130         return 0;
3131 }
3132
3133 /* create input playback/capture controls for the given pin */
3134 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3135                             const char *ctlname,
3136                             int idx, hda_nid_t mix_nid)
3137 {
3138         char name[32];
3139         int err;
3140
3141         sprintf(name, "%s Playback Volume", ctlname);
3142         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3143                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3144         if (err < 0)
3145                 return err;
3146         sprintf(name, "%s Playback Switch", ctlname);
3147         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3148                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3149         if (err < 0)
3150                 return err;
3151         return 0;
3152 }
3153
3154 /* create playback/capture controls for input pins */
3155 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3156                                                 const struct auto_pin_cfg *cfg)
3157 {
3158         struct hda_input_mux *imux = &spec->private_imux;
3159         int i, err, idx;
3160
3161         for (i = 0; i < AUTO_PIN_LAST; i++) {
3162                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3163                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3164                         err = new_analog_input(spec, cfg->input_pins[i],
3165                                                auto_pin_cfg_labels[i],
3166                                                idx, 0x0b);
3167                         if (err < 0)
3168                                 return err;
3169                         imux->items[imux->num_items].label =
3170                                 auto_pin_cfg_labels[i];
3171                         imux->items[imux->num_items].index =
3172                                 alc880_input_pin_idx(cfg->input_pins[i]);
3173                         imux->num_items++;
3174                 }
3175         }
3176         return 0;
3177 }
3178
3179 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3180                                               hda_nid_t nid, int pin_type,
3181                                               int dac_idx)
3182 {
3183         /* set as output */
3184         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3185                             pin_type);
3186         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3187                             AMP_OUT_UNMUTE);
3188         /* need the manual connection? */
3189         if (alc880_is_multi_pin(nid)) {
3190                 struct alc_spec *spec = codec->spec;
3191                 int idx = alc880_multi_pin_idx(nid);
3192                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3193                                     AC_VERB_SET_CONNECT_SEL,
3194                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3195         }
3196 }
3197
3198 static int get_pin_type(int line_out_type)
3199 {
3200         if (line_out_type == AUTO_PIN_HP_OUT)
3201                 return PIN_HP;
3202         else
3203                 return PIN_OUT;
3204 }
3205
3206 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3207 {
3208         struct alc_spec *spec = codec->spec;
3209         int i;
3210         
3211         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3212         for (i = 0; i < spec->autocfg.line_outs; i++) {
3213                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3214                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3215                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3216         }
3217 }
3218
3219 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3220 {
3221         struct alc_spec *spec = codec->spec;
3222         hda_nid_t pin;
3223
3224         pin = spec->autocfg.speaker_pins[0];
3225         if (pin) /* connect to front */
3226                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3227         pin = spec->autocfg.hp_pins[0];
3228         if (pin) /* connect to front */
3229                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3230 }
3231
3232 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3233 {
3234         struct alc_spec *spec = codec->spec;
3235         int i;
3236
3237         for (i = 0; i < AUTO_PIN_LAST; i++) {
3238                 hda_nid_t nid = spec->autocfg.input_pins[i];
3239                 if (alc880_is_input_pin(nid)) {
3240                         snd_hda_codec_write(codec, nid, 0,
3241                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3242                                             i <= AUTO_PIN_FRONT_MIC ?
3243                                             PIN_VREF80 : PIN_IN);
3244                         if (nid != ALC880_PIN_CD_NID)
3245                                 snd_hda_codec_write(codec, nid, 0,
3246                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3247                                                     AMP_OUT_MUTE);
3248                 }
3249         }
3250 }
3251
3252 /* parse the BIOS configuration and set up the alc_spec */
3253 /* return 1 if successful, 0 if the proper config is not found,
3254  * or a negative error code
3255  */
3256 static int alc880_parse_auto_config(struct hda_codec *codec)
3257 {
3258         struct alc_spec *spec = codec->spec;
3259         int err;
3260         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3261
3262         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3263                                            alc880_ignore);
3264         if (err < 0)
3265                 return err;
3266         if (!spec->autocfg.line_outs)
3267                 return 0; /* can't find valid BIOS pin config */
3268
3269         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3270         if (err < 0)
3271                 return err;
3272         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3273         if (err < 0)
3274                 return err;
3275         err = alc880_auto_create_extra_out(spec,
3276                                            spec->autocfg.speaker_pins[0],
3277                                            "Speaker");
3278         if (err < 0)
3279                 return err;
3280         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3281                                            "Headphone");
3282         if (err < 0)
3283                 return err;
3284         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3285         if (err < 0)
3286                 return err;
3287
3288         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3289
3290         if (spec->autocfg.dig_out_pin)
3291                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3292         if (spec->autocfg.dig_in_pin)
3293                 spec->dig_in_nid = ALC880_DIGIN_NID;
3294
3295         if (spec->kctl_alloc)
3296                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3297
3298         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3299
3300         spec->num_mux_defs = 1;
3301         spec->input_mux = &spec->private_imux;
3302
3303         return 1;
3304 }
3305
3306 /* additional initialization for auto-configuration model */
3307 static void alc880_auto_init(struct hda_codec *codec)
3308 {
3309         alc880_auto_init_multi_out(codec);
3310         alc880_auto_init_extra_out(codec);
3311         alc880_auto_init_analog_input(codec);
3312 }
3313
3314 /*
3315  * OK, here we have finally the patch for ALC880
3316  */
3317
3318 static int patch_alc880(struct hda_codec *codec)
3319 {
3320         struct alc_spec *spec;
3321         int board_config;
3322         int err;
3323
3324         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3325         if (spec == NULL)
3326                 return -ENOMEM;
3327
3328         codec->spec = spec;
3329
3330         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3331                                                   alc880_models,
3332                                                   alc880_cfg_tbl);
3333         if (board_config < 0) {
3334                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3335                        "trying auto-probe from BIOS...\n");
3336                 board_config = ALC880_AUTO;
3337         }
3338
3339         if (board_config == ALC880_AUTO) {
3340                 /* automatic parse from the BIOS config */
3341                 err = alc880_parse_auto_config(codec);
3342                 if (err < 0) {
3343                         alc_free(codec);
3344                         return err;
3345                 } else if (!err) {
3346                         printk(KERN_INFO
3347                                "hda_codec: Cannot set up configuration "
3348                                "from BIOS.  Using 3-stack mode...\n");
3349                         board_config = ALC880_3ST;
3350                 }
3351         }
3352
3353         if (board_config != ALC880_AUTO)
3354                 setup_preset(spec, &alc880_presets[board_config]);
3355
3356         spec->stream_name_analog = "ALC880 Analog";
3357         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3358         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3359
3360         spec->stream_name_digital = "ALC880 Digital";
3361         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3362         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3363
3364         if (!spec->adc_nids && spec->input_mux) {
3365                 /* check whether NID 0x07 is valid */
3366                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3367                 /* get type */
3368                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3369                 if (wcap != AC_WID_AUD_IN) {
3370                         spec->adc_nids = alc880_adc_nids_alt;
3371                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3372                         spec->mixers[spec->num_mixers] =
3373                                 alc880_capture_alt_mixer;
3374                         spec->num_mixers++;
3375                 } else {
3376                         spec->adc_nids = alc880_adc_nids;
3377                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3378                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3379                         spec->num_mixers++;
3380                 }
3381         }
3382
3383         codec->patch_ops = alc_patch_ops;
3384         if (board_config == ALC880_AUTO)
3385                 spec->init_hook = alc880_auto_init;
3386
3387         return 0;
3388 }
3389
3390
3391 /*
3392  * ALC260 support
3393  */
3394
3395 static hda_nid_t alc260_dac_nids[1] = {
3396         /* front */
3397         0x02,
3398 };
3399
3400 static hda_nid_t alc260_adc_nids[1] = {
3401         /* ADC0 */
3402         0x04,
3403 };
3404
3405 static hda_nid_t alc260_adc_nids_alt[1] = {
3406         /* ADC1 */
3407         0x05,
3408 };
3409
3410 static hda_nid_t alc260_hp_adc_nids[2] = {
3411         /* ADC1, 0 */
3412         0x05, 0x04
3413 };
3414
3415 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3416  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3417  */
3418 static hda_nid_t alc260_dual_adc_nids[2] = {
3419         /* ADC0, ADC1 */
3420         0x04, 0x05
3421 };
3422
3423 #define ALC260_DIGOUT_NID       0x03
3424 #define ALC260_DIGIN_NID        0x06
3425
3426 static struct hda_input_mux alc260_capture_source = {
3427         .num_items = 4,
3428         .items = {
3429                 { "Mic", 0x0 },
3430                 { "Front Mic", 0x1 },
3431                 { "Line", 0x2 },
3432                 { "CD", 0x4 },
3433         },
3434 };
3435
3436 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3437  * headphone jack and the internal CD lines since these are the only pins at
3438  * which audio can appear.  For flexibility, also allow the option of
3439  * recording the mixer output on the second ADC (ADC0 doesn't have a
3440  * connection to the mixer output).
3441  */
3442 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3443         {
3444                 .num_items = 3,
3445                 .items = {
3446                         { "Mic/Line", 0x0 },
3447                         { "CD", 0x4 },
3448                         { "Headphone", 0x2 },
3449                 },
3450         },
3451         {
3452                 .num_items = 4,
3453                 .items = {
3454                         { "Mic/Line", 0x0 },
3455                         { "CD", 0x4 },
3456                         { "Headphone", 0x2 },
3457                         { "Mixer", 0x5 },
3458                 },
3459         },
3460
3461 };
3462
3463 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3464  * the Fujitsu S702x, but jacks are marked differently.
3465  */
3466 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3467         {
3468                 .num_items = 4,
3469                 .items = {
3470                         { "Mic", 0x0 },
3471                         { "Line", 0x2 },
3472                         { "CD", 0x4 },
3473                         { "Headphone", 0x5 },
3474                 },
3475         },
3476         {
3477                 .num_items = 5,
3478                 .items = {
3479                         { "Mic", 0x0 },
3480                         { "Line", 0x2 },
3481                         { "CD", 0x4 },
3482                         { "Headphone", 0x6 },
3483                         { "Mixer", 0x5 },
3484                 },
3485         },
3486 };
3487 /*
3488  * This is just place-holder, so there's something for alc_build_pcms to look
3489  * at when it calculates the maximum number of channels. ALC260 has no mixer
3490  * element which allows changing the channel mode, so the verb list is
3491  * never used.
3492  */
3493 static struct hda_channel_mode alc260_modes[1] = {
3494         { 2, NULL },
3495 };
3496
3497
3498 /* Mixer combinations
3499  *
3500  * basic: base_output + input + pc_beep + capture
3501  * HP: base_output + input + capture_alt
3502  * HP_3013: hp_3013 + input + capture
3503  * fujitsu: fujitsu + capture
3504  * acer: acer + capture
3505  */
3506
3507 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3508         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3509         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3510         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3511         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3512         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3513         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3514         { } /* end */
3515 };
3516
3517 static struct snd_kcontrol_new alc260_input_mixer[] = {
3518         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3519         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3520         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3521         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3522         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3523         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3524         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3525         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3526         { } /* end */
3527 };
3528
3529 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3530         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3531         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3532         { } /* end */
3533 };
3534
3535 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3536         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3537         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3538         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3539         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3540         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3541         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3542         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3543         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3544         { } /* end */
3545 };
3546
3547 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3548  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3549  */
3550 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3551         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3552         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3553         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3554         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3555         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3556         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3557         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3558         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3559         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3560         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3561         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3562         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3563         { } /* end */
3564 };
3565
3566 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3567  * versions of the ALC260 don't act on requests to enable mic bias from NID
3568  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3569  * datasheet doesn't mention this restriction.  At this stage it's not clear
3570  * whether this behaviour is intentional or is a hardware bug in chip
3571  * revisions available in early 2006.  Therefore for now allow the
3572  * "Headphone Jack Mode" control to span all choices, but if it turns out
3573  * that the lack of mic bias for this NID is intentional we could change the
3574  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3575  *
3576  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3577  * don't appear to make the mic bias available from the "line" jack, even
3578  * though the NID used for this jack (0x14) can supply it.  The theory is
3579  * that perhaps Acer have included blocking capacitors between the ALC260
3580  * and the output jack.  If this turns out to be the case for all such
3581  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3582  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3583  *
3584  * The C20x Tablet series have a mono internal speaker which is controlled
3585  * via the chip's Mono sum widget and pin complex, so include the necessary
3586  * controls for such models.  On models without a "mono speaker" the control
3587  * won't do anything.
3588  */
3589 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3590         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3591         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3592         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3593         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3594                               HDA_OUTPUT),
3595         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3596                            HDA_INPUT),
3597         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3598         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3599         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3600         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3601         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3602         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3603         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3604         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3605         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3606         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3607         { } /* end */
3608 };
3609
3610 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3611  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3612  */
3613 static struct snd_kcontrol_new alc260_will_mixer[] = {
3614         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3615         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3616         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3617         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3618         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3619         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3620         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3621         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3622         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3623         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3624         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3625         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3626         { } /* end */
3627 };
3628
3629 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3630  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3631  */
3632 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3633         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3634         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3635         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3636         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3637         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3638         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3639         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3640         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3641         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3642         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3643         { } /* end */
3644 };
3645
3646 /* capture mixer elements */
3647 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3648         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3649         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3650         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3651         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3652         {
3653                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3654                 /* The multiple "Capture Source" controls confuse alsamixer
3655                  * So call somewhat different..
3656                  * FIXME: the controls appear in the "playback" view!
3657                  */
3658                 /* .name = "Capture Source", */
3659                 .name = "Input Source",
3660                 .count = 2,
3661                 .info = alc_mux_enum_info,
3662                 .get = alc_mux_enum_get,
3663                 .put = alc_mux_enum_put,
3664         },
3665         { } /* end */
3666 };
3667
3668 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3669         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3670         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3671         {
3672                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3673                 /* The multiple "Capture Source" controls confuse alsamixer
3674                  * So call somewhat different..
3675                  * FIXME: the controls appear in the "playback" view!
3676                  */
3677                 /* .name = "Capture Source", */
3678                 .name = "Input Source",
3679                 .count = 1,
3680                 .info = alc_mux_enum_info,
3681                 .get = alc_mux_enum_get,
3682                 .put = alc_mux_enum_put,
3683         },
3684         { } /* end */
3685 };
3686
3687 /*
3688  * initialization verbs
3689  */
3690 static struct hda_verb alc260_init_verbs[] = {
3691         /* Line In pin widget for input */
3692         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3693         /* CD pin widget for input */
3694         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3695         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3696         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3697         /* Mic2 (front panel) pin widget for input and vref at 80% */
3698         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3699         /* LINE-2 is used for line-out in rear */
3700         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3701         /* select line-out */
3702         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3703         /* LINE-OUT pin */
3704         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3705         /* enable HP */
3706         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3707         /* enable Mono */
3708         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3709         /* mute capture amp left and right */
3710         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3711         /* set connection select to line in (default select for this ADC) */
3712         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3713         /* mute capture amp left and right */
3714         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3715         /* set connection select to line in (default select for this ADC) */
3716         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3717         /* set vol=0 Line-Out mixer amp left and right */
3718         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3719         /* unmute pin widget amp left and right (no gain on this amp) */
3720         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3721         /* set vol=0 HP mixer amp left and right */
3722         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3723         /* unmute pin widget amp left and right (no gain on this amp) */
3724         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3725         /* set vol=0 Mono mixer amp left and right */
3726         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3727         /* unmute pin widget amp left and right (no gain on this amp) */
3728         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3729         /* unmute LINE-2 out pin */
3730         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3731         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3732          * Line In 2 = 0x03
3733          */
3734         /* mute CD */
3735         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3736         /* mute Line In */
3737         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3738         /* mute Mic */
3739         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3740         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3741         /* mute Front out path */
3742         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3743         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3744         /* mute Headphone out path */
3745         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3746         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3747         /* mute Mono out path */
3748         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3749         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3750         { }
3751 };
3752
3753 #if 0 /* should be identical with alc260_init_verbs? */
3754 static struct hda_verb alc260_hp_init_verbs[] = {
3755         /* Headphone and output */
3756         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3757         /* mono output */
3758         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3759         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3760         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3761         /* Mic2 (front panel) pin widget for input and vref at 80% */
3762         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3763         /* Line In pin widget for input */
3764         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3765         /* Line-2 pin widget for output */
3766         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3767         /* CD pin widget for input */
3768         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3769         /* unmute amp left and right */
3770         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3771         /* set connection select to line in (default select for this ADC) */
3772         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3773         /* unmute Line-Out mixer amp left and right (volume = 0) */
3774         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3775         /* mute pin widget amp left and right (no gain on this amp) */
3776         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3777         /* unmute HP mixer amp left and right (volume = 0) */
3778         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3779         /* mute pin widget amp left and right (no gain on this amp) */
3780         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3781         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3782          * Line In 2 = 0x03
3783          */
3784         /* unmute CD */
3785         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3786         /* unmute Line In */
3787         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3788         /* unmute Mic */
3789         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3790         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3791         /* Unmute Front out path */
3792         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3793         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3794         /* Unmute Headphone out path */
3795         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3796         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3797         /* Unmute Mono out path */
3798         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3799         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3800         { }
3801 };
3802 #endif
3803
3804 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3805         /* Line out and output */
3806         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3807         /* mono output */
3808         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3809         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3810         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3811         /* Mic2 (front panel) pin widget for input and vref at 80% */
3812         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3813         /* Line In pin widget for input */
3814         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3815         /* Headphone pin widget for output */
3816         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3817         /* CD pin widget for input */
3818         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3819         /* unmute amp left and right */
3820         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3821         /* set connection select to line in (default select for this ADC) */
3822         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3823         /* unmute Line-Out mixer amp left and right (volume = 0) */
3824         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3825         /* mute pin widget amp left and right (no gain on this amp) */
3826         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3827         /* unmute HP mixer amp left and right (volume = 0) */
3828         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3829         /* mute pin widget amp left and right (no gain on this amp) */
3830         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3831         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3832          * Line In 2 = 0x03
3833          */
3834         /* unmute CD */
3835         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3836         /* unmute Line In */
3837         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3838         /* unmute Mic */
3839         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3840         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3841         /* Unmute Front out path */
3842         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3843         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3844         /* Unmute Headphone out path */
3845         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3846         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3847         /* Unmute Mono out path */
3848         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3849         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3850         { }
3851 };
3852
3853 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3854  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3855  * audio = 0x16, internal speaker = 0x10.
3856  */
3857 static struct hda_verb alc260_fujitsu_init_verbs[] = {
3858         /* Disable all GPIOs */
3859         {0x01, AC_VERB_SET_GPIO_MASK, 0},
3860         /* Internal speaker is connected to headphone pin */
3861         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3862         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3863         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3864         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3865         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3866         /* Ensure all other unused pins are disabled and muted. */
3867         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3868         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3869         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3870         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3871         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3872         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3873         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3874         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3875
3876         /* Disable digital (SPDIF) pins */
3877         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3878         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3879
3880         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
3881          * when acting as an output.
3882          */
3883         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3884
3885         /* Start with output sum widgets muted and their output gains at min */
3886         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3887         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3888         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3889         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3890         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3891         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3892         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3893         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3894         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3895
3896         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3897         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3898         /* Unmute Line1 pin widget output buffer since it starts as an output.
3899          * If the pin mode is changed by the user the pin mode control will
3900          * take care of enabling the pin's input/output buffers as needed.
3901          * Therefore there's no need to enable the input buffer at this
3902          * stage.
3903          */
3904         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3905         /* Unmute input buffer of pin widget used for Line-in (no equiv 
3906          * mixer ctrl)
3907          */
3908         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3909
3910         /* Mute capture amp left and right */
3911         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3912         /* Set ADC connection select to match default mixer setting - line 
3913          * in (on mic1 pin)
3914          */
3915         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3916
3917         /* Do the same for the second ADC: mute capture input amp and
3918          * set ADC connection to line in (on mic1 pin)
3919          */
3920         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3921         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3922
3923         /* Mute all inputs to mixer widget (even unconnected ones) */
3924         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3925         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3926         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3927         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3928         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3929         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3930         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3931         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3932
3933         { }
3934 };
3935
3936 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3937  * similar laptops (adapted from Fujitsu init verbs).
3938  */
3939 static struct hda_verb alc260_acer_init_verbs[] = {
3940         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3941          * the headphone jack.  Turn this on and rely on the standard mute
3942          * methods whenever the user wants to turn these outputs off.
3943          */
3944         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3945         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3946         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3947         /* Internal speaker/Headphone jack is connected to Line-out pin */
3948         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3949         /* Internal microphone/Mic jack is connected to Mic1 pin */
3950         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3951         /* Line In jack is connected to Line1 pin */
3952         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3953         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3954         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3955         /* Ensure all other unused pins are disabled and muted. */
3956         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3957         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3958         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3959         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3960         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3961         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3962         /* Disable digital (SPDIF) pins */
3963         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3964         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3965
3966         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
3967          * bus when acting as outputs.
3968          */
3969         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3970         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3971
3972         /* Start with output sum widgets muted and their output gains at min */
3973         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3974         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3975         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3976         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3977         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3978         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3979         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3980         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3981         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3982
3983         /* Unmute Line-out pin widget amp left and right
3984          * (no equiv mixer ctrl)
3985          */
3986         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3987         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3988         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3989         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3990          * inputs. If the pin mode is changed by the user the pin mode control
3991          * will take care of enabling the pin's input/output buffers as needed.
3992          * Therefore there's no need to enable the input buffer at this
3993          * stage.
3994          */
3995         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3996         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3997
3998         /* Mute capture amp left and right */
3999         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4000         /* Set ADC connection select to match default mixer setting - mic
4001          * (on mic1 pin)
4002          */
4003         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4004
4005         /* Do similar with the second ADC: mute capture input amp and
4006          * set ADC connection to mic to match ALSA's default state.
4007          */
4008         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4009         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4010
4011         /* Mute all inputs to mixer widget (even unconnected ones) */
4012         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4013         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4014         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4015         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4016         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4017         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4018         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4019         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4020
4021         { }
4022 };
4023
4024 static struct hda_verb alc260_will_verbs[] = {
4025         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4026         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4027         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4028         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4029         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4030         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4031         {}
4032 };
4033
4034 static struct hda_verb alc260_replacer_672v_verbs[] = {
4035         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4036         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4037         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4038
4039         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4040         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4041         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4042
4043         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4044         {}
4045 };
4046
4047 /* toggle speaker-output according to the hp-jack state */
4048 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4049 {
4050         unsigned int present;
4051
4052         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4053         present = snd_hda_codec_read(codec, 0x0f, 0,
4054                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4055         if (present) {
4056                 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
4057                 snd_hda_codec_write(codec, 0x0f, 0,
4058                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4059         } else {
4060                 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4061                 snd_hda_codec_write(codec, 0x0f, 0,
4062                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4063         }
4064 }
4065
4066 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4067                                        unsigned int res)
4068 {
4069         if ((res >> 26) == ALC880_HP_EVENT)
4070                 alc260_replacer_672v_automute(codec);
4071 }
4072
4073 /* Test configuration for debugging, modelled after the ALC880 test
4074  * configuration.
4075  */
4076 #ifdef CONFIG_SND_DEBUG
4077 static hda_nid_t alc260_test_dac_nids[1] = {
4078         0x02,
4079 };
4080 static hda_nid_t alc260_test_adc_nids[2] = {
4081         0x04, 0x05,
4082 };
4083 /* For testing the ALC260, each input MUX needs its own definition since
4084  * the signal assignments are different.  This assumes that the first ADC 
4085  * is NID 0x04.
4086  */
4087 static struct hda_input_mux alc260_test_capture_sources[2] = {
4088         {
4089                 .num_items = 7,
4090                 .items = {
4091                         { "MIC1 pin", 0x0 },
4092                         { "MIC2 pin", 0x1 },
4093                         { "LINE1 pin", 0x2 },
4094                         { "LINE2 pin", 0x3 },
4095                         { "CD pin", 0x4 },
4096                         { "LINE-OUT pin", 0x5 },
4097                         { "HP-OUT pin", 0x6 },
4098                 },
4099         },
4100         {
4101                 .num_items = 8,
4102                 .items = {
4103                         { "MIC1 pin", 0x0 },
4104                         { "MIC2 pin", 0x1 },
4105                         { "LINE1 pin", 0x2 },
4106                         { "LINE2 pin", 0x3 },
4107                         { "CD pin", 0x4 },
4108                         { "Mixer", 0x5 },
4109                         { "LINE-OUT pin", 0x6 },
4110                         { "HP-OUT pin", 0x7 },
4111                 },
4112         },
4113 };
4114 static struct snd_kcontrol_new alc260_test_mixer[] = {
4115         /* Output driver widgets */
4116         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4117         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4118         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4119         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4120         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4121         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4122
4123         /* Modes for retasking pin widgets
4124          * Note: the ALC260 doesn't seem to act on requests to enable mic
4125          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4126          * mention this restriction.  At this stage it's not clear whether
4127          * this behaviour is intentional or is a hardware bug in chip
4128          * revisions available at least up until early 2006.  Therefore for
4129          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4130          * choices, but if it turns out that the lack of mic bias for these
4131          * NIDs is intentional we could change their modes from
4132          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4133          */
4134         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4135         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4136         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4137         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4138         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4139         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4140
4141         /* Loopback mixer controls */
4142         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4143         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4144         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4145         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4146         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4147         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4148         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4149         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4150         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4151         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4152         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4153         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4154         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4155         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4156         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4157         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4158
4159         /* Controls for GPIO pins, assuming they are configured as outputs */
4160         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4161         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4162         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4163         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4164
4165         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4166          * is ambigious as to which NID is which; testing on laptops which
4167          * make this output available should provide clarification. 
4168          */
4169         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4170         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4171
4172         { } /* end */
4173 };
4174 static struct hda_verb alc260_test_init_verbs[] = {
4175         /* Enable all GPIOs as outputs with an initial value of 0 */
4176         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4177         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4178         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4179
4180         /* Enable retasking pins as output, initially without power amp */
4181         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4182         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4183         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4184         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4185         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4186         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4187
4188         /* Disable digital (SPDIF) pins initially, but users can enable
4189          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4190          * payload also sets the generation to 0, output to be in "consumer"
4191          * PCM format, copyright asserted, no pre-emphasis and no validity
4192          * control.
4193          */
4194         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4195         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4196
4197         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4198          * OUT1 sum bus when acting as an output.
4199          */
4200         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4201         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4202         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4203         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4204
4205         /* Start with output sum widgets muted and their output gains at min */
4206         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4207         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4208         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4209         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4210         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4211         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4212         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4213         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4214         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4215
4216         /* Unmute retasking pin widget output buffers since the default
4217          * state appears to be output.  As the pin mode is changed by the
4218          * user the pin mode control will take care of enabling the pin's
4219          * input/output buffers as needed.
4220          */
4221         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4222         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4223         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4224         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4225         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4226         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4227         /* Also unmute the mono-out pin widget */
4228         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4229
4230         /* Mute capture amp left and right */
4231         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4232         /* Set ADC connection select to match default mixer setting (mic1
4233          * pin)
4234          */
4235         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4236
4237         /* Do the same for the second ADC: mute capture input amp and
4238          * set ADC connection to mic1 pin
4239          */
4240         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4241         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4242
4243         /* Mute all inputs to mixer widget (even unconnected ones) */
4244         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4245         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4246         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4247         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4248         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4249         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4250         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4251         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4252
4253         { }
4254 };
4255 #endif
4256
4257 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4258         .substreams = 1,
4259         .channels_min = 2,
4260         .channels_max = 2,
4261 };
4262
4263 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4264         .substreams = 1,
4265         .channels_min = 2,
4266         .channels_max = 2,
4267 };
4268
4269 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4270 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4271
4272 /*
4273  * for BIOS auto-configuration
4274  */
4275
4276 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4277                                         const char *pfx)
4278 {
4279         hda_nid_t nid_vol;
4280         unsigned long vol_val, sw_val;
4281         char name[32];
4282         int err;
4283
4284         if (nid >= 0x0f && nid < 0x11) {
4285                 nid_vol = nid - 0x7;
4286                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4287                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4288         } else if (nid == 0x11) {
4289                 nid_vol = nid - 0x7;
4290                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4291                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4292         } else if (nid >= 0x12 && nid <= 0x15) {
4293                 nid_vol = 0x08;
4294                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4295                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4296         } else
4297                 return 0; /* N/A */
4298         
4299         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4300         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4301         if (err < 0)
4302                 return err;
4303         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4304         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4305         if (err < 0)
4306                 return err;
4307         return 1;
4308 }
4309
4310 /* add playback controls from the parsed DAC table */
4311 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4312                                              const struct auto_pin_cfg *cfg)
4313 {
4314         hda_nid_t nid;
4315         int err;
4316
4317         spec->multiout.num_dacs = 1;
4318         spec->multiout.dac_nids = spec->private_dac_nids;
4319         spec->multiout.dac_nids[0] = 0x02;
4320
4321         nid = cfg->line_out_pins[0];
4322         if (nid) {
4323                 err = alc260_add_playback_controls(spec, nid, "Front");
4324                 if (err < 0)
4325                         return err;
4326         }
4327
4328         nid = cfg->speaker_pins[0];
4329         if (nid) {
4330                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4331                 if (err < 0)
4332                         return err;
4333         }
4334
4335         nid = cfg->hp_pins[0];
4336         if (nid) {
4337                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4338                 if (err < 0)
4339                         return err;
4340         }
4341         return 0;
4342 }
4343
4344 /* create playback/capture controls for input pins */
4345 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4346                                                 const struct auto_pin_cfg *cfg)
4347 {
4348         struct hda_input_mux *imux = &spec->private_imux;
4349         int i, err, idx;
4350
4351         for (i = 0; i < AUTO_PIN_LAST; i++) {
4352                 if (cfg->input_pins[i] >= 0x12) {
4353                         idx = cfg->input_pins[i] - 0x12;
4354                         err = new_analog_input(spec, cfg->input_pins[i],
4355                                                auto_pin_cfg_labels[i], idx,
4356                                                0x07);
4357                         if (err < 0)
4358                                 return err;
4359                         imux->items[imux->num_items].label =
4360                                 auto_pin_cfg_labels[i];
4361                         imux->items[imux->num_items].index = idx;
4362                         imux->num_items++;
4363                 }
4364                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4365                         idx = cfg->input_pins[i] - 0x09;
4366                         err = new_analog_input(spec, cfg->input_pins[i],
4367                                                auto_pin_cfg_labels[i], idx,
4368                                                0x07);
4369                         if (err < 0)
4370                                 return err;
4371                         imux->items[imux->num_items].label =
4372                                 auto_pin_cfg_labels[i];
4373                         imux->items[imux->num_items].index = idx;
4374                         imux->num_items++;
4375                 }
4376         }
4377         return 0;
4378 }
4379
4380 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4381                                               hda_nid_t nid, int pin_type,
4382                                               int sel_idx)
4383 {
4384         /* set as output */
4385         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4386                             pin_type);
4387         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4388                             AMP_OUT_UNMUTE);
4389         /* need the manual connection? */
4390         if (nid >= 0x12) {
4391                 int idx = nid - 0x12;
4392                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4393                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4394         }
4395 }
4396
4397 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4398 {
4399         struct alc_spec *spec = codec->spec;
4400         hda_nid_t nid;
4401
4402         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4403         nid = spec->autocfg.line_out_pins[0];
4404         if (nid) {
4405                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4406                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4407         }
4408         
4409         nid = spec->autocfg.speaker_pins[0];
4410         if (nid)
4411                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4412
4413         nid = spec->autocfg.hp_pins[0];
4414         if (nid)
4415                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4416 }
4417
4418 #define ALC260_PIN_CD_NID               0x16
4419 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4420 {
4421         struct alc_spec *spec = codec->spec;
4422         int i;
4423
4424         for (i = 0; i < AUTO_PIN_LAST; i++) {
4425                 hda_nid_t nid = spec->autocfg.input_pins[i];
4426                 if (nid >= 0x12) {
4427                         snd_hda_codec_write(codec, nid, 0,
4428                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4429                                             i <= AUTO_PIN_FRONT_MIC ?
4430                                             PIN_VREF80 : PIN_IN);
4431                         if (nid != ALC260_PIN_CD_NID)
4432                                 snd_hda_codec_write(codec, nid, 0,
4433                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4434                                                     AMP_OUT_MUTE);
4435                 }
4436         }
4437 }
4438
4439 /*
4440  * generic initialization of ADC, input mixers and output mixers
4441  */
4442 static struct hda_verb alc260_volume_init_verbs[] = {
4443         /*
4444          * Unmute ADC0-1 and set the default input to mic-in
4445          */
4446         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4447         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4448         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4449         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4450         
4451         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4452          * mixer widget
4453          * Note: PASD motherboards uses the Line In 2 as the input for
4454          * front panel mic (mic 2)
4455          */
4456         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4457         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4458         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4459         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4460         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4461         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4462
4463         /*
4464          * Set up output mixers (0x08 - 0x0a)
4465          */
4466         /* set vol=0 to output mixers */
4467         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4468         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4469         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4470         /* set up input amps for analog loopback */
4471         /* Amp Indices: DAC = 0, mixer = 1 */
4472         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4473         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4474         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4475         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4476         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4477         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4478         
4479         { }
4480 };
4481
4482 static int alc260_parse_auto_config(struct hda_codec *codec)
4483 {
4484         struct alc_spec *spec = codec->spec;
4485         unsigned int wcap;
4486         int err;
4487         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4488
4489         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4490                                            alc260_ignore);
4491         if (err < 0)
4492                 return err;
4493         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4494         if (err < 0)
4495                 return err;
4496         if (!spec->kctl_alloc)
4497                 return 0; /* can't find valid BIOS pin config */
4498         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4499         if (err < 0)
4500                 return err;
4501
4502         spec->multiout.max_channels = 2;
4503
4504         if (spec->autocfg.dig_out_pin)
4505                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4506         if (spec->kctl_alloc)
4507                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4508
4509         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4510
4511         spec->num_mux_defs = 1;
4512         spec->input_mux = &spec->private_imux;
4513
4514         /* check whether NID 0x04 is valid */
4515         wcap = get_wcaps(codec, 0x04);
4516         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4517         if (wcap != AC_WID_AUD_IN) {
4518                 spec->adc_nids = alc260_adc_nids_alt;
4519                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4520                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4521         } else {
4522                 spec->adc_nids = alc260_adc_nids;
4523                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4524                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4525         }
4526         spec->num_mixers++;
4527
4528         return 1;
4529 }
4530
4531 /* additional initialization for auto-configuration model */
4532 static void alc260_auto_init(struct hda_codec *codec)
4533 {
4534         alc260_auto_init_multi_out(codec);
4535         alc260_auto_init_analog_input(codec);
4536 }
4537
4538 /*
4539  * ALC260 configurations
4540  */
4541 static const char *alc260_models[ALC260_MODEL_LAST] = {
4542         [ALC260_BASIC]          = "basic",
4543         [ALC260_HP]             = "hp",
4544         [ALC260_HP_3013]        = "hp-3013",
4545         [ALC260_FUJITSU_S702X]  = "fujitsu",
4546         [ALC260_ACER]           = "acer",
4547         [ALC260_WILL]           = "will",
4548         [ALC260_REPLACER_672V]  = "replacer",
4549 #ifdef CONFIG_SND_DEBUG
4550         [ALC260_TEST]           = "test",
4551 #endif
4552         [ALC260_AUTO]           = "auto",
4553 };
4554
4555 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4556         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4557         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4558         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4559         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4560         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4561         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4562         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4563         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4564         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4565         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4566         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4567         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4568         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4569         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4570         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4571         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4572         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4573         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4574         {}
4575 };
4576
4577 static struct alc_config_preset alc260_presets[] = {
4578         [ALC260_BASIC] = {
4579                 .mixers = { alc260_base_output_mixer,
4580                             alc260_input_mixer,
4581                             alc260_pc_beep_mixer,
4582                             alc260_capture_mixer },
4583                 .init_verbs = { alc260_init_verbs },
4584                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4585                 .dac_nids = alc260_dac_nids,
4586                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4587                 .adc_nids = alc260_adc_nids,
4588                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4589                 .channel_mode = alc260_modes,
4590                 .input_mux = &alc260_capture_source,
4591         },
4592         [ALC260_HP] = {
4593                 .mixers = { alc260_base_output_mixer,
4594                             alc260_input_mixer,
4595                             alc260_capture_alt_mixer },
4596                 .init_verbs = { alc260_init_verbs },
4597                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4598                 .dac_nids = alc260_dac_nids,
4599                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4600                 .adc_nids = alc260_hp_adc_nids,
4601                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4602                 .channel_mode = alc260_modes,
4603                 .input_mux = &alc260_capture_source,
4604         },
4605         [ALC260_HP_3013] = {
4606                 .mixers = { alc260_hp_3013_mixer,
4607                             alc260_input_mixer,
4608                             alc260_capture_alt_mixer },
4609                 .init_verbs = { alc260_hp_3013_init_verbs },
4610                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4611                 .dac_nids = alc260_dac_nids,
4612                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4613                 .adc_nids = alc260_hp_adc_nids,
4614                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4615                 .channel_mode = alc260_modes,
4616                 .input_mux = &alc260_capture_source,
4617         },
4618         [ALC260_FUJITSU_S702X] = {
4619                 .mixers = { alc260_fujitsu_mixer,
4620                             alc260_capture_mixer },
4621                 .init_verbs = { alc260_fujitsu_init_verbs },
4622                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4623                 .dac_nids = alc260_dac_nids,
4624                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4625                 .adc_nids = alc260_dual_adc_nids,
4626                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4627                 .channel_mode = alc260_modes,
4628                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4629                 .input_mux = alc260_fujitsu_capture_sources,
4630         },
4631         [ALC260_ACER] = {
4632                 .mixers = { alc260_acer_mixer,
4633                             alc260_capture_mixer },
4634                 .init_verbs = { alc260_acer_init_verbs },
4635                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4636                 .dac_nids = alc260_dac_nids,
4637                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4638                 .adc_nids = alc260_dual_adc_nids,
4639                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4640                 .channel_mode = alc260_modes,
4641                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4642                 .input_mux = alc260_acer_capture_sources,
4643         },
4644         [ALC260_WILL] = {
4645                 .mixers = { alc260_will_mixer,
4646                             alc260_capture_mixer },
4647                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4648                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4649                 .dac_nids = alc260_dac_nids,
4650                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4651                 .adc_nids = alc260_adc_nids,
4652                 .dig_out_nid = ALC260_DIGOUT_NID,
4653                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4654                 .channel_mode = alc260_modes,
4655                 .input_mux = &alc260_capture_source,
4656         },
4657         [ALC260_REPLACER_672V] = {
4658                 .mixers = { alc260_replacer_672v_mixer,
4659                             alc260_capture_mixer },
4660                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4661                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4662                 .dac_nids = alc260_dac_nids,
4663                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4664                 .adc_nids = alc260_adc_nids,
4665                 .dig_out_nid = ALC260_DIGOUT_NID,
4666                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4667                 .channel_mode = alc260_modes,
4668                 .input_mux = &alc260_capture_source,
4669                 .unsol_event = alc260_replacer_672v_unsol_event,
4670                 .init_hook = alc260_replacer_672v_automute,
4671         },
4672 #ifdef CONFIG_SND_DEBUG
4673         [ALC260_TEST] = {
4674                 .mixers = { alc260_test_mixer,
4675                             alc260_capture_mixer },
4676                 .init_verbs = { alc260_test_init_verbs },
4677                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4678                 .dac_nids = alc260_test_dac_nids,
4679                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4680                 .adc_nids = alc260_test_adc_nids,
4681                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4682                 .channel_mode = alc260_modes,
4683                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4684                 .input_mux = alc260_test_capture_sources,
4685         },
4686 #endif
4687 };
4688
4689 static int patch_alc260(struct hda_codec *codec)
4690 {
4691         struct alc_spec *spec;
4692         int err, board_config;
4693
4694         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4695         if (spec == NULL)
4696                 return -ENOMEM;
4697
4698         codec->spec = spec;
4699
4700         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4701                                                   alc260_models,
4702                                                   alc260_cfg_tbl);
4703         if (board_config < 0) {
4704                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4705                            "trying auto-probe from BIOS...\n");
4706                 board_config = ALC260_AUTO;
4707         }
4708
4709         if (board_config == ALC260_AUTO) {
4710                 /* automatic parse from the BIOS config */
4711                 err = alc260_parse_auto_config(codec);
4712                 if (err < 0) {
4713                         alc_free(codec);
4714                         return err;
4715                 } else if (!err) {
4716                         printk(KERN_INFO
4717                                "hda_codec: Cannot set up configuration "
4718                                "from BIOS.  Using base mode...\n");
4719                         board_config = ALC260_BASIC;
4720                 }
4721         }
4722
4723         if (board_config != ALC260_AUTO)
4724                 setup_preset(spec, &alc260_presets[board_config]);
4725
4726         spec->stream_name_analog = "ALC260 Analog";
4727         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4728         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4729
4730         spec->stream_name_digital = "ALC260 Digital";
4731         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4732         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4733
4734         codec->patch_ops = alc_patch_ops;
4735         if (board_config == ALC260_AUTO)
4736                 spec->init_hook = alc260_auto_init;
4737
4738         return 0;
4739 }
4740
4741
4742 /*
4743  * ALC882 support
4744  *
4745  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4746  * configuration.  Each pin widget can choose any input DACs and a mixer.
4747  * Each ADC is connected from a mixer of all inputs.  This makes possible
4748  * 6-channel independent captures.
4749  *
4750  * In addition, an independent DAC for the multi-playback (not used in this
4751  * driver yet).
4752  */
4753 #define ALC882_DIGOUT_NID       0x06
4754 #define ALC882_DIGIN_NID        0x0a
4755
4756 static struct hda_channel_mode alc882_ch_modes[1] = {
4757         { 8, NULL }
4758 };
4759
4760 static hda_nid_t alc882_dac_nids[4] = {
4761         /* front, rear, clfe, rear_surr */
4762         0x02, 0x03, 0x04, 0x05
4763 };
4764
4765 /* identical with ALC880 */
4766 #define alc882_adc_nids         alc880_adc_nids
4767 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4768
4769 /* input MUX */
4770 /* FIXME: should be a matrix-type input source selection */
4771
4772 static struct hda_input_mux alc882_capture_source = {
4773         .num_items = 4,
4774         .items = {
4775                 { "Mic", 0x0 },
4776                 { "Front Mic", 0x1 },
4777                 { "Line", 0x2 },
4778                 { "CD", 0x4 },
4779         },
4780 };
4781 #define alc882_mux_enum_info alc_mux_enum_info
4782 #define alc882_mux_enum_get alc_mux_enum_get
4783
4784 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4785                                struct snd_ctl_elem_value *ucontrol)
4786 {
4787         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4788         struct alc_spec *spec = codec->spec;
4789         const struct hda_input_mux *imux = spec->input_mux;
4790         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4791         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4792         hda_nid_t nid = capture_mixers[adc_idx];
4793         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4794         unsigned int i, idx;
4795
4796         idx = ucontrol->value.enumerated.item[0];
4797         if (idx >= imux->num_items)
4798                 idx = imux->num_items - 1;
4799         if (*cur_val == idx && !codec->in_resume)
4800                 return 0;
4801         for (i = 0; i < imux->num_items; i++) {
4802                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4803                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4804                                     v | (imux->items[i].index << 8));
4805         }
4806         *cur_val = idx;
4807         return 1;
4808 }
4809
4810 /*
4811  * 2ch mode
4812  */
4813 static struct hda_verb alc882_3ST_ch2_init[] = {
4814         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4815         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4816         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4817         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4818         { } /* end */
4819 };
4820
4821 /*
4822  * 6ch mode
4823  */
4824 static struct hda_verb alc882_3ST_ch6_init[] = {
4825         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4826         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4827         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4828         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4829         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4830         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4831         { } /* end */
4832 };
4833
4834 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4835         { 2, alc882_3ST_ch2_init },
4836         { 6, alc882_3ST_ch6_init },
4837 };
4838
4839 /*
4840  * 6ch mode
4841  */
4842 static struct hda_verb alc882_sixstack_ch6_init[] = {
4843         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4844         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4845         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4846         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4847         { } /* end */
4848 };
4849
4850 /*
4851  * 8ch mode
4852  */
4853 static struct hda_verb alc882_sixstack_ch8_init[] = {
4854         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4855         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4856         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4857         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4858         { } /* end */
4859 };
4860
4861 static struct hda_channel_mode alc882_sixstack_modes[2] = {
4862         { 6, alc882_sixstack_ch6_init },
4863         { 8, alc882_sixstack_ch8_init },
4864 };
4865
4866 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4867  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4868  */
4869 static struct snd_kcontrol_new alc882_base_mixer[] = {
4870         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4871         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4872         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4873         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4874         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4875         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4876         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4877         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4878         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4879         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4880         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4881         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4882         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4883         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4884         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4885         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4886         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4887         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4888         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4889         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4890         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4891         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4892         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4893         { } /* end */
4894 };
4895
4896 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4897         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4898         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4899         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4900         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4901         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4902         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4903         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4904         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4905         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4906         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4907         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4908         { } /* end */
4909 };
4910
4911 static struct snd_kcontrol_new alc882_targa_mixer[] = {
4912         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4913         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4914         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4915         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4916         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4917         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4918         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4919         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4920         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4921         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4922         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4923         { } /* end */
4924 };
4925
4926 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4927  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4928  */
4929 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4930         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4931         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4932         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4933         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4934         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4935         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4936         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4937         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4938         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4939         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4940         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4941         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4942         { } /* end */
4943 };
4944
4945 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4946         {
4947                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4948                 .name = "Channel Mode",
4949                 .info = alc_ch_mode_info,
4950                 .get = alc_ch_mode_get,
4951                 .put = alc_ch_mode_put,
4952         },
4953         { } /* end */
4954 };
4955
4956 static struct hda_verb alc882_init_verbs[] = {
4957         /* Front mixer: unmute input/output amp left and right (volume = 0) */
4958         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4959         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4960         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4961         /* Rear mixer */
4962         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4963         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4964         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4965         /* CLFE mixer */
4966         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4967         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4968         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4969         /* Side mixer */
4970         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4971         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4972         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4973
4974         /* Front Pin: output 0 (0x0c) */
4975         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4976         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4977         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4978         /* Rear Pin: output 1 (0x0d) */
4979         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4980         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4981         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4982         /* CLFE Pin: output 2 (0x0e) */
4983         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4984         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4985         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4986         /* Side Pin: output 3 (0x0f) */
4987         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4988         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4989         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4990         /* Mic (rear) pin: input vref at 80% */
4991         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4992         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4993         /* Front Mic pin: input vref at 80% */
4994         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4995         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4996         /* Line In pin: input */
4997         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4998         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4999         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5000         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5001         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5002         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5003         /* CD pin widget for input */
5004         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5005
5006         /* FIXME: use matrix-type input source selection */
5007         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5008         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5009         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5010         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5011         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5012         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5013         /* Input mixer2 */
5014         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5015         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5016         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5017         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5018         /* Input mixer3 */
5019         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5020         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5021         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5022         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5023         /* ADC1: mute amp left and right */
5024         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5025         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5026         /* ADC2: mute amp left and right */
5027         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5028         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5029         /* ADC3: mute amp left and right */
5030         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5031         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5032
5033         { }
5034 };
5035
5036 static struct hda_verb alc882_eapd_verbs[] = {
5037         /* change to EAPD mode */
5038         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5039         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5040         { }
5041 };
5042
5043 /* Mac Pro test */
5044 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5045         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5046         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5047         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5048         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5049         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5050         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5051         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5052         { } /* end */
5053 };
5054
5055 static struct hda_verb alc882_macpro_init_verbs[] = {
5056         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5057         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5058         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5059         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5060         /* Front Pin: output 0 (0x0c) */
5061         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5062         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5063         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5064         /* Front Mic pin: input vref at 80% */
5065         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5066         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5067         /* Speaker:  output */
5068         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5069         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5070         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5071         /* Headphone output (output 0 - 0x0c) */
5072         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5073         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5074         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5075
5076         /* FIXME: use matrix-type input source selection */
5077         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5078         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5079         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5080         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5081         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5082         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5083         /* Input mixer2 */
5084         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5085         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5086         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5087         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5088         /* Input mixer3 */
5089         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5090         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5091         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5092         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5093         /* ADC1: mute amp left and right */
5094         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5095         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5096         /* ADC2: mute amp left and right */
5097         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5098         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5099         /* ADC3: mute amp left and right */
5100         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5101         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5102
5103         { }
5104 };
5105
5106 /* iMac 24 mixer. */
5107 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5108         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5109         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5110         { } /* end */
5111 };
5112
5113 /* iMac 24 init verbs. */
5114 static struct hda_verb alc885_imac24_init_verbs[] = {
5115         /* Internal speakers: output 0 (0x0c) */
5116         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5117         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5118         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5119         /* Internal speakers: output 0 (0x0c) */
5120         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5121         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5122         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5123         /* Headphone: output 0 (0x0c) */
5124         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5125         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5126         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5127         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5128         /* Front Mic: input vref at 80% */
5129         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5130         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5131         { }
5132 };
5133
5134 /* Toggle speaker-output according to the hp-jack state */
5135 static void alc885_imac24_automute(struct hda_codec *codec)
5136 {
5137         unsigned int present;
5138
5139         present = snd_hda_codec_read(codec, 0x14, 0,
5140                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5141         snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0,
5142                                  0x80, present ? 0x80 : 0);
5143         snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0,
5144                                  0x80, present ? 0x80 : 0);
5145         snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
5146                                  0x80, present ? 0x80 : 0);
5147         snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
5148                                  0x80, present ? 0x80 : 0);
5149 }
5150
5151 /* Processes unsolicited events. */
5152 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5153                                       unsigned int res)
5154 {
5155         /* Headphone insertion or removal. */
5156         if ((res >> 26) == ALC880_HP_EVENT)
5157                 alc885_imac24_automute(codec);
5158 }
5159
5160 static struct hda_verb alc882_targa_verbs[] = {
5161         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5162         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5163
5164         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5165         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5166         
5167         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5168         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5169         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5170
5171         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5172         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5173         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5174         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5175         { } /* end */
5176 };
5177
5178 /* toggle speaker-output according to the hp-jack state */
5179 static void alc882_targa_automute(struct hda_codec *codec)
5180 {
5181         unsigned int present;
5182  
5183         present = snd_hda_codec_read(codec, 0x14, 0,
5184                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5185         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5186                                  0x80, present ? 0x80 : 0);
5187         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5188                                  0x80, present ? 0x80 : 0);
5189         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5190 }
5191
5192 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5193 {
5194         /* Looks like the unsol event is incompatible with the standard
5195          * definition.  4bit tag is placed at 26 bit!
5196          */
5197         if (((res >> 26) == ALC880_HP_EVENT)) {
5198                 alc882_targa_automute(codec);
5199         }
5200 }
5201
5202 static struct hda_verb alc882_asus_a7j_verbs[] = {
5203         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5204         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5205
5206         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5207         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5208         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5209         
5210         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5211         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5212         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5213
5214         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5215         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5216         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5217         { } /* end */
5218 };
5219
5220 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5221 {
5222         unsigned int gpiostate, gpiomask, gpiodir;
5223
5224         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5225                                        AC_VERB_GET_GPIO_DATA, 0);
5226
5227         if (!muted)
5228                 gpiostate |= (1 << pin);
5229         else
5230                 gpiostate &= ~(1 << pin);
5231
5232         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5233                                       AC_VERB_GET_GPIO_MASK, 0);
5234         gpiomask |= (1 << pin);
5235
5236         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5237                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5238         gpiodir |= (1 << pin);
5239
5240
5241         snd_hda_codec_write(codec, codec->afg, 0,
5242                             AC_VERB_SET_GPIO_MASK, gpiomask);
5243         snd_hda_codec_write(codec, codec->afg, 0,
5244                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5245
5246         msleep(1);
5247
5248         snd_hda_codec_write(codec, codec->afg, 0,
5249                             AC_VERB_SET_GPIO_DATA, gpiostate);
5250 }
5251
5252 /*
5253  * generic initialization of ADC, input mixers and output mixers
5254  */
5255 static struct hda_verb alc882_auto_init_verbs[] = {
5256         /*
5257          * Unmute ADC0-2 and set the default input to mic-in
5258          */
5259         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5260         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5261         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5262         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5263         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5264         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5265
5266         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5267          * mixer widget
5268          * Note: PASD motherboards uses the Line In 2 as the input for
5269          * front panel mic (mic 2)
5270          */
5271         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5272         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5273         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5274         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5275         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5276         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5277
5278         /*
5279          * Set up output mixers (0x0c - 0x0f)
5280          */
5281         /* set vol=0 to output mixers */
5282         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5283         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5284         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5285         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5286         /* set up input amps for analog loopback */
5287         /* Amp Indices: DAC = 0, mixer = 1 */
5288         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5289         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5290         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5291         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5292         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5293         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5294         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5295         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5296         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5297         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5298
5299         /* FIXME: use matrix-type input source selection */
5300         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5301         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5302         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5303         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5304         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5305         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5306         /* Input mixer2 */
5307         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5308         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5309         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5310         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5311         /* Input mixer3 */
5312         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5313         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5314         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5315         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5316
5317         { }
5318 };
5319
5320 /* capture mixer elements */
5321 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5322         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5323         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5324         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5325         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5326         {
5327                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5328                 /* The multiple "Capture Source" controls confuse alsamixer
5329                  * So call somewhat different..
5330                  * FIXME: the controls appear in the "playback" view!
5331                  */
5332                 /* .name = "Capture Source", */
5333                 .name = "Input Source",
5334                 .count = 2,
5335                 .info = alc882_mux_enum_info,
5336                 .get = alc882_mux_enum_get,
5337                 .put = alc882_mux_enum_put,
5338         },
5339         { } /* end */
5340 };
5341
5342 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5343         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5344         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5345         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5346         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5347         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5348         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5349         {
5350                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5351                 /* The multiple "Capture Source" controls confuse alsamixer
5352                  * So call somewhat different..
5353                  * FIXME: the controls appear in the "playback" view!
5354                  */
5355                 /* .name = "Capture Source", */
5356                 .name = "Input Source",
5357                 .count = 3,
5358                 .info = alc882_mux_enum_info,
5359                 .get = alc882_mux_enum_get,
5360                 .put = alc882_mux_enum_put,
5361         },
5362         { } /* end */
5363 };
5364
5365 /* pcm configuration: identiacal with ALC880 */
5366 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5367 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5368 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5369 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5370
5371 /*
5372  * configuration and preset
5373  */
5374 static const char *alc882_models[ALC882_MODEL_LAST] = {
5375         [ALC882_3ST_DIG]        = "3stack-dig",
5376         [ALC882_6ST_DIG]        = "6stack-dig",
5377         [ALC882_ARIMA]          = "arima",
5378         [ALC882_W2JC]           = "w2jc",
5379         [ALC885_MACPRO]         = "macpro",
5380         [ALC885_IMAC24]         = "imac24",
5381         [ALC882_AUTO]           = "auto",
5382 };
5383
5384 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5385         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5386         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5387         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5388         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5389         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5390         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5391         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5392         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5393         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5394         {}
5395 };
5396
5397 static struct alc_config_preset alc882_presets[] = {
5398         [ALC882_3ST_DIG] = {
5399                 .mixers = { alc882_base_mixer },
5400                 .init_verbs = { alc882_init_verbs },
5401                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5402                 .dac_nids = alc882_dac_nids,
5403                 .dig_out_nid = ALC882_DIGOUT_NID,
5404                 .dig_in_nid = ALC882_DIGIN_NID,
5405                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5406                 .channel_mode = alc882_ch_modes,
5407                 .need_dac_fix = 1,
5408                 .input_mux = &alc882_capture_source,
5409         },
5410         [ALC882_6ST_DIG] = {
5411                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5412                 .init_verbs = { alc882_init_verbs },
5413                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5414                 .dac_nids = alc882_dac_nids,
5415                 .dig_out_nid = ALC882_DIGOUT_NID,
5416                 .dig_in_nid = ALC882_DIGIN_NID,
5417                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5418                 .channel_mode = alc882_sixstack_modes,
5419                 .input_mux = &alc882_capture_source,
5420         },
5421         [ALC882_ARIMA] = {
5422                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5423                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5424                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5425                 .dac_nids = alc882_dac_nids,
5426                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5427                 .channel_mode = alc882_sixstack_modes,
5428                 .input_mux = &alc882_capture_source,
5429         },
5430         [ALC882_W2JC] = {
5431                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5432                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5433                                 alc880_gpio1_init_verbs },
5434                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5435                 .dac_nids = alc882_dac_nids,
5436                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5437                 .channel_mode = alc880_threestack_modes,
5438                 .need_dac_fix = 1,
5439                 .input_mux = &alc882_capture_source,
5440                 .dig_out_nid = ALC882_DIGOUT_NID,
5441         },
5442         [ALC885_MACPRO] = {
5443                 .mixers = { alc882_macpro_mixer },
5444                 .init_verbs = { alc882_macpro_init_verbs },
5445                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5446                 .dac_nids = alc882_dac_nids,
5447                 .dig_out_nid = ALC882_DIGOUT_NID,
5448                 .dig_in_nid = ALC882_DIGIN_NID,
5449                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5450                 .channel_mode = alc882_ch_modes,
5451                 .input_mux = &alc882_capture_source,
5452         },
5453         [ALC885_IMAC24] = {
5454                 .mixers = { alc885_imac24_mixer },
5455                 .init_verbs = { alc885_imac24_init_verbs },
5456                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5457                 .dac_nids = alc882_dac_nids,
5458                 .dig_out_nid = ALC882_DIGOUT_NID,
5459                 .dig_in_nid = ALC882_DIGIN_NID,
5460                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5461                 .channel_mode = alc882_ch_modes,
5462                 .input_mux = &alc882_capture_source,
5463                 .unsol_event = alc885_imac24_unsol_event,
5464                 .init_hook = alc885_imac24_automute,
5465         },
5466         [ALC882_TARGA] = {
5467                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5468                             alc882_capture_mixer },
5469                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5470                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5471                 .dac_nids = alc882_dac_nids,
5472                 .dig_out_nid = ALC882_DIGOUT_NID,
5473                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5474                 .adc_nids = alc882_adc_nids,
5475                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5476                 .channel_mode = alc882_3ST_6ch_modes,
5477                 .need_dac_fix = 1,
5478                 .input_mux = &alc882_capture_source,
5479                 .unsol_event = alc882_targa_unsol_event,
5480                 .init_hook = alc882_targa_automute,
5481         },
5482         [ALC882_ASUS_A7J] = {
5483                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5484                             alc882_capture_mixer },
5485                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5486                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5487                 .dac_nids = alc882_dac_nids,
5488                 .dig_out_nid = ALC882_DIGOUT_NID,
5489                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5490                 .adc_nids = alc882_adc_nids,
5491                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5492                 .channel_mode = alc882_3ST_6ch_modes,
5493                 .need_dac_fix = 1,
5494                 .input_mux = &alc882_capture_source,
5495         },      
5496 };
5497
5498
5499 /*
5500  * Pin config fixes
5501  */
5502 enum { 
5503         PINFIX_ABIT_AW9D_MAX
5504 };
5505
5506 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5507         { 0x15, 0x01080104 }, /* side */
5508         { 0x16, 0x01011012 }, /* rear */
5509         { 0x17, 0x01016011 }, /* clfe */
5510         { }
5511 };
5512
5513 static const struct alc_pincfg *alc882_pin_fixes[] = {
5514         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5515 };
5516
5517 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5518         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5519         {}
5520 };
5521
5522 /*
5523  * BIOS auto configuration
5524  */
5525 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5526                                               hda_nid_t nid, int pin_type,
5527                                               int dac_idx)
5528 {
5529         /* set as output */
5530         struct alc_spec *spec = codec->spec;
5531         int idx;
5532
5533         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5534                 idx = 4;
5535         else
5536                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5537
5538         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5539                             pin_type);
5540         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5541                             AMP_OUT_UNMUTE);
5542         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5543
5544 }
5545
5546 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5547 {
5548         struct alc_spec *spec = codec->spec;
5549         int i;
5550
5551         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5552         for (i = 0; i <= HDA_SIDE; i++) {
5553                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5554                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5555                 if (nid)
5556                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5557                                                           i);
5558         }
5559 }
5560
5561 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5562 {
5563         struct alc_spec *spec = codec->spec;
5564         hda_nid_t pin;
5565
5566         pin = spec->autocfg.hp_pins[0];
5567         if (pin) /* connect to front */
5568                 /* use dac 0 */
5569                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5570 }
5571
5572 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5573 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5574
5575 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5576 {
5577         struct alc_spec *spec = codec->spec;
5578         int i;
5579
5580         for (i = 0; i < AUTO_PIN_LAST; i++) {
5581                 hda_nid_t nid = spec->autocfg.input_pins[i];
5582                 if (alc882_is_input_pin(nid)) {
5583                         snd_hda_codec_write(codec, nid, 0,
5584                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5585                                             i <= AUTO_PIN_FRONT_MIC ?
5586                                             PIN_VREF80 : PIN_IN);
5587                         if (nid != ALC882_PIN_CD_NID)
5588                                 snd_hda_codec_write(codec, nid, 0,
5589                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5590                                                     AMP_OUT_MUTE);
5591                 }
5592         }
5593 }
5594
5595 /* almost identical with ALC880 parser... */
5596 static int alc882_parse_auto_config(struct hda_codec *codec)
5597 {
5598         struct alc_spec *spec = codec->spec;
5599         int err = alc880_parse_auto_config(codec);
5600
5601         if (err < 0)
5602                 return err;
5603         else if (err > 0)
5604                 /* hack - override the init verbs */
5605                 spec->init_verbs[0] = alc882_auto_init_verbs;
5606         return err;
5607 }
5608
5609 /* additional initialization for auto-configuration model */
5610 static void alc882_auto_init(struct hda_codec *codec)
5611 {
5612         alc882_auto_init_multi_out(codec);
5613         alc882_auto_init_hp_out(codec);
5614         alc882_auto_init_analog_input(codec);
5615 }
5616
5617 static int patch_alc882(struct hda_codec *codec)
5618 {
5619         struct alc_spec *spec;
5620         int err, board_config;
5621
5622         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5623         if (spec == NULL)
5624                 return -ENOMEM;
5625
5626         codec->spec = spec;
5627
5628         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5629                                                   alc882_models,
5630                                                   alc882_cfg_tbl);
5631
5632         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5633                 /* Pick up systems that don't supply PCI SSID */
5634                 switch (codec->subsystem_id) {
5635                 case 0x106b0c00: /* Mac Pro */
5636                         board_config = ALC885_MACPRO;
5637                         break;
5638                 case 0x106b1000: /* iMac 24 */
5639                         board_config = ALC885_IMAC24;
5640                         break;
5641                 default:
5642                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5643                                          "trying auto-probe from BIOS...\n");
5644                         board_config = ALC882_AUTO;
5645                 }
5646         }
5647
5648         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5649
5650         if (board_config == ALC882_AUTO) {
5651                 /* automatic parse from the BIOS config */
5652                 err = alc882_parse_auto_config(codec);
5653                 if (err < 0) {
5654                         alc_free(codec);
5655                         return err;
5656                 } else if (!err) {
5657                         printk(KERN_INFO
5658                                "hda_codec: Cannot set up configuration "
5659                                "from BIOS.  Using base mode...\n");
5660                         board_config = ALC882_3ST_DIG;
5661                 }
5662         }
5663
5664         if (board_config != ALC882_AUTO)
5665                 setup_preset(spec, &alc882_presets[board_config]);
5666
5667         if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
5668                 alc882_gpio_mute(codec, 0, 0);
5669                 alc882_gpio_mute(codec, 1, 0);
5670         }
5671
5672         spec->stream_name_analog = "ALC882 Analog";
5673         spec->stream_analog_playback = &alc882_pcm_analog_playback;
5674         spec->stream_analog_capture = &alc882_pcm_analog_capture;
5675
5676         spec->stream_name_digital = "ALC882 Digital";
5677         spec->stream_digital_playback = &alc882_pcm_digital_playback;
5678         spec->stream_digital_capture = &alc882_pcm_digital_capture;
5679
5680         if (!spec->adc_nids && spec->input_mux) {
5681                 /* check whether NID 0x07 is valid */
5682                 unsigned int wcap = get_wcaps(codec, 0x07);
5683                 /* get type */
5684                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5685                 if (wcap != AC_WID_AUD_IN) {
5686                         spec->adc_nids = alc882_adc_nids_alt;
5687                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5688                         spec->mixers[spec->num_mixers] =
5689                                 alc882_capture_alt_mixer;
5690                         spec->num_mixers++;
5691                 } else {
5692                         spec->adc_nids = alc882_adc_nids;
5693                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5694                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5695                         spec->num_mixers++;
5696                 }
5697         }
5698
5699         codec->patch_ops = alc_patch_ops;
5700         if (board_config == ALC882_AUTO)
5701                 spec->init_hook = alc882_auto_init;
5702
5703         return 0;
5704 }
5705
5706 /*
5707  * ALC883 support
5708  *
5709  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5710  * configuration.  Each pin widget can choose any input DACs and a mixer.
5711  * Each ADC is connected from a mixer of all inputs.  This makes possible
5712  * 6-channel independent captures.
5713  *
5714  * In addition, an independent DAC for the multi-playback (not used in this
5715  * driver yet).
5716  */
5717 #define ALC883_DIGOUT_NID       0x06
5718 #define ALC883_DIGIN_NID        0x0a
5719
5720 static hda_nid_t alc883_dac_nids[4] = {
5721         /* front, rear, clfe, rear_surr */
5722         0x02, 0x04, 0x03, 0x05
5723 };
5724
5725 static hda_nid_t alc883_adc_nids[2] = {
5726         /* ADC1-2 */
5727         0x08, 0x09,
5728 };
5729
5730 /* input MUX */
5731 /* FIXME: should be a matrix-type input source selection */
5732
5733 static struct hda_input_mux alc883_capture_source = {
5734         .num_items = 4,
5735         .items = {
5736                 { "Mic", 0x0 },
5737                 { "Front Mic", 0x1 },
5738                 { "Line", 0x2 },
5739                 { "CD", 0x4 },
5740         },
5741 };
5742
5743 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5744         .num_items = 2,
5745         .items = {
5746                 { "Mic", 0x1 },
5747                 { "Line", 0x2 },
5748         },
5749 };
5750
5751 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5752         .num_items = 4,
5753         .items = {
5754                 { "Mic", 0x0 },
5755                 { "iMic", 0x1 },
5756                 { "Line", 0x2 },
5757                 { "CD", 0x4 },
5758         },
5759 };
5760
5761 #define alc883_mux_enum_info alc_mux_enum_info
5762 #define alc883_mux_enum_get alc_mux_enum_get
5763
5764 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5765                                struct snd_ctl_elem_value *ucontrol)
5766 {
5767         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5768         struct alc_spec *spec = codec->spec;
5769         const struct hda_input_mux *imux = spec->input_mux;
5770         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5771         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5772         hda_nid_t nid = capture_mixers[adc_idx];
5773         unsigned int *cur_val = &spec->cur_mux[adc_idx];
5774         unsigned int i, idx;
5775
5776         idx = ucontrol->value.enumerated.item[0];
5777         if (idx >= imux->num_items)
5778                 idx = imux->num_items - 1;
5779         if (*cur_val == idx && !codec->in_resume)
5780                 return 0;
5781         for (i = 0; i < imux->num_items; i++) {
5782                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
5783                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5784                                     v | (imux->items[i].index << 8));
5785         }
5786         *cur_val = idx;
5787         return 1;
5788 }
5789
5790 /*
5791  * 2ch mode
5792  */
5793 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5794         { 2, NULL }
5795 };
5796
5797 /*
5798  * 2ch mode
5799  */
5800 static struct hda_verb alc883_3ST_ch2_init[] = {
5801         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5802         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5803         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5804         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5805         { } /* end */
5806 };
5807
5808 /*
5809  * 6ch mode
5810  */
5811 static struct hda_verb alc883_3ST_ch6_init[] = {
5812         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5813         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5814         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5815         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5816         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5817         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5818         { } /* end */
5819 };
5820
5821 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5822         { 2, alc883_3ST_ch2_init },
5823         { 6, alc883_3ST_ch6_init },
5824 };
5825
5826 /*
5827  * 6ch mode
5828  */
5829 static struct hda_verb alc883_sixstack_ch6_init[] = {
5830         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5831         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5832         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5833         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5834         { } /* end */
5835 };
5836
5837 /*
5838  * 8ch mode
5839  */
5840 static struct hda_verb alc883_sixstack_ch8_init[] = {
5841         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5842         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5843         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5844         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5845         { } /* end */
5846 };
5847
5848 static struct hda_channel_mode alc883_sixstack_modes[2] = {
5849         { 6, alc883_sixstack_ch6_init },
5850         { 8, alc883_sixstack_ch8_init },
5851 };
5852
5853 static struct hda_verb alc883_medion_eapd_verbs[] = {
5854         /* eanable EAPD on medion laptop */
5855         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5856         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5857         { }
5858 };
5859
5860 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5861  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5862  */
5863
5864 static struct snd_kcontrol_new alc883_base_mixer[] = {
5865         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5866         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5867         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5868         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5869         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5870         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5871         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5872         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5873         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5874         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5875         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5876         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5877         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5878         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5879         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5880         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5881         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5882         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5883         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5884         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5885         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5886         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5887         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5888         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5889         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5890         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5891         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5892         {
5893                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5894                 /* .name = "Capture Source", */
5895                 .name = "Input Source",
5896                 .count = 2,
5897                 .info = alc883_mux_enum_info,
5898                 .get = alc883_mux_enum_get,
5899                 .put = alc883_mux_enum_put,
5900         },
5901         { } /* end */
5902 };
5903
5904 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5905         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5906         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5907         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5908         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5909         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5910         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5911         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5912         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5913         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5914         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5915         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5916         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5917         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5918         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5919         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5920         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5921         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5922         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5923         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5924         {
5925                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5926                 /* .name = "Capture Source", */
5927                 .name = "Input Source",
5928                 .count = 2,
5929                 .info = alc883_mux_enum_info,
5930                 .get = alc883_mux_enum_get,
5931                 .put = alc883_mux_enum_put,
5932         },
5933         { } /* end */
5934 };
5935
5936 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5937         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5938         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5939         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5940         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5941         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5942         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5943         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5944         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5945         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5946         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5947         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5948         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5949         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5950         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5951         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5952         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5953         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5954         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5955         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5956         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5957         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5958         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5959         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5960         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5961         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5962         {
5963                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5964                 /* .name = "Capture Source", */
5965                 .name = "Input Source",
5966                 .count = 2,
5967                 .info = alc883_mux_enum_info,
5968                 .get = alc883_mux_enum_get,
5969                 .put = alc883_mux_enum_put,
5970         },
5971         { } /* end */
5972 };
5973
5974 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5975         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5976         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5977         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5978         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5979         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5980         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5981         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5982         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5983         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5984         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5985         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5986         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5987         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5988         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5989         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5990         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5991         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5992         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5993         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5994         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5995         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5996         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5997         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5998
5999         {
6000                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6001                 /* .name = "Capture Source", */
6002                 .name = "Input Source",
6003                 .count = 1,
6004                 .info = alc883_mux_enum_info,
6005                 .get = alc883_mux_enum_get,
6006                 .put = alc883_mux_enum_put,
6007         },
6008         { } /* end */
6009 };
6010
6011 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6012         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6013         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6014         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6015         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6016         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6017         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6018         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6019         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6020         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6021         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6022         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6023         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6024         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6025         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6026         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6027         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6028         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6029         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6030         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6031         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6032         {
6033                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6034                 /* .name = "Capture Source", */
6035                 .name = "Input Source",
6036                 .count = 2,
6037                 .info = alc883_mux_enum_info,
6038                 .get = alc883_mux_enum_get,
6039                 .put = alc883_mux_enum_put,
6040         },
6041         { } /* end */
6042 };
6043
6044 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6045         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6046         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6047         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6048         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6049         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6050         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6051         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6052         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6053         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6054         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6055         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6056         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6057         {
6058                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6059                 /* .name = "Capture Source", */
6060                 .name = "Input Source",
6061                 .count = 2,
6062                 .info = alc883_mux_enum_info,
6063                 .get = alc883_mux_enum_get,
6064                 .put = alc883_mux_enum_put,
6065         },
6066         { } /* end */
6067 };
6068
6069 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6070         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6071         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6072         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6073         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6074         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6075         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6076         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6077         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6078         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6079         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6080         {
6081                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6082                 /* .name = "Capture Source", */
6083                 .name = "Input Source",
6084                 .count = 1,
6085                 .info = alc883_mux_enum_info,
6086                 .get = alc883_mux_enum_get,
6087                 .put = alc883_mux_enum_put,
6088         },
6089         { } /* end */
6090 };
6091
6092 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6093         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6094         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6095         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6096         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6097         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6098         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6099         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6100         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6101         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6102         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6103         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6104         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6105         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6106         {
6107                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6108                 /* .name = "Capture Source", */
6109                 .name = "Input Source",
6110                 .count = 2,
6111                 .info = alc883_mux_enum_info,
6112                 .get = alc883_mux_enum_get,
6113                 .put = alc883_mux_enum_put,
6114         },
6115         { } /* end */
6116 };
6117
6118 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6119         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6120         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6121         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6122         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6123         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6124         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6125         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6126         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6127         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6128         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6129         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6130         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6131         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6132         {
6133                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6134                 /* .name = "Capture Source", */
6135                 .name = "Input Source",
6136                 .count = 2,
6137                 .info = alc883_mux_enum_info,
6138                 .get = alc883_mux_enum_get,
6139                 .put = alc883_mux_enum_put,
6140         },
6141         { } /* end */
6142 };      
6143
6144 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6145         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6146         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6147         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6148         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6149         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6150         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6151         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6152         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6153         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6154         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6155         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6156         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6157         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6158         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6159         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6160         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6161         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6162         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6163         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6164         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6165         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6166         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6167         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6168         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6169         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6170         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6171         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6172         {
6173                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6174                 /* .name = "Capture Source", */
6175                 .name = "Input Source",
6176                 .count = 2,
6177                 .info = alc883_mux_enum_info,
6178                 .get = alc883_mux_enum_get,
6179                 .put = alc883_mux_enum_put,
6180         },
6181         { } /* end */
6182 };
6183
6184 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6185         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6186         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6187         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6188         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6189         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6190         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6191         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6192         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6193         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6194         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6195         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6196         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6197         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6198         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6199         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6200         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6201         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6202         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6203         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6204         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6205         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6206         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6207         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6208         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6209         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6210         {
6211                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6212                 /* .name = "Capture Source", */
6213                 .name = "Input Source",
6214                 .count = 2,
6215                 .info = alc883_mux_enum_info,
6216                 .get = alc883_mux_enum_get,
6217                 .put = alc883_mux_enum_put,
6218         },
6219         { } /* end */
6220 };
6221
6222 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6223         {
6224                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6225                 .name = "Channel Mode",
6226                 .info = alc_ch_mode_info,
6227                 .get = alc_ch_mode_get,
6228                 .put = alc_ch_mode_put,
6229         },
6230         { } /* end */
6231 };
6232
6233 static struct hda_verb alc883_init_verbs[] = {
6234         /* ADC1: mute amp left and right */
6235         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6236         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6237         /* ADC2: mute amp left and right */
6238         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6239         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6240         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6241         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6242         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6243         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6244         /* Rear mixer */
6245         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6246         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6247         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6248         /* CLFE mixer */
6249         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6250         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6251         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6252         /* Side mixer */
6253         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6254         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6255         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6256
6257         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6258         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6259         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6260         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6261         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6262
6263         /* Front Pin: output 0 (0x0c) */
6264         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6265         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6266         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6267         /* Rear Pin: output 1 (0x0d) */
6268         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6269         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6270         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6271         /* CLFE Pin: output 2 (0x0e) */
6272         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6273         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6274         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6275         /* Side Pin: output 3 (0x0f) */
6276         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6277         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6278         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6279         /* Mic (rear) pin: input vref at 80% */
6280         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6281         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6282         /* Front Mic pin: input vref at 80% */
6283         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6284         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6285         /* Line In pin: input */
6286         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6287         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6288         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6289         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6290         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6291         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6292         /* CD pin widget for input */
6293         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6294
6295         /* FIXME: use matrix-type input source selection */
6296         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6297         /* Input mixer2 */
6298         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6299         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6300         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6301         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6302         /* Input mixer3 */
6303         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6304         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6305         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6306         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6307         { }
6308 };
6309
6310 static struct hda_verb alc883_tagra_verbs[] = {
6311         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6312         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6313
6314         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6315         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6316         
6317         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6318         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6319         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6320
6321         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6322         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6323         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6324         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6325
6326         { } /* end */
6327 };
6328
6329 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6330         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6331         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6332         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6333         { } /* end */
6334 };
6335
6336 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6337         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6338         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6339         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6340         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6341         { } /* end */
6342 };
6343
6344 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6345         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6346         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6347         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6348         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6349         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6350         { } /* end */
6351 };
6352
6353 static struct hda_verb alc888_6st_hp_verbs[] = {
6354         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6355         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6356         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6357         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6358         { }
6359 };
6360
6361 static struct hda_verb alc888_3st_hp_verbs[] = {
6362         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6363         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6364         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6365         { }
6366 };
6367
6368 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6369         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6370         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6371         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6372         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6373         { }
6374 };
6375
6376 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6377         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6378         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6379         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6380         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6381         { }
6382 };
6383
6384 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6385         { 2, alc888_3st_hp_2ch_init },
6386         { 6, alc888_3st_hp_6ch_init },
6387 };
6388
6389 /* toggle front-jack and RCA according to the hp-jack state */
6390 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6391 {
6392         unsigned int present;
6393  
6394         present = snd_hda_codec_read(codec, 0x1b, 0,
6395                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6396         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6397                                  0x80, present ? 0x80 : 0);
6398         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6399                                  0x80, present ? 0x80 : 0);
6400         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6401                                  0x80, present ? 0x80 : 0);
6402         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6403                                  0x80, present ? 0x80 : 0);
6404         
6405 }
6406
6407 /* toggle RCA according to the front-jack state */
6408 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6409 {
6410         unsigned int present;
6411  
6412         present = snd_hda_codec_read(codec, 0x14, 0,
6413                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6414         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6415                                  0x80, present ? 0x80 : 0);
6416         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6417                                  0x80, present ? 0x80 : 0);
6418         
6419 }
6420 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6421                                              unsigned int res)
6422 {
6423         if ((res >> 26) == ALC880_HP_EVENT)
6424                 alc888_lenovo_ms7195_front_automute(codec);
6425         if ((res >> 26) == ALC880_FRONT_EVENT)
6426                 alc888_lenovo_ms7195_rca_automute(codec);
6427 }
6428
6429 static struct hda_verb alc883_medion_md2_verbs[] = {
6430         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6431         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6432
6433         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6434
6435         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6436         { } /* end */
6437 };
6438
6439 /* toggle speaker-output according to the hp-jack state */
6440 static void alc883_medion_md2_automute(struct hda_codec *codec)
6441 {
6442         unsigned int present;
6443  
6444         present = snd_hda_codec_read(codec, 0x14, 0,
6445                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6446         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6447                                  0x80, present ? 0x80 : 0);
6448         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6449                                  0x80, present ? 0x80 : 0);
6450 }
6451
6452 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6453                                           unsigned int res)
6454 {
6455         if ((res >> 26) == ALC880_HP_EVENT)
6456                 alc883_medion_md2_automute(codec);
6457 }
6458
6459 /* toggle speaker-output according to the hp-jack state */
6460 static void alc883_tagra_automute(struct hda_codec *codec)
6461 {
6462         unsigned int present;
6463         unsigned char bits;
6464
6465         present = snd_hda_codec_read(codec, 0x14, 0,
6466                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6467         bits = present ? 0x80 : 0;
6468         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
6469                                  0x80, bits);
6470         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
6471                                  0x80, bits);
6472         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6473                             present ? 1 : 3);
6474 }
6475
6476 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6477 {
6478         if ((res >> 26) == ALC880_HP_EVENT)
6479                 alc883_tagra_automute(codec);
6480 }
6481
6482 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6483 {
6484         unsigned int present;
6485         unsigned char bits;
6486
6487         present = snd_hda_codec_read(codec, 0x14, 0,
6488                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6489         bits = present ? 0x80 : 0;
6490         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6491                                  0x80, bits);
6492         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6493                                  0x80, bits);
6494 }
6495
6496 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6497 {
6498         unsigned int present;
6499         unsigned char bits;
6500
6501         present = snd_hda_codec_read(codec, 0x1b, 0,
6502                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6503         bits = present ? 0x80 : 0;
6504         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6505                                  0x80, bits);
6506         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6507                                  0x80, bits);
6508         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6509                                  0x80, bits);
6510         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6511                                  0x80, bits);
6512 }
6513
6514 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6515                                            unsigned int res)
6516 {
6517         if ((res >> 26) == ALC880_HP_EVENT)
6518                 alc883_lenovo_101e_all_automute(codec);
6519         if ((res >> 26) == ALC880_FRONT_EVENT)
6520                 alc883_lenovo_101e_ispeaker_automute(codec);
6521 }
6522
6523 /*
6524  * generic initialization of ADC, input mixers and output mixers
6525  */
6526 static struct hda_verb alc883_auto_init_verbs[] = {
6527         /*
6528          * Unmute ADC0-2 and set the default input to mic-in
6529          */
6530         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6531         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6532         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6533         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6534
6535         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6536          * mixer widget
6537          * Note: PASD motherboards uses the Line In 2 as the input for
6538          * front panel mic (mic 2)
6539          */
6540         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6541         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6542         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6543         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6544         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6545         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6546
6547         /*
6548          * Set up output mixers (0x0c - 0x0f)
6549          */
6550         /* set vol=0 to output mixers */
6551         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6552         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6553         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6554         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6555         /* set up input amps for analog loopback */
6556         /* Amp Indices: DAC = 0, mixer = 1 */
6557         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6558         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6559         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6560         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6561         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6562         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6563         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6564         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6565         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6566         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6567
6568         /* FIXME: use matrix-type input source selection */
6569         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6570         /* Input mixer1 */
6571         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6572         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6573         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6574         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6575         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6576         /* Input mixer2 */
6577         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6578         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6579         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6580         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6581         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6582
6583         { }
6584 };
6585
6586 /* capture mixer elements */
6587 static struct snd_kcontrol_new alc883_capture_mixer[] = {
6588         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6589         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6590         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6591         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6592         {
6593                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6594                 /* The multiple "Capture Source" controls confuse alsamixer
6595                  * So call somewhat different..
6596                  * FIXME: the controls appear in the "playback" view!
6597                  */
6598                 /* .name = "Capture Source", */
6599                 .name = "Input Source",
6600                 .count = 2,
6601                 .info = alc882_mux_enum_info,
6602                 .get = alc882_mux_enum_get,
6603                 .put = alc882_mux_enum_put,
6604         },
6605         { } /* end */
6606 };
6607
6608 /* pcm configuration: identiacal with ALC880 */
6609 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
6610 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
6611 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
6612 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
6613
6614 /*
6615  * configuration and preset
6616  */
6617 static const char *alc883_models[ALC883_MODEL_LAST] = {
6618         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
6619         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
6620         [ALC883_3ST_6ch]        = "3stack-6ch",
6621         [ALC883_6ST_DIG]        = "6stack-dig",
6622         [ALC883_TARGA_DIG]      = "targa-dig",
6623         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
6624         [ALC883_ACER]           = "acer",
6625         [ALC883_MEDION]         = "medion",
6626         [ALC883_MEDION_MD2]     = "medion-md2",
6627         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
6628         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6629         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
6630         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6631         [ALC888_6ST_HP]         = "6stack-hp",
6632         [ALC888_3ST_HP]         = "3stack-hp",
6633         [ALC883_AUTO]           = "auto",
6634 };
6635
6636 static struct snd_pci_quirk alc883_cfg_tbl[] = {
6637         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6638         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6639         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6640         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6641         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6642         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6643         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6644         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6645         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6646         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6647         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6648         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6649         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6650         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6651         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6652         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6653         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6654         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6655         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6656         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6657         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6658         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6659         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6660         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6661         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6662         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6663         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6664         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6665         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6666         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6667         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6668         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6669         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6670         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6671         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6672         {}
6673 };
6674
6675 static struct alc_config_preset alc883_presets[] = {
6676         [ALC883_3ST_2ch_DIG] = {
6677                 .mixers = { alc883_3ST_2ch_mixer },
6678                 .init_verbs = { alc883_init_verbs },
6679                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6680                 .dac_nids = alc883_dac_nids,
6681                 .dig_out_nid = ALC883_DIGOUT_NID,
6682                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6683                 .adc_nids = alc883_adc_nids,
6684                 .dig_in_nid = ALC883_DIGIN_NID,
6685                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6686                 .channel_mode = alc883_3ST_2ch_modes,
6687                 .input_mux = &alc883_capture_source,
6688         },
6689         [ALC883_3ST_6ch_DIG] = {
6690                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6691                 .init_verbs = { alc883_init_verbs },
6692                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6693                 .dac_nids = alc883_dac_nids,
6694                 .dig_out_nid = ALC883_DIGOUT_NID,
6695                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6696                 .adc_nids = alc883_adc_nids,
6697                 .dig_in_nid = ALC883_DIGIN_NID,
6698                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6699                 .channel_mode = alc883_3ST_6ch_modes,
6700                 .need_dac_fix = 1,
6701                 .input_mux = &alc883_capture_source,
6702         },
6703         [ALC883_3ST_6ch] = {
6704                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6705                 .init_verbs = { alc883_init_verbs },
6706                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6707                 .dac_nids = alc883_dac_nids,
6708                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6709                 .adc_nids = alc883_adc_nids,
6710                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6711                 .channel_mode = alc883_3ST_6ch_modes,
6712                 .need_dac_fix = 1,
6713                 .input_mux = &alc883_capture_source,
6714         },
6715         [ALC883_6ST_DIG] = {
6716                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
6717                 .init_verbs = { alc883_init_verbs },
6718                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6719                 .dac_nids = alc883_dac_nids,
6720                 .dig_out_nid = ALC883_DIGOUT_NID,
6721                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6722                 .adc_nids = alc883_adc_nids,
6723                 .dig_in_nid = ALC883_DIGIN_NID,
6724                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6725                 .channel_mode = alc883_sixstack_modes,
6726                 .input_mux = &alc883_capture_source,
6727         },
6728         [ALC883_TARGA_DIG] = {
6729                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6730                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6731                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6732                 .dac_nids = alc883_dac_nids,
6733                 .dig_out_nid = ALC883_DIGOUT_NID,
6734                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6735                 .adc_nids = alc883_adc_nids,
6736                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6737                 .channel_mode = alc883_3ST_6ch_modes,
6738                 .need_dac_fix = 1,
6739                 .input_mux = &alc883_capture_source,
6740                 .unsol_event = alc883_tagra_unsol_event,
6741                 .init_hook = alc883_tagra_automute,
6742         },
6743         [ALC883_TARGA_2ch_DIG] = {
6744                 .mixers = { alc883_tagra_2ch_mixer},
6745                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6746                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6747                 .dac_nids = alc883_dac_nids,
6748                 .dig_out_nid = ALC883_DIGOUT_NID,
6749                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6750                 .adc_nids = alc883_adc_nids,
6751                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6752                 .channel_mode = alc883_3ST_2ch_modes,
6753                 .input_mux = &alc883_capture_source,
6754                 .unsol_event = alc883_tagra_unsol_event,
6755                 .init_hook = alc883_tagra_automute,
6756         },
6757         [ALC883_ACER] = {
6758                 .mixers = { alc883_base_mixer,
6759                             alc883_chmode_mixer },
6760                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
6761                  * and the headphone jack.  Turn this on and rely on the
6762                  * standard mute methods whenever the user wants to turn
6763                  * these outputs off.
6764                  */
6765                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6766                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6767                 .dac_nids = alc883_dac_nids,
6768                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6769                 .adc_nids = alc883_adc_nids,
6770                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6771                 .channel_mode = alc883_3ST_2ch_modes,
6772                 .input_mux = &alc883_capture_source,
6773         },
6774         [ALC883_MEDION] = {
6775                 .mixers = { alc883_fivestack_mixer,
6776                             alc883_chmode_mixer },
6777                 .init_verbs = { alc883_init_verbs,
6778                                 alc883_medion_eapd_verbs },
6779                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6780                 .dac_nids = alc883_dac_nids,
6781                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6782                 .adc_nids = alc883_adc_nids,
6783                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6784                 .channel_mode = alc883_sixstack_modes,
6785                 .input_mux = &alc883_capture_source,
6786         },
6787         [ALC883_MEDION_MD2] = {
6788                 .mixers = { alc883_medion_md2_mixer},
6789                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6790                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6791                 .dac_nids = alc883_dac_nids,
6792                 .dig_out_nid = ALC883_DIGOUT_NID,
6793                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6794                 .adc_nids = alc883_adc_nids,
6795                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6796                 .channel_mode = alc883_3ST_2ch_modes,
6797                 .input_mux = &alc883_capture_source,
6798                 .unsol_event = alc883_medion_md2_unsol_event,
6799                 .init_hook = alc883_medion_md2_automute,
6800         },      
6801         [ALC883_LAPTOP_EAPD] = {
6802                 .mixers = { alc883_base_mixer,
6803                             alc883_chmode_mixer },
6804                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6805                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6806                 .dac_nids = alc883_dac_nids,
6807                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6808                 .adc_nids = alc883_adc_nids,
6809                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6810                 .channel_mode = alc883_3ST_2ch_modes,
6811                 .input_mux = &alc883_capture_source,
6812         },
6813         [ALC883_LENOVO_101E_2ch] = {
6814                 .mixers = { alc883_lenovo_101e_2ch_mixer},
6815                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6816                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6817                 .dac_nids = alc883_dac_nids,
6818                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6819                 .adc_nids = alc883_adc_nids,
6820                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6821                 .channel_mode = alc883_3ST_2ch_modes,
6822                 .input_mux = &alc883_lenovo_101e_capture_source,
6823                 .unsol_event = alc883_lenovo_101e_unsol_event,
6824                 .init_hook = alc883_lenovo_101e_all_automute,
6825         },
6826         [ALC883_LENOVO_NB0763] = {
6827                 .mixers = { alc883_lenovo_nb0763_mixer },
6828                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6829                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6830                 .dac_nids = alc883_dac_nids,
6831                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6832                 .adc_nids = alc883_adc_nids,
6833                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6834                 .channel_mode = alc883_3ST_2ch_modes,
6835                 .need_dac_fix = 1,
6836                 .input_mux = &alc883_lenovo_nb0763_capture_source,
6837                 .unsol_event = alc883_medion_md2_unsol_event,
6838                 .init_hook = alc883_medion_md2_automute,
6839         },
6840         [ALC888_LENOVO_MS7195_DIG] = {
6841                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6842                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6843                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6844                 .dac_nids = alc883_dac_nids,
6845                 .dig_out_nid = ALC883_DIGOUT_NID,
6846                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6847                 .adc_nids = alc883_adc_nids,
6848                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6849                 .channel_mode = alc883_3ST_6ch_modes,
6850                 .need_dac_fix = 1,
6851                 .input_mux = &alc883_capture_source,
6852                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
6853                 .init_hook = alc888_lenovo_ms7195_front_automute,
6854         },      
6855         [ALC888_6ST_HP] = {
6856                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
6857                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
6858                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6859                 .dac_nids = alc883_dac_nids,
6860                 .dig_out_nid = ALC883_DIGOUT_NID,
6861                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6862                 .adc_nids = alc883_adc_nids,
6863                 .dig_in_nid = ALC883_DIGIN_NID,
6864                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6865                 .channel_mode = alc883_sixstack_modes,
6866                 .input_mux = &alc883_capture_source,
6867         },
6868         [ALC888_3ST_HP] = {
6869                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
6870                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
6871                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6872                 .dac_nids = alc883_dac_nids,
6873                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6874                 .adc_nids = alc883_adc_nids,
6875                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
6876                 .channel_mode = alc888_3st_hp_modes,
6877                 .need_dac_fix = 1,
6878                 .input_mux = &alc883_capture_source,
6879         },
6880 };
6881
6882
6883 /*
6884  * BIOS auto configuration
6885  */
6886 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6887                                               hda_nid_t nid, int pin_type,
6888                                               int dac_idx)
6889 {
6890         /* set as output */
6891         struct alc_spec *spec = codec->spec;
6892         int idx;
6893
6894         if (spec->multiout.dac_nids[dac_idx] == 0x25)
6895                 idx = 4;
6896         else
6897                 idx = spec->multiout.dac_nids[dac_idx] - 2;
6898
6899         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6900                             pin_type);
6901         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6902                             AMP_OUT_UNMUTE);
6903         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6904
6905 }
6906
6907 static void alc883_auto_init_multi_out(struct hda_codec *codec)
6908 {
6909         struct alc_spec *spec = codec->spec;
6910         int i;
6911
6912         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6913         for (i = 0; i <= HDA_SIDE; i++) {
6914                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6915                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6916                 if (nid)
6917                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6918                                                           i);
6919         }
6920 }
6921
6922 static void alc883_auto_init_hp_out(struct hda_codec *codec)
6923 {
6924         struct alc_spec *spec = codec->spec;
6925         hda_nid_t pin;
6926
6927         pin = spec->autocfg.hp_pins[0];
6928         if (pin) /* connect to front */
6929                 /* use dac 0 */
6930                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6931 }
6932
6933 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
6934 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
6935
6936 static void alc883_auto_init_analog_input(struct hda_codec *codec)
6937 {
6938         struct alc_spec *spec = codec->spec;
6939         int i;
6940
6941         for (i = 0; i < AUTO_PIN_LAST; i++) {
6942                 hda_nid_t nid = spec->autocfg.input_pins[i];
6943                 if (alc883_is_input_pin(nid)) {
6944                         snd_hda_codec_write(codec, nid, 0,
6945                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
6946                                             (i <= AUTO_PIN_FRONT_MIC ?
6947                                              PIN_VREF80 : PIN_IN));
6948                         if (nid != ALC883_PIN_CD_NID)
6949                                 snd_hda_codec_write(codec, nid, 0,
6950                                                     AC_VERB_SET_AMP_GAIN_MUTE,
6951                                                     AMP_OUT_MUTE);
6952                 }
6953         }
6954 }
6955
6956 /* almost identical with ALC880 parser... */
6957 static int alc883_parse_auto_config(struct hda_codec *codec)
6958 {
6959         struct alc_spec *spec = codec->spec;
6960         int err = alc880_parse_auto_config(codec);
6961
6962         if (err < 0)
6963                 return err;
6964         else if (err > 0)
6965                 /* hack - override the init verbs */
6966                 spec->init_verbs[0] = alc883_auto_init_verbs;
6967         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
6968         spec->num_mixers++;
6969         return err;
6970 }
6971
6972 /* additional initialization for auto-configuration model */
6973 static void alc883_auto_init(struct hda_codec *codec)
6974 {
6975         alc883_auto_init_multi_out(codec);
6976         alc883_auto_init_hp_out(codec);
6977         alc883_auto_init_analog_input(codec);
6978 }
6979
6980 static int patch_alc883(struct hda_codec *codec)
6981 {
6982         struct alc_spec *spec;
6983         int err, board_config;
6984
6985         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6986         if (spec == NULL)
6987                 return -ENOMEM;
6988
6989         codec->spec = spec;
6990
6991         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
6992                                                   alc883_models,
6993                                                   alc883_cfg_tbl);
6994         if (board_config < 0) {
6995                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
6996                        "trying auto-probe from BIOS...\n");
6997                 board_config = ALC883_AUTO;
6998         }
6999
7000         if (board_config == ALC883_AUTO) {
7001                 /* automatic parse from the BIOS config */
7002                 err = alc883_parse_auto_config(codec);
7003                 if (err < 0) {
7004                         alc_free(codec);
7005                         return err;
7006                 } else if (!err) {
7007                         printk(KERN_INFO
7008                                "hda_codec: Cannot set up configuration "
7009                                "from BIOS.  Using base mode...\n");
7010                         board_config = ALC883_3ST_2ch_DIG;
7011                 }
7012         }
7013
7014         if (board_config != ALC883_AUTO)
7015                 setup_preset(spec, &alc883_presets[board_config]);
7016
7017         spec->stream_name_analog = "ALC883 Analog";
7018         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7019         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7020
7021         spec->stream_name_digital = "ALC883 Digital";
7022         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7023         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7024
7025         if (!spec->adc_nids && spec->input_mux) {
7026                 spec->adc_nids = alc883_adc_nids;
7027                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7028         }
7029
7030         codec->patch_ops = alc_patch_ops;
7031         if (board_config == ALC883_AUTO)
7032                 spec->init_hook = alc883_auto_init;
7033
7034         return 0;
7035 }
7036
7037 /*
7038  * ALC262 support
7039  */
7040
7041 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7042 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7043
7044 #define alc262_dac_nids         alc260_dac_nids
7045 #define alc262_adc_nids         alc882_adc_nids
7046 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7047
7048 #define alc262_modes            alc260_modes
7049 #define alc262_capture_source   alc882_capture_source
7050
7051 static struct snd_kcontrol_new alc262_base_mixer[] = {
7052         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7053         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7054         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7055         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7056         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7057         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7058         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7059         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7060         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7061         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7062         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7063         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7064         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7065            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7066         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7067         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7068         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7069         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7070         { } /* end */
7071 };
7072
7073 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7074         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7075         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7076         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7077         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7078         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7079         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7080         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7081         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7082         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7083         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7084         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7085         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7086         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7087            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7088         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7089         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7090         { } /* end */
7091 };
7092
7093 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7094         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7095         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7096         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7097         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7098         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7099
7100         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7101         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7102         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7103         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7104         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7105         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7106         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7107         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7108         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7109         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7110         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7111         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7112         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7113         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7114         { } /* end */
7115 };
7116
7117 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7118         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7119         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7120         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7121         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7122         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7123         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7124         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7125         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7126         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7127         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7128         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7129         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7130         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7131         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7132         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7133         { } /* end */
7134 };
7135
7136 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7137         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7138         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7139         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7140         { } /* end */
7141 };
7142
7143 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7144         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7145         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7146         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7147         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7148         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7149         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7150         { } /* end */
7151 };
7152
7153 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7154         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7155         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7156         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7157         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7158         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7159         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7160         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7161         { } /* end */
7162 };
7163
7164 #define alc262_capture_mixer            alc882_capture_mixer
7165 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7166
7167 /*
7168  * generic initialization of ADC, input mixers and output mixers
7169  */
7170 static struct hda_verb alc262_init_verbs[] = {
7171         /*
7172          * Unmute ADC0-2 and set the default input to mic-in
7173          */
7174         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7175         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7176         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7177         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7178         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7179         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7180
7181         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7182          * mixer widget
7183          * Note: PASD motherboards uses the Line In 2 as the input for
7184          * front panel mic (mic 2)
7185          */
7186         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7187         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7188         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7189         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7190         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7191         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7192
7193         /*
7194          * Set up output mixers (0x0c - 0x0e)
7195          */
7196         /* set vol=0 to output mixers */
7197         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7198         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7199         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7200         /* set up input amps for analog loopback */
7201         /* Amp Indices: DAC = 0, mixer = 1 */
7202         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7203         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7204         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7205         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7206         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7207         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7208
7209         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7210         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7211         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7212         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7213         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7214         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7215
7216         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7217         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7218         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7219         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7220         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7221         
7222         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7223         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7224         
7225         /* FIXME: use matrix-type input source selection */
7226         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7227         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7228         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7229         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7230         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7231         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7232         /* Input mixer2 */
7233         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7234         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7235         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7236         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7237         /* Input mixer3 */
7238         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7239         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7240         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7241         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7242
7243         { }
7244 };
7245
7246 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7247         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7248         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7249         {}
7250 };
7251
7252 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7253         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7254         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7255         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7256
7257         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7258         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7259         {}
7260 };
7261
7262 static struct hda_verb alc262_sony_unsol_verbs[] = {
7263         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7264         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7265         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7266
7267         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7268         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7269 };
7270
7271 /* mute/unmute internal speaker according to the hp jack and mute state */
7272 static void alc262_hippo_automute(struct hda_codec *codec, int force)
7273 {
7274         struct alc_spec *spec = codec->spec;
7275         unsigned int mute;
7276
7277         if (force || !spec->sense_updated) {
7278                 unsigned int present;
7279                 /* need to execute and sync at first */
7280                 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7281                 present = snd_hda_codec_read(codec, 0x15, 0,
7282                                          AC_VERB_GET_PIN_SENSE, 0);
7283                 spec->jack_present = (present & 0x80000000) != 0;
7284                 spec->sense_updated = 1;
7285         }
7286         if (spec->jack_present) {
7287                 /* mute internal speaker */
7288                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7289                                          0x80, 0x80);
7290                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7291                                          0x80, 0x80);
7292         } else {
7293                 /* unmute internal speaker if necessary */
7294                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7295                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7296                                          0x80, mute & 0x80);
7297                 mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
7298                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7299                                          0x80, mute & 0x80);
7300         }
7301 }
7302
7303 /* unsolicited event for HP jack sensing */
7304 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7305                                        unsigned int res)
7306 {
7307         if ((res >> 26) != ALC880_HP_EVENT)
7308                 return;
7309         alc262_hippo_automute(codec, 1);
7310 }
7311
7312 static void alc262_hippo1_automute(struct hda_codec *codec, int force)
7313 {
7314         struct alc_spec *spec = codec->spec;
7315         unsigned int mute;
7316
7317         if (force || !spec->sense_updated) {
7318                 unsigned int present;
7319                 /* need to execute and sync at first */
7320                 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7321                 present = snd_hda_codec_read(codec, 0x1b, 0,
7322                                          AC_VERB_GET_PIN_SENSE, 0);
7323                 spec->jack_present = (present & 0x80000000) != 0;
7324                 spec->sense_updated = 1;
7325         }
7326         if (spec->jack_present) {
7327                 /* mute internal speaker */
7328                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7329                                          0x80, 0x80);
7330                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7331                                          0x80, 0x80);
7332         } else {
7333                 /* unmute internal speaker if necessary */
7334                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7335                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7336                                          0x80, mute & 0x80);
7337                 mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
7338                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7339                                          0x80, mute & 0x80);
7340         }
7341 }
7342
7343 /* unsolicited event for HP jack sensing */
7344 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7345                                        unsigned int res)
7346 {
7347         if ((res >> 26) != ALC880_HP_EVENT)
7348                 return;
7349         alc262_hippo1_automute(codec, 1);
7350 }
7351
7352 /*
7353  * fujitsu model
7354  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7355  */
7356
7357 #define ALC_HP_EVENT    0x37
7358
7359 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7360         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7361         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7362         {}
7363 };
7364
7365 static struct hda_input_mux alc262_fujitsu_capture_source = {
7366         .num_items = 2,
7367         .items = {
7368                 { "Mic", 0x0 },
7369                 { "CD", 0x4 },
7370         },
7371 };
7372
7373 static struct hda_input_mux alc262_HP_capture_source = {
7374         .num_items = 5,
7375         .items = {
7376                 { "Mic", 0x0 },
7377                 { "Front Mic", 0x3 },
7378                 { "Line", 0x2 },
7379                 { "CD", 0x4 },
7380                 { "AUX IN", 0x6 },
7381         },
7382 };
7383
7384 /* mute/unmute internal speaker according to the hp jack and mute state */
7385 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7386 {
7387         struct alc_spec *spec = codec->spec;
7388         unsigned int mute;
7389
7390         if (force || !spec->sense_updated) {
7391                 unsigned int present;
7392                 /* need to execute and sync at first */
7393                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7394                 present = snd_hda_codec_read(codec, 0x14, 0,
7395                                          AC_VERB_GET_PIN_SENSE, 0);
7396                 spec->jack_present = (present & 0x80000000) != 0;
7397                 spec->sense_updated = 1;
7398         }
7399         if (spec->jack_present) {
7400                 /* mute internal speaker */
7401                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7402                                          0x80, 0x80);
7403                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7404                                          0x80, 0x80);
7405         } else {
7406                 /* unmute internal speaker if necessary */
7407                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7408                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7409                                          0x80, mute & 0x80);
7410                 mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
7411                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7412                                          0x80, mute & 0x80);
7413         }
7414 }
7415
7416 /* unsolicited event for HP jack sensing */
7417 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7418                                        unsigned int res)
7419 {
7420         if ((res >> 26) != ALC_HP_EVENT)
7421                 return;
7422         alc262_fujitsu_automute(codec, 1);
7423 }
7424
7425 /* bind volumes of both NID 0x0c and 0x0d */
7426 static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
7427                                          struct snd_ctl_elem_value *ucontrol)
7428 {
7429         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7430         long *valp = ucontrol->value.integer.value;
7431         int change;
7432
7433         change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
7434                                           0x7f, valp[0] & 0x7f);
7435         change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
7436                                            0x7f, valp[1] & 0x7f);
7437         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
7438                                  0x7f, valp[0] & 0x7f);
7439         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
7440                                  0x7f, valp[1] & 0x7f);
7441         return change;
7442 }
7443
7444 /* bind hp and internal speaker mute (with plug check) */
7445 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7446                                          struct snd_ctl_elem_value *ucontrol)
7447 {
7448         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7449         long *valp = ucontrol->value.integer.value;
7450         int change;
7451
7452         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7453                                           0x80, valp[0] ? 0 : 0x80);
7454         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7455                                            0x80, valp[1] ? 0 : 0x80);
7456         if (change || codec->in_resume)
7457                 alc262_fujitsu_automute(codec, codec->in_resume);
7458         return change;
7459 }
7460
7461 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7462         {
7463                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7464                 .name = "Master Playback Volume",
7465                 .info = snd_hda_mixer_amp_volume_info,
7466                 .get = snd_hda_mixer_amp_volume_get,
7467                 .put = alc262_fujitsu_master_vol_put,
7468                 .tlv = { .c = snd_hda_mixer_amp_tlv },
7469                 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7470         },
7471         {
7472                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7473                 .name = "Master Playback Switch",
7474                 .info = snd_hda_mixer_amp_switch_info,
7475                 .get = snd_hda_mixer_amp_switch_get,
7476                 .put = alc262_fujitsu_master_sw_put,
7477                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7478         },
7479         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7480         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7481         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7482         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7483         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7484         { } /* end */
7485 };
7486
7487 /* additional init verbs for Benq laptops */
7488 static struct hda_verb alc262_EAPD_verbs[] = {
7489         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7490         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7491         {}
7492 };
7493
7494 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7495         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7496         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7497
7498         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7499         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7500         {}
7501 };
7502
7503 /* add playback controls from the parsed DAC table */
7504 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7505                                              const struct auto_pin_cfg *cfg)
7506 {
7507         hda_nid_t nid;
7508         int err;
7509
7510         spec->multiout.num_dacs = 1;    /* only use one dac */
7511         spec->multiout.dac_nids = spec->private_dac_nids;
7512         spec->multiout.dac_nids[0] = 2;
7513
7514         nid = cfg->line_out_pins[0];
7515         if (nid) {
7516                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7517                                   "Front Playback Volume",
7518                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7519                 if (err < 0)
7520                         return err;
7521                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7522                                   "Front Playback Switch",
7523                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7524                 if (err < 0)
7525                         return err;
7526         }
7527
7528         nid = cfg->speaker_pins[0];
7529         if (nid) {
7530                 if (nid == 0x16) {
7531                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7532                                           "Speaker Playback Volume",
7533                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7534                                                               HDA_OUTPUT));
7535                         if (err < 0)
7536                                 return err;
7537                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7538                                           "Speaker Playback Switch",
7539                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7540                                                               HDA_OUTPUT));
7541                         if (err < 0)
7542                                 return err;
7543                 } else {
7544                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7545                                           "Speaker Playback Switch",
7546                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7547                                                               HDA_OUTPUT));
7548                         if (err < 0)
7549                                 return err;
7550                 }
7551         }
7552         nid = cfg->hp_pins[0];
7553         if (nid) {
7554                 /* spec->multiout.hp_nid = 2; */
7555                 if (nid == 0x16) {
7556                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7557                                           "Headphone Playback Volume",
7558                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7559                                                               HDA_OUTPUT));
7560                         if (err < 0)
7561                                 return err;
7562                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7563                                           "Headphone Playback Switch",
7564                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7565                                                               HDA_OUTPUT));
7566                         if (err < 0)
7567                                 return err;
7568                 } else {
7569                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7570                                           "Headphone Playback Switch",
7571                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7572                                                               HDA_OUTPUT));
7573                         if (err < 0)
7574                                 return err;
7575                 }
7576         }
7577         return 0;
7578 }
7579
7580 /* identical with ALC880 */
7581 #define alc262_auto_create_analog_input_ctls \
7582         alc880_auto_create_analog_input_ctls
7583
7584 /*
7585  * generic initialization of ADC, input mixers and output mixers
7586  */
7587 static struct hda_verb alc262_volume_init_verbs[] = {
7588         /*
7589          * Unmute ADC0-2 and set the default input to mic-in
7590          */
7591         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7592         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7593         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7594         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7595         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7596         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7597
7598         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7599          * mixer widget
7600          * Note: PASD motherboards uses the Line In 2 as the input for
7601          * front panel mic (mic 2)
7602          */
7603         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7604         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7605         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7606         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7607         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7608         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7609
7610         /*
7611          * Set up output mixers (0x0c - 0x0f)
7612          */
7613         /* set vol=0 to output mixers */
7614         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7615         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7616         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7617         
7618         /* set up input amps for analog loopback */
7619         /* Amp Indices: DAC = 0, mixer = 1 */
7620         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7621         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7622         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7623         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7624         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7625         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7626
7627         /* FIXME: use matrix-type input source selection */
7628         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7629         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7630         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7631         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7632         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7633         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7634         /* Input mixer2 */
7635         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7636         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7637         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7638         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7639         /* Input mixer3 */
7640         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7641         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7642         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7643         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7644
7645         { }
7646 };
7647
7648 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7649         /*
7650          * Unmute ADC0-2 and set the default input to mic-in
7651          */
7652         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7653         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7654         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7655         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7656         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7657         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7658
7659         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7660          * mixer widget
7661          * Note: PASD motherboards uses the Line In 2 as the input for
7662          * front panel mic (mic 2)
7663          */
7664         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7665         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7666         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7667         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7668         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7669         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7670         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7671         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7672         
7673         /*
7674          * Set up output mixers (0x0c - 0x0e)
7675          */
7676         /* set vol=0 to output mixers */
7677         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7678         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7679         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7680
7681         /* set up input amps for analog loopback */
7682         /* Amp Indices: DAC = 0, mixer = 1 */
7683         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7684         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7685         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7686         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7687         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7688         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7689
7690         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7691         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7692         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7693
7694         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7695         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7696
7697         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7698         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7699
7700         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7701         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7702         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7703         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7704         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7705
7706         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7707         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7708         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7709         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7710         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7711         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7712
7713
7714         /* FIXME: use matrix-type input source selection */
7715         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7716         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7717         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7718         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7719         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7720         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7721         /* Input mixer2 */
7722         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7723         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7724         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7725         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7726         /* Input mixer3 */
7727         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7728         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7729         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7730         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7731
7732         { }
7733 };
7734
7735 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7736         /*
7737          * Unmute ADC0-2 and set the default input to mic-in
7738          */
7739         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7740         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7741         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7742         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7743         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7744         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7745
7746         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7747          * mixer widget
7748          * Note: PASD motherboards uses the Line In 2 as the input for front
7749          * panel mic (mic 2)
7750          */
7751         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7752         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7753         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7754         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7755         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7756         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7757         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7758         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7759         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
7760         /*
7761          * Set up output mixers (0x0c - 0x0e)
7762          */
7763         /* set vol=0 to output mixers */
7764         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7765         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7766         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7767
7768         /* set up input amps for analog loopback */
7769         /* Amp Indices: DAC = 0, mixer = 1 */
7770         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7771         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7772         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7773         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7774         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7775         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7776
7777
7778         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
7779         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
7780         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
7781         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
7782         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
7783         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
7784         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
7785
7786         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7787         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7788
7789         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7790         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7791
7792         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7793         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7794         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7795         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7796         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7797         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7798
7799         /* FIXME: use matrix-type input source selection */
7800         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7801         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7802         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7803         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7804         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7805         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7806         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7807         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7808         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7809         /* Input mixer2 */
7810         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7811         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7812         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7813         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7814         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7815         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7816         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7817         /* Input mixer3 */
7818         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7819         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7820         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7821         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7822         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7823         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7824         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7825
7826         { }
7827 };
7828
7829 /* pcm configuration: identiacal with ALC880 */
7830 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
7831 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
7832 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
7833 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
7834
7835 /*
7836  * BIOS auto configuration
7837  */
7838 static int alc262_parse_auto_config(struct hda_codec *codec)
7839 {
7840         struct alc_spec *spec = codec->spec;
7841         int err;
7842         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7843
7844         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7845                                            alc262_ignore);
7846         if (err < 0)
7847                 return err;
7848         if (!spec->autocfg.line_outs)
7849                 return 0; /* can't find valid BIOS pin config */
7850         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7851         if (err < 0)
7852                 return err;
7853         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7854         if (err < 0)
7855                 return err;
7856
7857         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7858
7859         if (spec->autocfg.dig_out_pin)
7860                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7861         if (spec->autocfg.dig_in_pin)
7862                 spec->dig_in_nid = ALC262_DIGIN_NID;
7863
7864         if (spec->kctl_alloc)
7865                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7866
7867         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7868         spec->num_mux_defs = 1;
7869         spec->input_mux = &spec->private_imux;
7870
7871         return 1;
7872 }
7873
7874 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
7875 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
7876 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
7877
7878
7879 /* init callback for auto-configuration model -- overriding the default init */
7880 static void alc262_auto_init(struct hda_codec *codec)
7881 {
7882         alc262_auto_init_multi_out(codec);
7883         alc262_auto_init_hp_out(codec);
7884         alc262_auto_init_analog_input(codec);
7885 }
7886
7887 /*
7888  * configuration and preset
7889  */
7890 static const char *alc262_models[ALC262_MODEL_LAST] = {
7891         [ALC262_BASIC]          = "basic",
7892         [ALC262_HIPPO]          = "hippo",
7893         [ALC262_HIPPO_1]        = "hippo_1",
7894         [ALC262_FUJITSU]        = "fujitsu",
7895         [ALC262_HP_BPC]         = "hp-bpc",
7896         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7897         [ALC262_BENQ_ED8]       = "benq",
7898         [ALC262_BENQ_T31]       = "benq-t31",
7899         [ALC262_SONY_ASSAMD]    = "sony-assamd",
7900         [ALC262_AUTO]           = "auto",
7901 };
7902
7903 static struct snd_pci_quirk alc262_cfg_tbl[] = {
7904         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7905         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7906         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7907         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7908         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7909         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7910         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7911         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7912         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7913         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7914         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7915         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7916         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7917         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7918         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7919         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7920         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7921         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7922         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7923         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7924         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7925         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7926         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7927         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7928         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7929         {}
7930 };
7931
7932 static struct alc_config_preset alc262_presets[] = {
7933         [ALC262_BASIC] = {
7934                 .mixers = { alc262_base_mixer },
7935                 .init_verbs = { alc262_init_verbs },
7936                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7937                 .dac_nids = alc262_dac_nids,
7938                 .hp_nid = 0x03,
7939                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7940                 .channel_mode = alc262_modes,
7941                 .input_mux = &alc262_capture_source,
7942         },
7943         [ALC262_HIPPO] = {
7944                 .mixers = { alc262_base_mixer },
7945                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
7946                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7947                 .dac_nids = alc262_dac_nids,
7948                 .hp_nid = 0x03,
7949                 .dig_out_nid = ALC262_DIGOUT_NID,
7950                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7951                 .channel_mode = alc262_modes,
7952                 .input_mux = &alc262_capture_source,
7953                 .unsol_event = alc262_hippo_unsol_event,
7954         },
7955         [ALC262_HIPPO_1] = {
7956                 .mixers = { alc262_hippo1_mixer },
7957                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
7958                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7959                 .dac_nids = alc262_dac_nids,
7960                 .hp_nid = 0x02,
7961                 .dig_out_nid = ALC262_DIGOUT_NID,
7962                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7963                 .channel_mode = alc262_modes,
7964                 .input_mux = &alc262_capture_source,
7965                 .unsol_event = alc262_hippo1_unsol_event,
7966         },
7967         [ALC262_FUJITSU] = {
7968                 .mixers = { alc262_fujitsu_mixer },
7969                 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
7970                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7971                 .dac_nids = alc262_dac_nids,
7972                 .hp_nid = 0x03,
7973                 .dig_out_nid = ALC262_DIGOUT_NID,
7974                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7975                 .channel_mode = alc262_modes,
7976                 .input_mux = &alc262_fujitsu_capture_source,
7977                 .unsol_event = alc262_fujitsu_unsol_event,
7978         },
7979         [ALC262_HP_BPC] = {
7980                 .mixers = { alc262_HP_BPC_mixer },
7981                 .init_verbs = { alc262_HP_BPC_init_verbs },
7982                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7983                 .dac_nids = alc262_dac_nids,
7984                 .hp_nid = 0x03,
7985                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7986                 .channel_mode = alc262_modes,
7987                 .input_mux = &alc262_HP_capture_source,
7988         },
7989         [ALC262_HP_BPC_D7000_WF] = {
7990                 .mixers = { alc262_HP_BPC_WildWest_mixer },
7991                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7992                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7993                 .dac_nids = alc262_dac_nids,
7994                 .hp_nid = 0x03,
7995                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7996                 .channel_mode = alc262_modes,
7997                 .input_mux = &alc262_HP_capture_source,
7998         },
7999         [ALC262_HP_BPC_D7000_WL] = {
8000                 .mixers = { alc262_HP_BPC_WildWest_mixer,
8001                             alc262_HP_BPC_WildWest_option_mixer },
8002                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8003                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8004                 .dac_nids = alc262_dac_nids,
8005                 .hp_nid = 0x03,
8006                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8007                 .channel_mode = alc262_modes,
8008                 .input_mux = &alc262_HP_capture_source,
8009         },
8010         [ALC262_BENQ_ED8] = {
8011                 .mixers = { alc262_base_mixer },
8012                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8013                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8014                 .dac_nids = alc262_dac_nids,
8015                 .hp_nid = 0x03,
8016                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8017                 .channel_mode = alc262_modes,
8018                 .input_mux = &alc262_capture_source,
8019         },
8020         [ALC262_SONY_ASSAMD] = {
8021                 .mixers = { alc262_sony_mixer },
8022                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8023                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8024                 .dac_nids = alc262_dac_nids,
8025                 .hp_nid = 0x02,
8026                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8027                 .channel_mode = alc262_modes,
8028                 .input_mux = &alc262_capture_source,
8029                 .unsol_event = alc262_hippo_unsol_event,
8030         },
8031         [ALC262_BENQ_T31] = {
8032                 .mixers = { alc262_benq_t31_mixer },
8033                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8034                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8035                 .dac_nids = alc262_dac_nids,
8036                 .hp_nid = 0x03,
8037                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8038                 .channel_mode = alc262_modes,
8039                 .input_mux = &alc262_capture_source,
8040                 .unsol_event = alc262_hippo_unsol_event,
8041         },      
8042 };
8043
8044 static int patch_alc262(struct hda_codec *codec)
8045 {
8046         struct alc_spec *spec;
8047         int board_config;
8048         int err;
8049
8050         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8051         if (spec == NULL)
8052                 return -ENOMEM;
8053
8054         codec->spec = spec;
8055 #if 0
8056         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8057          * under-run
8058          */
8059         {
8060         int tmp;
8061         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8062         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8063         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8064         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8065         }
8066 #endif
8067
8068         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8069                                                   alc262_models,
8070                                                   alc262_cfg_tbl);
8071
8072         if (board_config < 0) {
8073                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8074                        "trying auto-probe from BIOS...\n");
8075                 board_config = ALC262_AUTO;
8076         }
8077
8078         if (board_config == ALC262_AUTO) {
8079                 /* automatic parse from the BIOS config */
8080                 err = alc262_parse_auto_config(codec);
8081                 if (err < 0) {
8082                         alc_free(codec);
8083                         return err;
8084                 } else if (!err) {
8085                         printk(KERN_INFO
8086                                "hda_codec: Cannot set up configuration "
8087                                "from BIOS.  Using base mode...\n");
8088                         board_config = ALC262_BASIC;
8089                 }
8090         }
8091
8092         if (board_config != ALC262_AUTO)
8093                 setup_preset(spec, &alc262_presets[board_config]);
8094
8095         spec->stream_name_analog = "ALC262 Analog";
8096         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8097         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8098                 
8099         spec->stream_name_digital = "ALC262 Digital";
8100         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8101         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8102
8103         if (!spec->adc_nids && spec->input_mux) {
8104                 /* check whether NID 0x07 is valid */
8105                 unsigned int wcap = get_wcaps(codec, 0x07);
8106
8107                 /* get type */
8108                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8109                 if (wcap != AC_WID_AUD_IN) {
8110                         spec->adc_nids = alc262_adc_nids_alt;
8111                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8112                         spec->mixers[spec->num_mixers] =
8113                                 alc262_capture_alt_mixer;
8114                         spec->num_mixers++;
8115                 } else {
8116                         spec->adc_nids = alc262_adc_nids;
8117                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8118                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8119                         spec->num_mixers++;
8120                 }
8121         }
8122
8123         codec->patch_ops = alc_patch_ops;
8124         if (board_config == ALC262_AUTO)
8125                 spec->init_hook = alc262_auto_init;
8126                 
8127         return 0;
8128 }
8129
8130 /*
8131  *  ALC268 channel source setting (2 channel)
8132  */
8133 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8134 #define alc268_modes            alc260_modes
8135         
8136 static hda_nid_t alc268_dac_nids[2] = {
8137         /* front, hp */
8138         0x02, 0x03
8139 };
8140
8141 static hda_nid_t alc268_adc_nids[2] = {
8142         /* ADC0-1 */
8143         0x08, 0x07
8144 };
8145
8146 static hda_nid_t alc268_adc_nids_alt[1] = {
8147         /* ADC0 */
8148         0x08
8149 };
8150
8151 static struct snd_kcontrol_new alc268_base_mixer[] = {
8152         /* output mixer control */
8153         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8154         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8155         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8156         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8157         { }
8158 };
8159
8160 /*
8161  * generic initialization of ADC, input mixers and output mixers
8162  */
8163 static struct hda_verb alc268_base_init_verbs[] = {
8164         /* Unmute DAC0-1 and set vol = 0 */
8165         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8166         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8167         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8168         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8169         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8170         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8171
8172         /*
8173          * Set up output mixers (0x0c - 0x0e)
8174          */
8175         /* set vol=0 to output mixers */
8176         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8177         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8178         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8179         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8180
8181         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8182         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8183
8184         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8185         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8186         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8187         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8188         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8189         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8190         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8191         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8192
8193         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8194         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8195         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8196         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8197         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8198         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8199         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8200         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8201
8202         /* FIXME: use matrix-type input source selection */
8203         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8204         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8205         /* Input mixer2 */
8206         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8207         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8208         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8209         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8210
8211         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8212         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8213         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8214         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8215         { }
8216 };
8217
8218 /*
8219  * generic initialization of ADC, input mixers and output mixers
8220  */
8221 static struct hda_verb alc268_volume_init_verbs[] = {
8222         /* set output DAC */
8223         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8224         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8225         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8226         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8227
8228         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8229         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8230         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8231         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8232         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8233
8234         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8235         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8236         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8237         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8238         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8239
8240         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8241         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8242         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8243         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8244
8245         /* set PCBEEP vol = 0 */
8246         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8247
8248         { }
8249 };
8250
8251 #define alc268_mux_enum_info alc_mux_enum_info
8252 #define alc268_mux_enum_get alc_mux_enum_get
8253
8254 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8255                                struct snd_ctl_elem_value *ucontrol)
8256 {
8257         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8258         struct alc_spec *spec = codec->spec;
8259         const struct hda_input_mux *imux = spec->input_mux;
8260         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8261         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8262         hda_nid_t nid = capture_mixers[adc_idx];
8263         unsigned int *cur_val = &spec->cur_mux[adc_idx];
8264         unsigned int i, idx;
8265
8266         idx = ucontrol->value.enumerated.item[0];
8267         if (idx >= imux->num_items)
8268                 idx = imux->num_items - 1;
8269         if (*cur_val == idx && !codec->in_resume)
8270                 return 0;
8271         for (i = 0; i < imux->num_items; i++) {
8272                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8273                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8274                                     v | (imux->items[i].index << 8));
8275                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
8276                                     idx );
8277         }
8278         *cur_val = idx;
8279         return 1;
8280 }
8281
8282 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8283         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8284         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8285         {
8286                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8287                 /* The multiple "Capture Source" controls confuse alsamixer
8288                  * So call somewhat different..
8289                  * FIXME: the controls appear in the "playback" view!
8290                  */
8291                 /* .name = "Capture Source", */
8292                 .name = "Input Source",
8293                 .count = 1,
8294                 .info = alc268_mux_enum_info,
8295                 .get = alc268_mux_enum_get,
8296                 .put = alc268_mux_enum_put,
8297         },
8298         { } /* end */
8299 };
8300
8301 static struct snd_kcontrol_new alc268_capture_mixer[] = {
8302         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8303         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8304         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8305         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8306         {
8307                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8308                 /* The multiple "Capture Source" controls confuse alsamixer
8309                  * So call somewhat different..
8310                  * FIXME: the controls appear in the "playback" view!
8311                  */
8312                 /* .name = "Capture Source", */
8313                 .name = "Input Source",
8314                 .count = 2,
8315                 .info = alc268_mux_enum_info,
8316                 .get = alc268_mux_enum_get,
8317                 .put = alc268_mux_enum_put,
8318         },
8319         { } /* end */
8320 };
8321
8322 static struct hda_input_mux alc268_capture_source = {
8323         .num_items = 4,
8324         .items = {
8325                 { "Mic", 0x0 },
8326                 { "Front Mic", 0x1 },
8327                 { "Line", 0x2 },
8328                 { "CD", 0x3 },
8329         },
8330 };
8331
8332 /* create input playback/capture controls for the given pin */
8333 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8334                                     const char *ctlname, int idx)
8335 {
8336         char name[32];
8337         int err;
8338
8339         sprintf(name, "%s Playback Volume", ctlname);
8340         if (nid == 0x14) {
8341                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8342                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8343                                                       HDA_OUTPUT));
8344                 if (err < 0)
8345                         return err;
8346         } else if (nid == 0x15) {
8347                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8348                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8349                                                       HDA_OUTPUT));
8350                 if (err < 0)
8351                         return err;
8352         } else
8353                 return -1;
8354         sprintf(name, "%s Playback Switch", ctlname);
8355         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8356                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8357         if (err < 0)
8358                 return err;
8359         return 0;
8360 }
8361
8362 /* add playback controls from the parsed DAC table */
8363 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8364                                              const struct auto_pin_cfg *cfg)
8365 {
8366         hda_nid_t nid;
8367         int err;
8368
8369         spec->multiout.num_dacs = 2;    /* only use one dac */
8370         spec->multiout.dac_nids = spec->private_dac_nids;
8371         spec->multiout.dac_nids[0] = 2;
8372         spec->multiout.dac_nids[1] = 3;
8373
8374         nid = cfg->line_out_pins[0];
8375         if (nid)
8376                 alc268_new_analog_output(spec, nid, "Front", 0);        
8377
8378         nid = cfg->speaker_pins[0];
8379         if (nid == 0x1d) {
8380                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8381                                   "Speaker Playback Volume",
8382                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8383                 if (err < 0)
8384                         return err;
8385         }
8386         nid = cfg->hp_pins[0];
8387         if (nid)
8388                 alc268_new_analog_output(spec, nid, "Headphone", 0);
8389
8390         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8391         if (nid == 0x16) {
8392                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8393                                   "Mono Playback Switch",
8394                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8395                 if (err < 0)
8396                         return err;
8397         }
8398         return 0;       
8399 }
8400
8401 /* create playback/capture controls for input pins */
8402 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8403                                                 const struct auto_pin_cfg *cfg)
8404 {
8405         struct hda_input_mux *imux = &spec->private_imux;
8406         int i, idx1;
8407
8408         for (i = 0; i < AUTO_PIN_LAST; i++) {
8409                 switch(cfg->input_pins[i]) {
8410                 case 0x18:
8411                         idx1 = 0;       /* Mic 1 */
8412                         break;
8413                 case 0x19:
8414                         idx1 = 1;       /* Mic 2 */
8415                         break;
8416                 case 0x1a:
8417                         idx1 = 2;       /* Line In */
8418                         break;
8419                 case 0x1c:      
8420                         idx1 = 3;       /* CD */
8421                         break;
8422                 default:
8423                         continue;
8424                 }
8425                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8426                 imux->items[imux->num_items].index = idx1;
8427                 imux->num_items++;      
8428         }
8429         return 0;
8430 }
8431
8432 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8433 {
8434         struct alc_spec *spec = codec->spec;
8435         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8436         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8437         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8438         unsigned int    dac_vol1, dac_vol2;
8439
8440         if (speaker_nid) {
8441                 snd_hda_codec_write(codec, speaker_nid, 0,
8442                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8443                 snd_hda_codec_write(codec, 0x0f, 0,
8444                                     AC_VERB_SET_AMP_GAIN_MUTE,
8445                                     AMP_IN_UNMUTE(1));
8446                 snd_hda_codec_write(codec, 0x10, 0,
8447                                     AC_VERB_SET_AMP_GAIN_MUTE,
8448                                     AMP_IN_UNMUTE(1));
8449         } else {
8450                 snd_hda_codec_write(codec, 0x0f, 0,
8451                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8452                 snd_hda_codec_write(codec, 0x10, 0,
8453                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8454         }
8455
8456         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
8457         if (line_nid == 0x14)   
8458                 dac_vol2 = AMP_OUT_ZERO;
8459         else if (line_nid == 0x15)
8460                 dac_vol1 = AMP_OUT_ZERO;
8461         if (hp_nid == 0x14)     
8462                 dac_vol2 = AMP_OUT_ZERO;
8463         else if (hp_nid == 0x15)
8464                 dac_vol1 = AMP_OUT_ZERO;
8465         if (line_nid != 0x16 || hp_nid != 0x16 ||
8466             spec->autocfg.line_out_pins[1] != 0x16 ||
8467             spec->autocfg.line_out_pins[2] != 0x16)
8468                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8469
8470         snd_hda_codec_write(codec, 0x02, 0,
8471                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8472         snd_hda_codec_write(codec, 0x03, 0,
8473                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8474 }
8475
8476 /* pcm configuration: identiacal with ALC880 */
8477 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
8478 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
8479 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
8480
8481 /*
8482  * BIOS auto configuration
8483  */
8484 static int alc268_parse_auto_config(struct hda_codec *codec)
8485 {
8486         struct alc_spec *spec = codec->spec;
8487         int err;
8488         static hda_nid_t alc268_ignore[] = { 0 };
8489
8490         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8491                                            alc268_ignore);
8492         if (err < 0)
8493                 return err;
8494         if (!spec->autocfg.line_outs)
8495                 return 0; /* can't find valid BIOS pin config */
8496
8497         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8498         if (err < 0)
8499                 return err;
8500         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8501         if (err < 0)
8502                 return err;
8503
8504         spec->multiout.max_channels = 2;
8505
8506         /* digital only support output */
8507         if (spec->autocfg.dig_out_pin)
8508                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8509
8510         if (spec->kctl_alloc)
8511                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8512
8513         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8514         spec->num_mux_defs = 1;
8515         spec->input_mux = &spec->private_imux;
8516
8517         return 1;
8518 }
8519
8520 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
8521 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
8522 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
8523
8524 /* init callback for auto-configuration model -- overriding the default init */
8525 static void alc268_auto_init(struct hda_codec *codec)
8526 {
8527         alc268_auto_init_multi_out(codec);
8528         alc268_auto_init_hp_out(codec);
8529         alc268_auto_init_mono_speaker_out(codec);
8530         alc268_auto_init_analog_input(codec);
8531 }
8532
8533 /*
8534  * configuration and preset
8535  */
8536 static const char *alc268_models[ALC268_MODEL_LAST] = {
8537         [ALC268_3ST]            = "3stack",
8538         [ALC268_AUTO]           = "auto",
8539 };
8540
8541 static struct snd_pci_quirk alc268_cfg_tbl[] = {
8542         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8543         {}
8544 };
8545
8546 static struct alc_config_preset alc268_presets[] = {
8547         [ALC268_3ST] = {
8548                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8549                 .init_verbs = { alc268_base_init_verbs },
8550                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8551                 .dac_nids = alc268_dac_nids,
8552                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8553                 .adc_nids = alc268_adc_nids_alt,
8554                 .hp_nid = 0x03,
8555                 .dig_out_nid = ALC268_DIGOUT_NID,
8556                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8557                 .channel_mode = alc268_modes,
8558                 .input_mux = &alc268_capture_source,
8559         },
8560 };
8561
8562 static int patch_alc268(struct hda_codec *codec)
8563 {
8564         struct alc_spec *spec;
8565         int board_config;
8566         int err;
8567
8568         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8569         if (spec == NULL)
8570                 return -ENOMEM;
8571
8572         codec->spec = spec;
8573
8574         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8575                                                   alc268_models,
8576                                                   alc268_cfg_tbl);
8577
8578         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8579                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8580                        "trying auto-probe from BIOS...\n");
8581                 board_config = ALC268_AUTO;
8582         }
8583
8584         if (board_config == ALC268_AUTO) {
8585                 /* automatic parse from the BIOS config */
8586                 err = alc268_parse_auto_config(codec);
8587                 if (err < 0) {
8588                         alc_free(codec);
8589                         return err;
8590                 } else if (!err) {
8591                         printk(KERN_INFO
8592                                "hda_codec: Cannot set up configuration "
8593                                "from BIOS.  Using base mode...\n");
8594                         board_config = ALC268_3ST;
8595                 }
8596         }
8597
8598         if (board_config != ALC268_AUTO)
8599                 setup_preset(spec, &alc268_presets[board_config]);
8600
8601         spec->stream_name_analog = "ALC268 Analog";
8602         spec->stream_analog_playback = &alc268_pcm_analog_playback;
8603         spec->stream_analog_capture = &alc268_pcm_analog_capture;
8604
8605         spec->stream_name_digital = "ALC268 Digital";
8606         spec->stream_digital_playback = &alc268_pcm_digital_playback;
8607
8608         if (board_config == ALC268_AUTO) {
8609                 if (!spec->adc_nids && spec->input_mux) {
8610                         /* check whether NID 0x07 is valid */
8611                         unsigned int wcap = get_wcaps(codec, 0x07);
8612
8613                         /* get type */
8614                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8615                         if (wcap != AC_WID_AUD_IN) {
8616                                 spec->adc_nids = alc268_adc_nids_alt;
8617                                 spec->num_adc_nids =
8618                                         ARRAY_SIZE(alc268_adc_nids_alt);
8619                                 spec->mixers[spec->num_mixers] =
8620                                         alc268_capture_alt_mixer;
8621                                 spec->num_mixers++;
8622                         } else {
8623                                 spec->adc_nids = alc268_adc_nids;
8624                                 spec->num_adc_nids =
8625                                         ARRAY_SIZE(alc268_adc_nids);
8626                                 spec->mixers[spec->num_mixers] =
8627                                         alc268_capture_mixer;
8628                                 spec->num_mixers++;
8629                         }
8630                 }
8631         }
8632         codec->patch_ops = alc_patch_ops;
8633         if (board_config == ALC268_AUTO)
8634                 spec->init_hook = alc268_auto_init;
8635                 
8636         return 0;
8637 }
8638
8639 /*
8640  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8641  */
8642
8643 /*
8644  * set the path ways for 2 channel output
8645  * need to set the codec line out and mic 1 pin widgets to inputs
8646  */
8647 static struct hda_verb alc861_threestack_ch2_init[] = {
8648         /* set pin widget 1Ah (line in) for input */
8649         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8650         /* set pin widget 18h (mic1/2) for input, for mic also enable
8651          * the vref
8652          */
8653         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8654
8655         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8656 #if 0
8657         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8658         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8659 #endif
8660         { } /* end */
8661 };
8662 /*
8663  * 6ch mode
8664  * need to set the codec line out and mic 1 pin widgets to outputs
8665  */
8666 static struct hda_verb alc861_threestack_ch6_init[] = {
8667         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8668         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8669         /* set pin widget 18h (mic1) for output (CLFE)*/
8670         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8671
8672         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8673         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8674
8675         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8676 #if 0
8677         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8678         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8679 #endif
8680         { } /* end */
8681 };
8682
8683 static struct hda_channel_mode alc861_threestack_modes[2] = {
8684         { 2, alc861_threestack_ch2_init },
8685         { 6, alc861_threestack_ch6_init },
8686 };
8687 /* Set mic1 as input and unmute the mixer */
8688 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8689         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8690         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8691         { } /* end */
8692 };
8693 /* Set mic1 as output and mute mixer */
8694 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8695         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8696         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8697         { } /* end */
8698 };
8699
8700 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8701         { 2, alc861_uniwill_m31_ch2_init },
8702         { 4, alc861_uniwill_m31_ch4_init },
8703 };
8704
8705 /* Set mic1 and line-in as input and unmute the mixer */
8706 static struct hda_verb alc861_asus_ch2_init[] = {
8707         /* set pin widget 1Ah (line in) for input */
8708         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8709         /* set pin widget 18h (mic1/2) for input, for mic also enable
8710          * the vref
8711          */
8712         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8713
8714         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8715 #if 0
8716         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8717         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8718 #endif
8719         { } /* end */
8720 };
8721 /* Set mic1 nad line-in as output and mute mixer */
8722 static struct hda_verb alc861_asus_ch6_init[] = {
8723         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8724         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8725         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8726         /* set pin widget 18h (mic1) for output (CLFE)*/
8727         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8728         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8729         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8730         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8731
8732         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8733 #if 0
8734         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8735         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8736 #endif
8737         { } /* end */
8738 };
8739
8740 static struct hda_channel_mode alc861_asus_modes[2] = {
8741         { 2, alc861_asus_ch2_init },
8742         { 6, alc861_asus_ch6_init },
8743 };
8744
8745 /* patch-ALC861 */
8746
8747 static struct snd_kcontrol_new alc861_base_mixer[] = {
8748         /* output mixer control */
8749         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8750         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8751         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8752         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8753         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8754
8755         /*Input mixer control */
8756         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8757            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8758         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8759         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8760         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8761         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8762         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8763         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8764         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8765         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8766
8767         /* Capture mixer control */
8768         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8769         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8770         {
8771                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8772                 .name = "Capture Source",
8773                 .count = 1,
8774                 .info = alc_mux_enum_info,
8775                 .get = alc_mux_enum_get,
8776                 .put = alc_mux_enum_put,
8777         },
8778         { } /* end */
8779 };
8780
8781 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8782         /* output mixer control */
8783         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8784         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8785         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8786         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8787         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8788
8789         /* Input mixer control */
8790         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8791            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8792         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8793         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8794         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8795         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8796         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8797         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8798         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8799         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8800
8801         /* Capture mixer control */
8802         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8803         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8804         {
8805                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8806                 .name = "Capture Source",
8807                 .count = 1,
8808                 .info = alc_mux_enum_info,
8809                 .get = alc_mux_enum_get,
8810                 .put = alc_mux_enum_put,
8811         },
8812         {
8813                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8814                 .name = "Channel Mode",
8815                 .info = alc_ch_mode_info,
8816                 .get = alc_ch_mode_get,
8817                 .put = alc_ch_mode_put,
8818                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
8819         },
8820         { } /* end */
8821 };
8822
8823 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8824         /* output mixer control */
8825         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8826         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8827         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8828         
8829         /*Capture mixer control */
8830         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8831         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8832         {
8833                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8834                 .name = "Capture Source",
8835                 .count = 1,
8836                 .info = alc_mux_enum_info,
8837                 .get = alc_mux_enum_get,
8838                 .put = alc_mux_enum_put,
8839         },
8840
8841         { } /* end */
8842 };
8843
8844 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8845         /* output mixer control */
8846         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8847         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8848         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8849         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8850         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8851
8852         /* Input mixer control */
8853         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8854            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8855         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8856         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8857         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8858         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8859         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8860         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8861         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8862         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8863
8864         /* Capture mixer control */
8865         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8866         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8867         {
8868                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8869                 .name = "Capture Source",
8870                 .count = 1,
8871                 .info = alc_mux_enum_info,
8872                 .get = alc_mux_enum_get,
8873                 .put = alc_mux_enum_put,
8874         },
8875         {
8876                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8877                 .name = "Channel Mode",
8878                 .info = alc_ch_mode_info,
8879                 .get = alc_ch_mode_get,
8880                 .put = alc_ch_mode_put,
8881                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8882         },
8883         { } /* end */
8884 };
8885
8886 static struct snd_kcontrol_new alc861_asus_mixer[] = {
8887         /* output mixer control */
8888         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8889         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8890         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8891         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8892         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8893
8894         /* Input mixer control */
8895         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8896         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8897         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8898         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8899         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8900         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8901         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8902         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8903         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8904         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
8905
8906         /* Capture mixer control */
8907         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8908         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8909         {
8910                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8911                 .name = "Capture Source",
8912                 .count = 1,
8913                 .info = alc_mux_enum_info,
8914                 .get = alc_mux_enum_get,
8915                 .put = alc_mux_enum_put,
8916         },
8917         {
8918                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8919                 .name = "Channel Mode",
8920                 .info = alc_ch_mode_info,
8921                 .get = alc_ch_mode_get,
8922                 .put = alc_ch_mode_put,
8923                 .private_value = ARRAY_SIZE(alc861_asus_modes),
8924         },
8925         { }
8926 };
8927
8928 /* additional mixer */
8929 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
8930         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8931         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8932         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
8933         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
8934         { }
8935 };
8936
8937 /*
8938  * generic initialization of ADC, input mixers and output mixers
8939  */
8940 static struct hda_verb alc861_base_init_verbs[] = {
8941         /*
8942          * Unmute ADC0 and set the default input to mic-in
8943          */
8944         /* port-A for surround (rear panel) */
8945         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8946         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
8947         /* port-B for mic-in (rear panel) with vref */
8948         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8949         /* port-C for line-in (rear panel) */
8950         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8951         /* port-D for Front */
8952         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8953         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8954         /* port-E for HP out (front panel) */
8955         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8956         /* route front PCM to HP */
8957         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8958         /* port-F for mic-in (front panel) with vref */
8959         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8960         /* port-G for CLFE (rear panel) */
8961         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8962         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8963         /* port-H for side (rear panel) */
8964         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8965         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
8966         /* CD-in */
8967         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8968         /* route front mic to ADC1*/
8969         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8970         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8971         
8972         /* Unmute DAC0~3 & spdif out*/
8973         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8974         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8975         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8976         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8977         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8978         
8979         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8980         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8981         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8982         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8983         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8984         
8985         /* Unmute Stereo Mixer 15 */
8986         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8987         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8988         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8989         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8990
8991         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8992         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8993         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8994         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8995         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8996         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8997         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8998         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8999         /* hp used DAC 3 (Front) */
9000         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9001         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9002
9003         { }
9004 };
9005
9006 static struct hda_verb alc861_threestack_init_verbs[] = {
9007         /*
9008          * Unmute ADC0 and set the default input to mic-in
9009          */
9010         /* port-A for surround (rear panel) */
9011         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9012         /* port-B for mic-in (rear panel) with vref */
9013         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9014         /* port-C for line-in (rear panel) */
9015         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9016         /* port-D for Front */
9017         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9018         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9019         /* port-E for HP out (front panel) */
9020         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9021         /* route front PCM to HP */
9022         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9023         /* port-F for mic-in (front panel) with vref */
9024         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9025         /* port-G for CLFE (rear panel) */
9026         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9027         /* port-H for side (rear panel) */
9028         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9029         /* CD-in */
9030         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9031         /* route front mic to ADC1*/
9032         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9033         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9034         /* Unmute DAC0~3 & spdif out*/
9035         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9036         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9037         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9038         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9039         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9040         
9041         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9042         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9043         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9044         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9045         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9046         
9047         /* Unmute Stereo Mixer 15 */
9048         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9049         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9050         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9051         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9052
9053         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9054         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9055         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9056         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9057         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9058         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9059         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9060         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9061         /* hp used DAC 3 (Front) */
9062         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9063         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9064         { }
9065 };
9066
9067 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9068         /*
9069          * Unmute ADC0 and set the default input to mic-in
9070          */
9071         /* port-A for surround (rear panel) */
9072         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9073         /* port-B for mic-in (rear panel) with vref */
9074         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9075         /* port-C for line-in (rear panel) */
9076         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9077         /* port-D for Front */
9078         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9079         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9080         /* port-E for HP out (front panel) */
9081         /* this has to be set to VREF80 */
9082         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9083         /* route front PCM to HP */
9084         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9085         /* port-F for mic-in (front panel) with vref */
9086         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9087         /* port-G for CLFE (rear panel) */
9088         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9089         /* port-H for side (rear panel) */
9090         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9091         /* CD-in */
9092         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9093         /* route front mic to ADC1*/
9094         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9095         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9096         /* Unmute DAC0~3 & spdif out*/
9097         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9098         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9099         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9100         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9101         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9102         
9103         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9104         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9105         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9106         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9107         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9108         
9109         /* Unmute Stereo Mixer 15 */
9110         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9111         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9112         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9113         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9114
9115         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9116         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9117         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9118         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9119         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9120         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9121         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9122         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9123         /* hp used DAC 3 (Front) */
9124         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9125         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9126         { }
9127 };
9128
9129 static struct hda_verb alc861_asus_init_verbs[] = {
9130         /*
9131          * Unmute ADC0 and set the default input to mic-in
9132          */
9133         /* port-A for surround (rear panel)
9134          * according to codec#0 this is the HP jack
9135          */
9136         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9137         /* route front PCM to HP */
9138         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9139         /* port-B for mic-in (rear panel) with vref */
9140         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9141         /* port-C for line-in (rear panel) */
9142         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9143         /* port-D for Front */
9144         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9145         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9146         /* port-E for HP out (front panel) */
9147         /* this has to be set to VREF80 */
9148         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9149         /* route front PCM to HP */
9150         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9151         /* port-F for mic-in (front panel) with vref */
9152         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9153         /* port-G for CLFE (rear panel) */
9154         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9155         /* port-H for side (rear panel) */
9156         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9157         /* CD-in */
9158         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9159         /* route front mic to ADC1*/
9160         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9161         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9162         /* Unmute DAC0~3 & spdif out*/
9163         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9164         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9165         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9166         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9167         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9168         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9169         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9170         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9171         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9172         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9173         
9174         /* Unmute Stereo Mixer 15 */
9175         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9176         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9177         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9178         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9179
9180         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9181         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9182         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9183         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9184         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9185         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9186         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9187         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9188         /* hp used DAC 3 (Front) */
9189         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9190         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9191         { }
9192 };
9193
9194 /* additional init verbs for ASUS laptops */
9195 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9196         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9197         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9198         { }
9199 };
9200
9201 /*
9202  * generic initialization of ADC, input mixers and output mixers
9203  */
9204 static struct hda_verb alc861_auto_init_verbs[] = {
9205         /*
9206          * Unmute ADC0 and set the default input to mic-in
9207          */
9208         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9209         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9210         
9211         /* Unmute DAC0~3 & spdif out*/
9212         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9213         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9214         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9215         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9216         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9217         
9218         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9219         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9220         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9221         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9222         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9223         
9224         /* Unmute Stereo Mixer 15 */
9225         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9226         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9227         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9228         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9229
9230         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9231         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9232         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9233         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9234         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9235         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9236         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9237         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9238
9239         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9240         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9241         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9242         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9243         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9244         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9245         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9246         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9247
9248         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
9249
9250         { }
9251 };
9252
9253 static struct hda_verb alc861_toshiba_init_verbs[] = {
9254         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9255
9256         { }
9257 };
9258
9259 /* toggle speaker-output according to the hp-jack state */
9260 static void alc861_toshiba_automute(struct hda_codec *codec)
9261 {
9262         unsigned int present;
9263
9264         present = snd_hda_codec_read(codec, 0x0f, 0,
9265                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9266         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
9267                                  0x80, present ? 0x80 : 0);
9268         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
9269                                  0x80, present ? 0x80 : 0);
9270         snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
9271                                  0x80, present ? 0 : 0x80);
9272         snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
9273                                  0x80, present ? 0 : 0x80);
9274 }
9275
9276 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9277                                        unsigned int res)
9278 {
9279         if ((res >> 26) == ALC880_HP_EVENT)
9280                 alc861_toshiba_automute(codec);
9281 }
9282
9283 /* pcm configuration: identiacal with ALC880 */
9284 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
9285 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
9286 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
9287 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
9288
9289
9290 #define ALC861_DIGOUT_NID       0x07
9291
9292 static struct hda_channel_mode alc861_8ch_modes[1] = {
9293         { 8, NULL }
9294 };
9295
9296 static hda_nid_t alc861_dac_nids[4] = {
9297         /* front, surround, clfe, side */
9298         0x03, 0x06, 0x05, 0x04
9299 };
9300
9301 static hda_nid_t alc660_dac_nids[3] = {
9302         /* front, clfe, surround */
9303         0x03, 0x05, 0x06
9304 };
9305
9306 static hda_nid_t alc861_adc_nids[1] = {
9307         /* ADC0-2 */
9308         0x08,
9309 };
9310
9311 static struct hda_input_mux alc861_capture_source = {
9312         .num_items = 5,
9313         .items = {
9314                 { "Mic", 0x0 },
9315                 { "Front Mic", 0x3 },
9316                 { "Line", 0x1 },
9317                 { "CD", 0x4 },
9318                 { "Mixer", 0x5 },
9319         },
9320 };
9321
9322 /* fill in the dac_nids table from the parsed pin configuration */
9323 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9324                                      const struct auto_pin_cfg *cfg)
9325 {
9326         int i;
9327         hda_nid_t nid;
9328
9329         spec->multiout.dac_nids = spec->private_dac_nids;
9330         for (i = 0; i < cfg->line_outs; i++) {
9331                 nid = cfg->line_out_pins[i];
9332                 if (nid) {
9333                         if (i >= ARRAY_SIZE(alc861_dac_nids))
9334                                 continue;
9335                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9336                 }
9337         }
9338         spec->multiout.num_dacs = cfg->line_outs;
9339         return 0;
9340 }
9341
9342 /* add playback controls from the parsed DAC table */
9343 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9344                                              const struct auto_pin_cfg *cfg)
9345 {
9346         char name[32];
9347         static const char *chname[4] = {
9348                 "Front", "Surround", NULL /*CLFE*/, "Side"
9349         };
9350         hda_nid_t nid;
9351         int i, idx, err;
9352
9353         for (i = 0; i < cfg->line_outs; i++) {
9354                 nid = spec->multiout.dac_nids[i];
9355                 if (!nid)
9356                         continue;
9357                 if (nid == 0x05) {
9358                         /* Center/LFE */
9359                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9360                                           "Center Playback Switch",
9361                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9362                                                               HDA_OUTPUT));
9363                         if (err < 0)
9364                                 return err;
9365                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9366                                           "LFE Playback Switch",
9367                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9368                                                               HDA_OUTPUT));
9369                         if (err < 0)
9370                                 return err;
9371                 } else {
9372                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9373                              idx++)
9374                                 if (nid == alc861_dac_nids[idx])
9375                                         break;
9376                         sprintf(name, "%s Playback Switch", chname[idx]);
9377                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9378                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9379                                                               HDA_OUTPUT));
9380                         if (err < 0)
9381                                 return err;
9382                 }
9383         }
9384         return 0;
9385 }
9386
9387 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9388 {
9389         int err;
9390         hda_nid_t nid;
9391
9392         if (!pin)
9393                 return 0;
9394
9395         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9396                 nid = 0x03;
9397                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9398                                   "Headphone Playback Switch",
9399                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9400                 if (err < 0)
9401                         return err;
9402                 spec->multiout.hp_nid = nid;
9403         }
9404         return 0;
9405 }
9406
9407 /* create playback/capture controls for input pins */
9408 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9409                                                 const struct auto_pin_cfg *cfg)
9410 {
9411         struct hda_input_mux *imux = &spec->private_imux;
9412         int i, err, idx, idx1;
9413
9414         for (i = 0; i < AUTO_PIN_LAST; i++) {
9415                 switch (cfg->input_pins[i]) {
9416                 case 0x0c:
9417                         idx1 = 1;
9418                         idx = 2;        /* Line In */
9419                         break;
9420                 case 0x0f:
9421                         idx1 = 2;
9422                         idx = 2;        /* Line In */
9423                         break;
9424                 case 0x0d:
9425                         idx1 = 0;
9426                         idx = 1;        /* Mic In */
9427                         break;
9428                 case 0x10:
9429                         idx1 = 3;
9430                         idx = 1;        /* Mic In */
9431                         break;
9432                 case 0x11:
9433                         idx1 = 4;
9434                         idx = 0;        /* CD */
9435                         break;
9436                 default:
9437                         continue;
9438                 }
9439
9440                 err = new_analog_input(spec, cfg->input_pins[i],
9441                                        auto_pin_cfg_labels[i], idx, 0x15);
9442                 if (err < 0)
9443                         return err;
9444
9445                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9446                 imux->items[imux->num_items].index = idx1;
9447                 imux->num_items++;
9448         }
9449         return 0;
9450 }
9451
9452 static struct snd_kcontrol_new alc861_capture_mixer[] = {
9453         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9454         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9455
9456         {
9457                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9458                 /* The multiple "Capture Source" controls confuse alsamixer
9459                  * So call somewhat different..
9460                  *FIXME: the controls appear in the "playback" view!
9461                  */
9462                 /* .name = "Capture Source", */
9463                 .name = "Input Source",
9464                 .count = 1,
9465                 .info = alc_mux_enum_info,
9466                 .get = alc_mux_enum_get,
9467                 .put = alc_mux_enum_put,
9468         },
9469         { } /* end */
9470 };
9471
9472 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9473                                               hda_nid_t nid,
9474                                               int pin_type, int dac_idx)
9475 {
9476         /* set as output */
9477
9478         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9479                             pin_type);
9480         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9481                             AMP_OUT_UNMUTE);
9482
9483 }
9484
9485 static void alc861_auto_init_multi_out(struct hda_codec *codec)
9486 {
9487         struct alc_spec *spec = codec->spec;
9488         int i;
9489
9490         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9491         for (i = 0; i < spec->autocfg.line_outs; i++) {
9492                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9493                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9494                 if (nid)
9495                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9496                                                           spec->multiout.dac_nids[i]);
9497         }
9498 }
9499
9500 static void alc861_auto_init_hp_out(struct hda_codec *codec)
9501 {
9502         struct alc_spec *spec = codec->spec;
9503         hda_nid_t pin;
9504
9505         pin = spec->autocfg.hp_pins[0];
9506         if (pin) /* connect to front */
9507                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9508                                                   spec->multiout.dac_nids[0]);
9509 }
9510
9511 static void alc861_auto_init_analog_input(struct hda_codec *codec)
9512 {
9513         struct alc_spec *spec = codec->spec;
9514         int i;
9515
9516         for (i = 0; i < AUTO_PIN_LAST; i++) {
9517                 hda_nid_t nid = spec->autocfg.input_pins[i];
9518                 if (nid >= 0x0c && nid <= 0x11) {
9519                         snd_hda_codec_write(codec, nid, 0,
9520                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
9521                                             i <= AUTO_PIN_FRONT_MIC ?
9522                                             PIN_VREF80 : PIN_IN);
9523                 }
9524         }
9525 }
9526
9527 /* parse the BIOS configuration and set up the alc_spec */
9528 /* return 1 if successful, 0 if the proper config is not found,
9529  * or a negative error code
9530  */
9531 static int alc861_parse_auto_config(struct hda_codec *codec)
9532 {
9533         struct alc_spec *spec = codec->spec;
9534         int err;
9535         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9536
9537         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9538                                            alc861_ignore);
9539         if (err < 0)
9540                 return err;
9541         if (!spec->autocfg.line_outs)
9542                 return 0; /* can't find valid BIOS pin config */
9543
9544         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9545         if (err < 0)
9546                 return err;
9547         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9548         if (err < 0)
9549                 return err;
9550         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9551         if (err < 0)
9552                 return err;
9553         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9554         if (err < 0)
9555                 return err;
9556
9557         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9558
9559         if (spec->autocfg.dig_out_pin)
9560                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9561
9562         if (spec->kctl_alloc)
9563                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9564
9565         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9566
9567         spec->num_mux_defs = 1;
9568         spec->input_mux = &spec->private_imux;
9569
9570         spec->adc_nids = alc861_adc_nids;
9571         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9572         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9573         spec->num_mixers++;
9574
9575         return 1;
9576 }
9577
9578 /* additional initialization for auto-configuration model */
9579 static void alc861_auto_init(struct hda_codec *codec)
9580 {
9581         alc861_auto_init_multi_out(codec);
9582         alc861_auto_init_hp_out(codec);
9583         alc861_auto_init_analog_input(codec);
9584 }
9585
9586
9587 /*
9588  * configuration and preset
9589  */
9590 static const char *alc861_models[ALC861_MODEL_LAST] = {
9591         [ALC861_3ST]            = "3stack",
9592         [ALC660_3ST]            = "3stack-660",
9593         [ALC861_3ST_DIG]        = "3stack-dig",
9594         [ALC861_6ST_DIG]        = "6stack-dig",
9595         [ALC861_UNIWILL_M31]    = "uniwill-m31",
9596         [ALC861_TOSHIBA]        = "toshiba",
9597         [ALC861_ASUS]           = "asus",
9598         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
9599         [ALC861_AUTO]           = "auto",
9600 };
9601
9602 static struct snd_pci_quirk alc861_cfg_tbl[] = {
9603         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9604         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9605         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9606         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9607         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9608         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9609         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9610         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9611         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9612          *        Any other models that need this preset?
9613          */
9614         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9615         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9616         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9617         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9618         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9619         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9620         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9621         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9622         {}
9623 };
9624
9625 static struct alc_config_preset alc861_presets[] = {
9626         [ALC861_3ST] = {
9627                 .mixers = { alc861_3ST_mixer },
9628                 .init_verbs = { alc861_threestack_init_verbs },
9629                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9630                 .dac_nids = alc861_dac_nids,
9631                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9632                 .channel_mode = alc861_threestack_modes,
9633                 .need_dac_fix = 1,
9634                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9635                 .adc_nids = alc861_adc_nids,
9636                 .input_mux = &alc861_capture_source,
9637         },
9638         [ALC861_3ST_DIG] = {
9639                 .mixers = { alc861_base_mixer },
9640                 .init_verbs = { alc861_threestack_init_verbs },
9641                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9642                 .dac_nids = alc861_dac_nids,
9643                 .dig_out_nid = ALC861_DIGOUT_NID,
9644                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9645                 .channel_mode = alc861_threestack_modes,
9646                 .need_dac_fix = 1,
9647                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9648                 .adc_nids = alc861_adc_nids,
9649                 .input_mux = &alc861_capture_source,
9650         },
9651         [ALC861_6ST_DIG] = {
9652                 .mixers = { alc861_base_mixer },
9653                 .init_verbs = { alc861_base_init_verbs },
9654                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9655                 .dac_nids = alc861_dac_nids,
9656                 .dig_out_nid = ALC861_DIGOUT_NID,
9657                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9658                 .channel_mode = alc861_8ch_modes,
9659                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9660                 .adc_nids = alc861_adc_nids,
9661                 .input_mux = &alc861_capture_source,
9662         },
9663         [ALC660_3ST] = {
9664                 .mixers = { alc861_3ST_mixer },
9665                 .init_verbs = { alc861_threestack_init_verbs },
9666                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
9667                 .dac_nids = alc660_dac_nids,
9668                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9669                 .channel_mode = alc861_threestack_modes,
9670                 .need_dac_fix = 1,
9671                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9672                 .adc_nids = alc861_adc_nids,
9673                 .input_mux = &alc861_capture_source,
9674         },
9675         [ALC861_UNIWILL_M31] = {
9676                 .mixers = { alc861_uniwill_m31_mixer },
9677                 .init_verbs = { alc861_uniwill_m31_init_verbs },
9678                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9679                 .dac_nids = alc861_dac_nids,
9680                 .dig_out_nid = ALC861_DIGOUT_NID,
9681                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9682                 .channel_mode = alc861_uniwill_m31_modes,
9683                 .need_dac_fix = 1,
9684                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9685                 .adc_nids = alc861_adc_nids,
9686                 .input_mux = &alc861_capture_source,
9687         },
9688         [ALC861_TOSHIBA] = {
9689                 .mixers = { alc861_toshiba_mixer },
9690                 .init_verbs = { alc861_base_init_verbs,
9691                                 alc861_toshiba_init_verbs },
9692                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9693                 .dac_nids = alc861_dac_nids,
9694                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9695                 .channel_mode = alc883_3ST_2ch_modes,
9696                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9697                 .adc_nids = alc861_adc_nids,
9698                 .input_mux = &alc861_capture_source,
9699                 .unsol_event = alc861_toshiba_unsol_event,
9700                 .init_hook = alc861_toshiba_automute,
9701         },
9702         [ALC861_ASUS] = {
9703                 .mixers = { alc861_asus_mixer },
9704                 .init_verbs = { alc861_asus_init_verbs },
9705                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9706                 .dac_nids = alc861_dac_nids,
9707                 .dig_out_nid = ALC861_DIGOUT_NID,
9708                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9709                 .channel_mode = alc861_asus_modes,
9710                 .need_dac_fix = 1,
9711                 .hp_nid = 0x06,
9712                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9713                 .adc_nids = alc861_adc_nids,
9714                 .input_mux = &alc861_capture_source,
9715         },
9716         [ALC861_ASUS_LAPTOP] = {
9717                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9718                 .init_verbs = { alc861_asus_init_verbs,
9719                                 alc861_asus_laptop_init_verbs },
9720                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9721                 .dac_nids = alc861_dac_nids,
9722                 .dig_out_nid = ALC861_DIGOUT_NID,
9723                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9724                 .channel_mode = alc883_3ST_2ch_modes,
9725                 .need_dac_fix = 1,
9726                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9727                 .adc_nids = alc861_adc_nids,
9728                 .input_mux = &alc861_capture_source,
9729         },
9730 };
9731
9732
9733 static int patch_alc861(struct hda_codec *codec)
9734 {
9735         struct alc_spec *spec;
9736         int board_config;
9737         int err;
9738
9739         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9740         if (spec == NULL)
9741                 return -ENOMEM;
9742
9743         codec->spec = spec;
9744
9745         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9746                                                   alc861_models,
9747                                                   alc861_cfg_tbl);
9748
9749         if (board_config < 0) {
9750                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9751                        "trying auto-probe from BIOS...\n");
9752                 board_config = ALC861_AUTO;
9753         }
9754
9755         if (board_config == ALC861_AUTO) {
9756                 /* automatic parse from the BIOS config */
9757                 err = alc861_parse_auto_config(codec);
9758                 if (err < 0) {
9759                         alc_free(codec);
9760                         return err;
9761                 } else if (!err) {
9762                         printk(KERN_INFO
9763                                "hda_codec: Cannot set up configuration "
9764                                "from BIOS.  Using base mode...\n");
9765                    board_config = ALC861_3ST_DIG;
9766                 }
9767         }
9768
9769         if (board_config != ALC861_AUTO)
9770                 setup_preset(spec, &alc861_presets[board_config]);
9771
9772         spec->stream_name_analog = "ALC861 Analog";
9773         spec->stream_analog_playback = &alc861_pcm_analog_playback;
9774         spec->stream_analog_capture = &alc861_pcm_analog_capture;
9775
9776         spec->stream_name_digital = "ALC861 Digital";
9777         spec->stream_digital_playback = &alc861_pcm_digital_playback;
9778         spec->stream_digital_capture = &alc861_pcm_digital_capture;
9779
9780         codec->patch_ops = alc_patch_ops;
9781         if (board_config == ALC861_AUTO)
9782                 spec->init_hook = alc861_auto_init;
9783                 
9784         return 0;
9785 }
9786
9787 /*
9788  * ALC861-VD support
9789  *
9790  * Based on ALC882
9791  *
9792  * In addition, an independent DAC
9793  */
9794 #define ALC861VD_DIGOUT_NID     0x06
9795
9796 static hda_nid_t alc861vd_dac_nids[4] = {
9797         /* front, surr, clfe, side surr */
9798         0x02, 0x03, 0x04, 0x05
9799 };
9800
9801 /* dac_nids for ALC660vd are in a different order - according to
9802  * Realtek's driver.
9803  * This should probably tesult in a different mixer for 6stack models
9804  * of ALC660vd codecs, but for now there is only 3stack mixer
9805  * - and it is the same as in 861vd.
9806  * adc_nids in ALC660vd are (is) the same as in 861vd
9807  */
9808 static hda_nid_t alc660vd_dac_nids[3] = {
9809         /* front, rear, clfe, rear_surr */
9810         0x02, 0x04, 0x03
9811 };
9812
9813 static hda_nid_t alc861vd_adc_nids[1] = {
9814         /* ADC0 */
9815         0x09,
9816 };
9817
9818 /* input MUX */
9819 /* FIXME: should be a matrix-type input source selection */
9820 static struct hda_input_mux alc861vd_capture_source = {
9821         .num_items = 4,
9822         .items = {
9823                 { "Mic", 0x0 },
9824                 { "Front Mic", 0x1 },
9825                 { "Line", 0x2 },
9826                 { "CD", 0x4 },
9827         },
9828 };
9829
9830 static struct hda_input_mux alc861vd_dallas_capture_source = {
9831         .num_items = 3,
9832         .items = {
9833                 { "Front Mic", 0x0 },
9834                 { "ATAPI Mic", 0x1 },
9835                 { "Line In", 0x5 },
9836         },
9837 };
9838
9839 #define alc861vd_mux_enum_info alc_mux_enum_info
9840 #define alc861vd_mux_enum_get alc_mux_enum_get
9841
9842 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9843                                 struct snd_ctl_elem_value *ucontrol)
9844 {
9845         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9846         struct alc_spec *spec = codec->spec;
9847         const struct hda_input_mux *imux = spec->input_mux;
9848         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9849         static hda_nid_t capture_mixers[1] = { 0x22 };
9850         hda_nid_t nid = capture_mixers[adc_idx];
9851         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9852         unsigned int i, idx;
9853
9854         idx = ucontrol->value.enumerated.item[0];
9855         if (idx >= imux->num_items)
9856                 idx = imux->num_items - 1;
9857         if (*cur_val == idx && !codec->in_resume)
9858                 return 0;
9859         for (i = 0; i < imux->num_items; i++) {
9860                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
9861                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9862                                     v | (imux->items[i].index << 8));
9863         }
9864         *cur_val = idx;
9865         return 1;
9866 }
9867
9868 /*
9869  * 2ch mode
9870  */
9871 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9872         { 2, NULL }
9873 };
9874
9875 /*
9876  * 6ch mode
9877  */
9878 static struct hda_verb alc861vd_6stack_ch6_init[] = {
9879         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9880         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9881         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9882         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9883         { } /* end */
9884 };
9885
9886 /*
9887  * 8ch mode
9888  */
9889 static struct hda_verb alc861vd_6stack_ch8_init[] = {
9890         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9891         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9892         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9893         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9894         { } /* end */
9895 };
9896
9897 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
9898         { 6, alc861vd_6stack_ch6_init },
9899         { 8, alc861vd_6stack_ch8_init },
9900 };
9901
9902 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
9903         {
9904                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9905                 .name = "Channel Mode",
9906                 .info = alc_ch_mode_info,
9907                 .get = alc_ch_mode_get,
9908                 .put = alc_ch_mode_put,
9909         },
9910         { } /* end */
9911 };
9912
9913 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
9914         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9915         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9916
9917         {
9918                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9919                 /* The multiple "Capture Source" controls confuse alsamixer
9920                  * So call somewhat different..
9921                  *FIXME: the controls appear in the "playback" view!
9922                  */
9923                 /* .name = "Capture Source", */
9924                 .name = "Input Source",
9925                 .count = 1,
9926                 .info = alc861vd_mux_enum_info,
9927                 .get = alc861vd_mux_enum_get,
9928                 .put = alc861vd_mux_enum_put,
9929         },
9930         { } /* end */
9931 };
9932
9933 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9934  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9935  */
9936 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
9937         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9938         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9939
9940         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9941         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9942
9943         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
9944                                 HDA_OUTPUT),
9945         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
9946                                 HDA_OUTPUT),
9947         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9948         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9949
9950         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
9951         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9952
9953         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9954
9955         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9956         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9957         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9958
9959         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9960         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9961         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9962
9963         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9964         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9965
9966         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9967         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9968
9969         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9970         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9971
9972         { } /* end */
9973 };
9974
9975 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
9976         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9977         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9978
9979         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9980
9981         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9982         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9983         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9984
9985         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9986         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9987         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9988
9989         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9990         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9991
9992         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9993         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9994
9995         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9996         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9997
9998         { } /* end */
9999 };
10000
10001 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10002         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10003         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10004         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10005
10006         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10007
10008         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10009         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10010         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10011
10012         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10013         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10014         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10015
10016         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10017         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10018
10019         { } /* end */
10020 };
10021
10022 /* Pin assignment: Front=0x14, HP = 0x15,
10023  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10024  */
10025 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10026         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10027         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10028         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10029         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10030         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10031         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10032         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10033         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10034         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10035         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10036         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10037         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10038         {
10039                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10040                 /* .name = "Capture Source", */
10041                 .name = "Input Source",
10042                 .count = 1,
10043                 .info = alc882_mux_enum_info,
10044                 .get = alc882_mux_enum_get,
10045                 .put = alc882_mux_enum_put,
10046         },
10047         { } /* end */
10048 };
10049
10050 /*
10051  * generic initialization of ADC, input mixers and output mixers
10052  */
10053 static struct hda_verb alc861vd_volume_init_verbs[] = {
10054         /*
10055          * Unmute ADC0 and set the default input to mic-in
10056          */
10057         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10058         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10059
10060         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10061          * the analog-loopback mixer widget
10062          */
10063         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10064         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10065         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10066         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10067         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10068         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10069
10070         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10071         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10072         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10073         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10074         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10075
10076         /*
10077          * Set up output mixers (0x02 - 0x05)
10078          */
10079         /* set vol=0 to output mixers */
10080         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10081         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10082         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10083         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10084
10085         /* set up input amps for analog loopback */
10086         /* Amp Indices: DAC = 0, mixer = 1 */
10087         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10088         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10089         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10090         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10091         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10092         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10093         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10094         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10095
10096         { }
10097 };
10098
10099 /*
10100  * 3-stack pin configuration:
10101  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10102  */
10103 static struct hda_verb alc861vd_3stack_init_verbs[] = {
10104         /*
10105          * Set pin mode and muting
10106          */
10107         /* set front pin widgets 0x14 for output */
10108         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10109         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10110         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10111
10112         /* Mic (rear) pin: input vref at 80% */
10113         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10114         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10115         /* Front Mic pin: input vref at 80% */
10116         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10117         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10118         /* Line In pin: input */
10119         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10120         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10121         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10122         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10123         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10124         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10125         /* CD pin widget for input */
10126         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10127
10128         { }
10129 };
10130
10131 /*
10132  * 6-stack pin configuration:
10133  */
10134 static struct hda_verb alc861vd_6stack_init_verbs[] = {
10135         /*
10136          * Set pin mode and muting
10137          */
10138         /* set front pin widgets 0x14 for output */
10139         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10140         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10141         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10142
10143         /* Rear Pin: output 1 (0x0d) */
10144         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10145         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10146         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10147         /* CLFE Pin: output 2 (0x0e) */
10148         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10149         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10150         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10151         /* Side Pin: output 3 (0x0f) */
10152         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10153         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10154         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10155
10156         /* Mic (rear) pin: input vref at 80% */
10157         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10158         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10159         /* Front Mic pin: input vref at 80% */
10160         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10161         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10162         /* Line In pin: input */
10163         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10164         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10165         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10166         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10167         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10168         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10169         /* CD pin widget for input */
10170         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10171
10172         { }
10173 };
10174
10175 static struct hda_verb alc861vd_eapd_verbs[] = {
10176         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10177         { }
10178 };
10179
10180 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10181         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10182         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10183         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10184         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10185         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
10186         {}
10187 };
10188
10189 /* toggle speaker-output according to the hp-jack state */
10190 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10191 {
10192         unsigned int present;
10193         unsigned char bits;
10194
10195         present = snd_hda_codec_read(codec, 0x1b, 0,
10196                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10197         bits = present ? 0x80 : 0;
10198         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10199                                  0x80, bits);
10200         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10201                                  0x80, bits);
10202 }
10203
10204 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10205 {
10206         unsigned int present;
10207         unsigned char bits;
10208
10209         present = snd_hda_codec_read(codec, 0x18, 0,
10210                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10211         bits = present ? 0x80 : 0;
10212         snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
10213                                  0x80, bits);
10214         snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
10215                                  0x80, bits);
10216 }
10217
10218 static void alc861vd_lenovo_automute(struct hda_codec *codec)
10219 {
10220         alc861vd_lenovo_hp_automute(codec);
10221         alc861vd_lenovo_mic_automute(codec);
10222 }
10223
10224 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10225                                         unsigned int res)
10226 {
10227         switch (res >> 26) {
10228         case ALC880_HP_EVENT:
10229                 alc861vd_lenovo_hp_automute(codec);
10230                 break;
10231         case ALC880_MIC_EVENT:
10232                 alc861vd_lenovo_mic_automute(codec);
10233                 break;
10234         }
10235 }
10236
10237 static struct hda_verb alc861vd_dallas_verbs[] = {
10238         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10239         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10240         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10241         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10242
10243         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10244         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10245         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10246         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10247         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10248         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10249         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10250         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10251         
10252         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10253         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10254         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10255         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10256         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10257         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10258         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10259         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10260
10261         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10262         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10263         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10264         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10265         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10266         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10267         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10268         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10269
10270         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10271         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10272         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10273         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10274
10275         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10276         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
10277         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10278
10279         { } /* end */
10280 };
10281
10282 /* toggle speaker-output according to the hp-jack state */
10283 static void alc861vd_dallas_automute(struct hda_codec *codec)
10284 {
10285         unsigned int present;
10286
10287         present = snd_hda_codec_read(codec, 0x15, 0,
10288                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10289         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10290                                  0x80, present ? 0x80 : 0);
10291         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10292                                  0x80, present ? 0x80 : 0);
10293 }
10294
10295 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10296 {
10297         if ((res >> 26) == ALC880_HP_EVENT)
10298                 alc861vd_dallas_automute(codec);
10299 }
10300
10301 /* pcm configuration: identiacal with ALC880 */
10302 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
10303 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
10304 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
10305 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
10306
10307 /*
10308  * configuration and preset
10309  */
10310 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10311         [ALC660VD_3ST]          = "3stack-660",
10312         [ALC660VD_3ST_DIG]= "3stack-660-digout",
10313         [ALC861VD_3ST]          = "3stack",
10314         [ALC861VD_3ST_DIG]      = "3stack-digout",
10315         [ALC861VD_6ST_DIG]      = "6stack-digout",
10316         [ALC861VD_LENOVO]       = "lenovo",
10317         [ALC861VD_DALLAS]       = "dallas",
10318         [ALC861VD_AUTO]         = "auto",
10319 };
10320
10321 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10322         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10323         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10324         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10325         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10326         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10327
10328         SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10329         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10330         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10331         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10332         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10333         {}
10334 };
10335
10336 static struct alc_config_preset alc861vd_presets[] = {
10337         [ALC660VD_3ST] = {
10338                 .mixers = { alc861vd_3st_mixer },
10339                 .init_verbs = { alc861vd_volume_init_verbs,
10340                                  alc861vd_3stack_init_verbs },
10341                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10342                 .dac_nids = alc660vd_dac_nids,
10343                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10344                 .adc_nids = alc861vd_adc_nids,
10345                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10346                 .channel_mode = alc861vd_3stack_2ch_modes,
10347                 .input_mux = &alc861vd_capture_source,
10348         },
10349         [ALC660VD_3ST_DIG] = {
10350                 .mixers = { alc861vd_3st_mixer },
10351                 .init_verbs = { alc861vd_volume_init_verbs,
10352                                  alc861vd_3stack_init_verbs },
10353                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10354                 .dac_nids = alc660vd_dac_nids,
10355                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10356                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10357                 .adc_nids = alc861vd_adc_nids,
10358                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10359                 .channel_mode = alc861vd_3stack_2ch_modes,
10360                 .input_mux = &alc861vd_capture_source,
10361         },
10362         [ALC861VD_3ST] = {
10363                 .mixers = { alc861vd_3st_mixer },
10364                 .init_verbs = { alc861vd_volume_init_verbs,
10365                                  alc861vd_3stack_init_verbs },
10366                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10367                 .dac_nids = alc861vd_dac_nids,
10368                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10369                 .channel_mode = alc861vd_3stack_2ch_modes,
10370                 .input_mux = &alc861vd_capture_source,
10371         },
10372         [ALC861VD_3ST_DIG] = {
10373                 .mixers = { alc861vd_3st_mixer },
10374                 .init_verbs = { alc861vd_volume_init_verbs,
10375                                  alc861vd_3stack_init_verbs },
10376                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10377                 .dac_nids = alc861vd_dac_nids,
10378                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10379                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10380                 .channel_mode = alc861vd_3stack_2ch_modes,
10381                 .input_mux = &alc861vd_capture_source,
10382         },
10383         [ALC861VD_6ST_DIG] = {
10384                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10385                 .init_verbs = { alc861vd_volume_init_verbs,
10386                                 alc861vd_6stack_init_verbs },
10387                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10388                 .dac_nids = alc861vd_dac_nids,
10389                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10390                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10391                 .channel_mode = alc861vd_6stack_modes,
10392                 .input_mux = &alc861vd_capture_source,
10393         },
10394         [ALC861VD_LENOVO] = {
10395                 .mixers = { alc861vd_lenovo_mixer },
10396                 .init_verbs = { alc861vd_volume_init_verbs,
10397                                 alc861vd_3stack_init_verbs,
10398                                 alc861vd_eapd_verbs,
10399                                 alc861vd_lenovo_unsol_verbs },
10400                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10401                 .dac_nids = alc660vd_dac_nids,
10402                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10403                 .adc_nids = alc861vd_adc_nids,
10404                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10405                 .channel_mode = alc861vd_3stack_2ch_modes,
10406                 .input_mux = &alc861vd_capture_source,
10407                 .unsol_event = alc861vd_lenovo_unsol_event,
10408                 .init_hook = alc861vd_lenovo_automute,
10409         },
10410         [ALC861VD_DALLAS] = {
10411                 .mixers = { alc861vd_dallas_mixer },
10412                 .init_verbs = { alc861vd_dallas_verbs },
10413                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10414                 .dac_nids = alc861vd_dac_nids,
10415                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10416                 .adc_nids = alc861vd_adc_nids,
10417                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10418                 .channel_mode = alc861vd_3stack_2ch_modes,
10419                 .input_mux = &alc861vd_dallas_capture_source,
10420                 .unsol_event = alc861vd_dallas_unsol_event,
10421                 .init_hook = alc861vd_dallas_automute,
10422         },      
10423 };
10424
10425 /*
10426  * BIOS auto configuration
10427  */
10428 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10429                                 hda_nid_t nid, int pin_type, int dac_idx)
10430 {
10431         /* set as output */
10432         snd_hda_codec_write(codec, nid, 0,
10433                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10434         snd_hda_codec_write(codec, nid, 0,
10435                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10436 }
10437
10438 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10439 {
10440         struct alc_spec *spec = codec->spec;
10441         int i;
10442
10443         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10444         for (i = 0; i <= HDA_SIDE; i++) {
10445                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10446                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10447                 if (nid)
10448                         alc861vd_auto_set_output_and_unmute(codec, nid,
10449                                                             pin_type, i);
10450         }
10451 }
10452
10453
10454 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10455 {
10456         struct alc_spec *spec = codec->spec;
10457         hda_nid_t pin;
10458
10459         pin = spec->autocfg.hp_pins[0];
10460         if (pin) /* connect to front and  use dac 0 */
10461                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10462 }
10463
10464 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
10465 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
10466
10467 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10468 {
10469         struct alc_spec *spec = codec->spec;
10470         int i;
10471
10472         for (i = 0; i < AUTO_PIN_LAST; i++) {
10473                 hda_nid_t nid = spec->autocfg.input_pins[i];
10474                 if (alc861vd_is_input_pin(nid)) {
10475                         snd_hda_codec_write(codec, nid, 0,
10476                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
10477                                         i <= AUTO_PIN_FRONT_MIC ?
10478                                                         PIN_VREF80 : PIN_IN);
10479                         if (nid != ALC861VD_PIN_CD_NID)
10480                                 snd_hda_codec_write(codec, nid, 0,
10481                                                 AC_VERB_SET_AMP_GAIN_MUTE,
10482                                                 AMP_OUT_MUTE);
10483                 }
10484         }
10485 }
10486
10487 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
10488 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
10489
10490 /* add playback controls from the parsed DAC table */
10491 /* Based on ALC880 version. But ALC861VD has separate,
10492  * different NIDs for mute/unmute switch and volume control */
10493 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10494                                              const struct auto_pin_cfg *cfg)
10495 {
10496         char name[32];
10497         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10498         hda_nid_t nid_v, nid_s;
10499         int i, err;
10500
10501         for (i = 0; i < cfg->line_outs; i++) {
10502                 if (!spec->multiout.dac_nids[i])
10503                         continue;
10504                 nid_v = alc861vd_idx_to_mixer_vol(
10505                                 alc880_dac_to_idx(
10506                                         spec->multiout.dac_nids[i]));
10507                 nid_s = alc861vd_idx_to_mixer_switch(
10508                                 alc880_dac_to_idx(
10509                                         spec->multiout.dac_nids[i]));
10510
10511                 if (i == 2) {
10512                         /* Center/LFE */
10513                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10514                                           "Center Playback Volume",
10515                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10516                                                               HDA_OUTPUT));
10517                         if (err < 0)
10518                                 return err;
10519                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10520                                           "LFE Playback Volume",
10521                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10522                                                               HDA_OUTPUT));
10523                         if (err < 0)
10524                                 return err;
10525                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10526                                           "Center Playback Switch",
10527                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10528                                                               HDA_INPUT));
10529                         if (err < 0)
10530                                 return err;
10531                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10532                                           "LFE Playback Switch",
10533                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10534                                                               HDA_INPUT));
10535                         if (err < 0)
10536                                 return err;
10537                 } else {
10538                         sprintf(name, "%s Playback Volume", chname[i]);
10539                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10540                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10541                                                               HDA_OUTPUT));
10542                         if (err < 0)
10543                                 return err;
10544                         sprintf(name, "%s Playback Switch", chname[i]);
10545                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10546                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10547                                                               HDA_INPUT));
10548                         if (err < 0)
10549                                 return err;
10550                 }
10551         }
10552         return 0;
10553 }
10554
10555 /* add playback controls for speaker and HP outputs */
10556 /* Based on ALC880 version. But ALC861VD has separate,
10557  * different NIDs for mute/unmute switch and volume control */
10558 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10559                                         hda_nid_t pin, const char *pfx)
10560 {
10561         hda_nid_t nid_v, nid_s;
10562         int err;
10563         char name[32];
10564
10565         if (!pin)
10566                 return 0;
10567
10568         if (alc880_is_fixed_pin(pin)) {
10569                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10570                 /* specify the DAC as the extra output */
10571                 if (!spec->multiout.hp_nid)
10572                         spec->multiout.hp_nid = nid_v;
10573                 else
10574                         spec->multiout.extra_out_nid[0] = nid_v;
10575                 /* control HP volume/switch on the output mixer amp */
10576                 nid_v = alc861vd_idx_to_mixer_vol(
10577                                 alc880_fixed_pin_idx(pin));
10578                 nid_s = alc861vd_idx_to_mixer_switch(
10579                                 alc880_fixed_pin_idx(pin));
10580
10581                 sprintf(name, "%s Playback Volume", pfx);
10582                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10583                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10584                 if (err < 0)
10585                         return err;
10586                 sprintf(name, "%s Playback Switch", pfx);
10587                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10588                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10589                 if (err < 0)
10590                         return err;
10591         } else if (alc880_is_multi_pin(pin)) {
10592                 /* set manual connection */
10593                 /* we have only a switch on HP-out PIN */
10594                 sprintf(name, "%s Playback Switch", pfx);
10595                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10596                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10597                 if (err < 0)
10598                         return err;
10599         }
10600         return 0;
10601 }
10602
10603 /* parse the BIOS configuration and set up the alc_spec
10604  * return 1 if successful, 0 if the proper config is not found,
10605  * or a negative error code
10606  * Based on ALC880 version - had to change it to override
10607  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10608 static int alc861vd_parse_auto_config(struct hda_codec *codec)
10609 {
10610         struct alc_spec *spec = codec->spec;
10611         int err;
10612         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10613
10614         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10615                                            alc861vd_ignore);
10616         if (err < 0)
10617                 return err;
10618         if (!spec->autocfg.line_outs)
10619                 return 0; /* can't find valid BIOS pin config */
10620
10621         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10622         if (err < 0)
10623                 return err;
10624         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10625         if (err < 0)
10626                 return err;
10627         err = alc861vd_auto_create_extra_out(spec,
10628                                              spec->autocfg.speaker_pins[0],
10629                                              "Speaker");
10630         if (err < 0)
10631                 return err;
10632         err = alc861vd_auto_create_extra_out(spec,
10633                                              spec->autocfg.hp_pins[0],
10634                                              "Headphone");
10635         if (err < 0)
10636                 return err;
10637         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10638         if (err < 0)
10639                 return err;
10640
10641         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10642
10643         if (spec->autocfg.dig_out_pin)
10644                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10645
10646         if (spec->kctl_alloc)
10647                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10648
10649         spec->init_verbs[spec->num_init_verbs++]
10650                 = alc861vd_volume_init_verbs;
10651
10652         spec->num_mux_defs = 1;
10653         spec->input_mux = &spec->private_imux;
10654
10655         return 1;
10656 }
10657
10658 /* additional initialization for auto-configuration model */
10659 static void alc861vd_auto_init(struct hda_codec *codec)
10660 {
10661         alc861vd_auto_init_multi_out(codec);
10662         alc861vd_auto_init_hp_out(codec);
10663         alc861vd_auto_init_analog_input(codec);
10664 }
10665
10666 static int patch_alc861vd(struct hda_codec *codec)
10667 {
10668         struct alc_spec *spec;
10669         int err, board_config;
10670
10671         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10672         if (spec == NULL)
10673                 return -ENOMEM;
10674
10675         codec->spec = spec;
10676
10677         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10678                                                   alc861vd_models,
10679                                                   alc861vd_cfg_tbl);
10680
10681         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10682                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10683                         "ALC861VD, trying auto-probe from BIOS...\n");
10684                 board_config = ALC861VD_AUTO;
10685         }
10686
10687         if (board_config == ALC861VD_AUTO) {
10688                 /* automatic parse from the BIOS config */
10689                 err = alc861vd_parse_auto_config(codec);
10690                 if (err < 0) {
10691                         alc_free(codec);
10692                         return err;
10693                 } else if (!err) {
10694                         printk(KERN_INFO
10695                                "hda_codec: Cannot set up configuration "
10696                                "from BIOS.  Using base mode...\n");
10697                         board_config = ALC861VD_3ST;
10698                 }
10699         }
10700
10701         if (board_config != ALC861VD_AUTO)
10702                 setup_preset(spec, &alc861vd_presets[board_config]);
10703
10704         spec->stream_name_analog = "ALC861VD Analog";
10705         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10706         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10707
10708         spec->stream_name_digital = "ALC861VD Digital";
10709         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10710         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10711
10712         spec->adc_nids = alc861vd_adc_nids;
10713         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10714
10715         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10716         spec->num_mixers++;
10717
10718         codec->patch_ops = alc_patch_ops;
10719
10720         if (board_config == ALC861VD_AUTO)
10721                 spec->init_hook = alc861vd_auto_init;
10722
10723         return 0;
10724 }
10725
10726 /*
10727  * ALC662 support
10728  *
10729  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10730  * configuration.  Each pin widget can choose any input DACs and a mixer.
10731  * Each ADC is connected from a mixer of all inputs.  This makes possible
10732  * 6-channel independent captures.
10733  *
10734  * In addition, an independent DAC for the multi-playback (not used in this
10735  * driver yet).
10736  */
10737 #define ALC662_DIGOUT_NID       0x06
10738 #define ALC662_DIGIN_NID        0x0a
10739
10740 static hda_nid_t alc662_dac_nids[4] = {
10741         /* front, rear, clfe, rear_surr */
10742         0x02, 0x03, 0x04
10743 };
10744
10745 static hda_nid_t alc662_adc_nids[1] = {
10746         /* ADC1-2 */
10747         0x09,
10748 };
10749 /* input MUX */
10750 /* FIXME: should be a matrix-type input source selection */
10751
10752 static struct hda_input_mux alc662_capture_source = {
10753         .num_items = 4,
10754         .items = {
10755                 { "Mic", 0x0 },
10756                 { "Front Mic", 0x1 },
10757                 { "Line", 0x2 },
10758                 { "CD", 0x4 },
10759         },
10760 };
10761
10762 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10763         .num_items = 2,
10764         .items = {
10765                 { "Mic", 0x1 },
10766                 { "Line", 0x2 },
10767         },
10768 };
10769 #define alc662_mux_enum_info alc_mux_enum_info
10770 #define alc662_mux_enum_get alc_mux_enum_get
10771
10772 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10773                                struct snd_ctl_elem_value *ucontrol)
10774 {
10775         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10776         struct alc_spec *spec = codec->spec;
10777         const struct hda_input_mux *imux = spec->input_mux;
10778         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10779         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
10780         hda_nid_t nid = capture_mixers[adc_idx];
10781         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10782         unsigned int i, idx;
10783
10784         idx = ucontrol->value.enumerated.item[0];
10785         if (idx >= imux->num_items)
10786                 idx = imux->num_items - 1;
10787         if (*cur_val == idx && !codec->in_resume)
10788                 return 0;
10789         for (i = 0; i < imux->num_items; i++) {
10790                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
10791                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10792                                     v | (imux->items[i].index << 8));
10793         }
10794         *cur_val = idx;
10795         return 1;
10796 }
10797 /*
10798  * 2ch mode
10799  */
10800 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10801         { 2, NULL }
10802 };
10803
10804 /*
10805  * 2ch mode
10806  */
10807 static struct hda_verb alc662_3ST_ch2_init[] = {
10808         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10809         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10810         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10811         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10812         { } /* end */
10813 };
10814
10815 /*
10816  * 6ch mode
10817  */
10818 static struct hda_verb alc662_3ST_ch6_init[] = {
10819         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10820         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10821         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10822         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10823         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10824         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10825         { } /* end */
10826 };
10827
10828 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10829         { 2, alc662_3ST_ch2_init },
10830         { 6, alc662_3ST_ch6_init },
10831 };
10832
10833 /*
10834  * 2ch mode
10835  */
10836 static struct hda_verb alc662_sixstack_ch6_init[] = {
10837         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10838         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10839         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10840         { } /* end */
10841 };
10842
10843 /*
10844  * 6ch mode
10845  */
10846 static struct hda_verb alc662_sixstack_ch8_init[] = {
10847         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10848         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10849         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10850         { } /* end */
10851 };
10852
10853 static struct hda_channel_mode alc662_5stack_modes[2] = {
10854         { 2, alc662_sixstack_ch6_init },
10855         { 6, alc662_sixstack_ch8_init },
10856 };
10857
10858 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10859  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10860  */
10861
10862 static struct snd_kcontrol_new alc662_base_mixer[] = {
10863         /* output mixer control */
10864         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10865         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
10866         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10867         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10868         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10869         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10870         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10871         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10872         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10873
10874         /*Input mixer control */
10875         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
10876         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
10877         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
10878         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
10879         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
10880         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
10881         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
10882         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
10883
10884         /* Capture mixer control */
10885         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10886         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10887         {
10888                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10889                 .name = "Capture Source",
10890                 .count = 1,
10891                 .info = alc_mux_enum_info,
10892                 .get = alc_mux_enum_get,
10893                 .put = alc_mux_enum_put,
10894         },
10895         { } /* end */
10896 };
10897
10898 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
10899         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10900         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10901         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10902         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10903         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10904         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10905         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10906         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10907         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10908         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10909         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10910         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10911         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10912         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10913         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10914         {
10915                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10916                 /* .name = "Capture Source", */
10917                 .name = "Input Source",
10918                 .count = 1,
10919                 .info = alc662_mux_enum_info,
10920                 .get = alc662_mux_enum_get,
10921                 .put = alc662_mux_enum_put,
10922         },
10923         { } /* end */
10924 };
10925
10926 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
10927         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10928         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10929         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10930         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
10931         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10932         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10933         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10934         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10935         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10936         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10937         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10938         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10939         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10940         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10941         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10942         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10943         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10944         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10945         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10946         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10947         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10948         {
10949                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10950                 /* .name = "Capture Source", */
10951                 .name = "Input Source",
10952                 .count = 1,
10953                 .info = alc662_mux_enum_info,
10954                 .get = alc662_mux_enum_get,
10955                 .put = alc662_mux_enum_put,
10956         },
10957         { } /* end */
10958 };
10959
10960 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
10961         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10962         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10963         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10964         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
10965         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10966         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10967         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10968         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10969         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10970         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10971         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10972         {
10973                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10974                 /* .name = "Capture Source", */
10975                 .name = "Input Source",
10976                 .count = 1,
10977                 .info = alc662_mux_enum_info,
10978                 .get = alc662_mux_enum_get,
10979                 .put = alc662_mux_enum_put,
10980         },
10981         { } /* end */
10982 };
10983
10984 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
10985         {
10986                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10987                 .name = "Channel Mode",
10988                 .info = alc_ch_mode_info,
10989                 .get = alc_ch_mode_get,
10990                 .put = alc_ch_mode_put,
10991         },
10992         { } /* end */
10993 };
10994
10995 static struct hda_verb alc662_init_verbs[] = {
10996         /* ADC: mute amp left and right */
10997         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10998         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10999         /* Front mixer: unmute input/output amp left and right (volume = 0) */
11000
11001         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11002         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11003         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11004         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11005         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11006
11007         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11008         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11009         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11010         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11011         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11012         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11013
11014         /* Front Pin: output 0 (0x0c) */
11015         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11016         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11017
11018         /* Rear Pin: output 1 (0x0d) */
11019         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11020         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11021
11022         /* CLFE Pin: output 2 (0x0e) */
11023         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11024         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11025
11026         /* Mic (rear) pin: input vref at 80% */
11027         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11028         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11029         /* Front Mic pin: input vref at 80% */
11030         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11031         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11032         /* Line In pin: input */
11033         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11034         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11035         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11036         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11037         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11038         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11039         /* CD pin widget for input */
11040         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11041
11042         /* FIXME: use matrix-type input source selection */
11043         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11044         /* Input mixer */
11045         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11046         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11047         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11048         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11049         { }
11050 };
11051
11052 static struct hda_verb alc662_sue_init_verbs[] = {
11053         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11054         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11055         {}
11056 };
11057
11058 /*
11059  * generic initialization of ADC, input mixers and output mixers
11060  */
11061 static struct hda_verb alc662_auto_init_verbs[] = {
11062         /*
11063          * Unmute ADC and set the default input to mic-in
11064          */
11065         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11066         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11067
11068         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11069          * mixer widget
11070          * Note: PASD motherboards uses the Line In 2 as the input for front
11071          * panel mic (mic 2)
11072          */
11073         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11074         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11075         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11076         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11077         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11078         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11079
11080         /*
11081          * Set up output mixers (0x0c - 0x0f)
11082          */
11083         /* set vol=0 to output mixers */
11084         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11085         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11086         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11087
11088         /* set up input amps for analog loopback */
11089         /* Amp Indices: DAC = 0, mixer = 1 */
11090         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11091         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11092         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11093         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11094         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11095         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11096
11097
11098         /* FIXME: use matrix-type input source selection */
11099         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11100         /* Input mixer */
11101         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11102         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11103         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11104         /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
11105         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11106
11107         { }
11108 };
11109
11110 /* capture mixer elements */
11111 static struct snd_kcontrol_new alc662_capture_mixer[] = {
11112         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11113         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11114         {
11115                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11116                 /* The multiple "Capture Source" controls confuse alsamixer
11117                  * So call somewhat different..
11118                  * FIXME: the controls appear in the "playback" view!
11119                  */
11120                 /* .name = "Capture Source", */
11121                 .name = "Input Source",
11122                 .count = 1,
11123                 .info = alc882_mux_enum_info,
11124                 .get = alc882_mux_enum_get,
11125                 .put = alc882_mux_enum_put,
11126         },
11127         { } /* end */
11128 };
11129
11130 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11131 {
11132         unsigned int present;
11133         unsigned char bits;
11134
11135         present = snd_hda_codec_read(codec, 0x14, 0,
11136                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11137         bits = present ? 0x80 : 0;
11138         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11139                                  0x80, bits);
11140         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11141                                  0x80, bits);
11142 }
11143
11144 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11145 {
11146         unsigned int present;
11147         unsigned char bits;
11148
11149         present = snd_hda_codec_read(codec, 0x1b, 0,
11150                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11151         bits = present ? 0x80 : 0;
11152         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11153                                  0x80, bits);
11154         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11155                                  0x80, bits);
11156         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11157                                  0x80, bits);
11158         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11159                                  0x80, bits);
11160 }
11161
11162 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11163                                            unsigned int res)
11164 {
11165         if ((res >> 26) == ALC880_HP_EVENT)
11166                 alc662_lenovo_101e_all_automute(codec);
11167         if ((res >> 26) == ALC880_FRONT_EVENT)
11168                 alc662_lenovo_101e_ispeaker_automute(codec);
11169 }
11170
11171
11172 /* pcm configuration: identiacal with ALC880 */
11173 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
11174 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
11175 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
11176 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
11177
11178 /*
11179  * configuration and preset
11180  */
11181 static const char *alc662_models[ALC662_MODEL_LAST] = {
11182         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
11183         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
11184         [ALC662_3ST_6ch]        = "3stack-6ch",
11185         [ALC662_5ST_DIG]        = "6stack-dig",
11186         [ALC662_LENOVO_101E]    = "lenovo-101e",
11187         [ALC662_AUTO]           = "auto",
11188 };
11189
11190 static struct snd_pci_quirk alc662_cfg_tbl[] = {
11191         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11192         {}
11193 };
11194
11195 static struct alc_config_preset alc662_presets[] = {
11196         [ALC662_3ST_2ch_DIG] = {
11197                 .mixers = { alc662_3ST_2ch_mixer },
11198                 .init_verbs = { alc662_init_verbs },
11199                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11200                 .dac_nids = alc662_dac_nids,
11201                 .dig_out_nid = ALC662_DIGOUT_NID,
11202                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11203                 .adc_nids = alc662_adc_nids,
11204                 .dig_in_nid = ALC662_DIGIN_NID,
11205                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11206                 .channel_mode = alc662_3ST_2ch_modes,
11207                 .input_mux = &alc662_capture_source,
11208         },
11209         [ALC662_3ST_6ch_DIG] = {
11210                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11211                 .init_verbs = { alc662_init_verbs },
11212                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11213                 .dac_nids = alc662_dac_nids,
11214                 .dig_out_nid = ALC662_DIGOUT_NID,
11215                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11216                 .adc_nids = alc662_adc_nids,
11217                 .dig_in_nid = ALC662_DIGIN_NID,
11218                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11219                 .channel_mode = alc662_3ST_6ch_modes,
11220                 .need_dac_fix = 1,
11221                 .input_mux = &alc662_capture_source,
11222         },
11223         [ALC662_3ST_6ch] = {
11224                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11225                 .init_verbs = { alc662_init_verbs },
11226                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11227                 .dac_nids = alc662_dac_nids,
11228                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11229                 .adc_nids = alc662_adc_nids,
11230                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11231                 .channel_mode = alc662_3ST_6ch_modes,
11232                 .need_dac_fix = 1,
11233                 .input_mux = &alc662_capture_source,
11234         },
11235         [ALC662_5ST_DIG] = {
11236                 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
11237                 .init_verbs = { alc662_init_verbs },
11238                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11239                 .dac_nids = alc662_dac_nids,
11240                 .dig_out_nid = ALC662_DIGOUT_NID,
11241                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11242                 .adc_nids = alc662_adc_nids,
11243                 .dig_in_nid = ALC662_DIGIN_NID,
11244                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11245                 .channel_mode = alc662_5stack_modes,
11246                 .input_mux = &alc662_capture_source,
11247         },
11248         [ALC662_LENOVO_101E] = {
11249                 .mixers = { alc662_lenovo_101e_mixer },
11250                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11251                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11252                 .dac_nids = alc662_dac_nids,
11253                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11254                 .adc_nids = alc662_adc_nids,
11255                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11256                 .channel_mode = alc662_3ST_2ch_modes,
11257                 .input_mux = &alc662_lenovo_101e_capture_source,
11258                 .unsol_event = alc662_lenovo_101e_unsol_event,
11259                 .init_hook = alc662_lenovo_101e_all_automute,
11260         },
11261
11262 };
11263
11264
11265 /*
11266  * BIOS auto configuration
11267  */
11268
11269 /* add playback controls from the parsed DAC table */
11270 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11271                                              const struct auto_pin_cfg *cfg)
11272 {
11273         char name[32];
11274         static const char *chname[4] = {
11275                 "Front", "Surround", NULL /*CLFE*/, "Side"
11276         };
11277         hda_nid_t nid;
11278         int i, err;
11279
11280         for (i = 0; i < cfg->line_outs; i++) {
11281                 if (!spec->multiout.dac_nids[i])
11282                         continue;
11283                 nid = alc880_idx_to_mixer(i);
11284                 if (i == 2) {
11285                         /* Center/LFE */
11286                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11287                                           "Center Playback Volume",
11288                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11289                                                               HDA_OUTPUT));
11290                         if (err < 0)
11291                                 return err;
11292                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11293                                           "LFE Playback Volume",
11294                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11295                                                               HDA_OUTPUT));
11296                         if (err < 0)
11297                                 return err;
11298                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11299                                           "Center Playback Switch",
11300                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11301                                                               HDA_INPUT));
11302                         if (err < 0)
11303                                 return err;
11304                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11305                                           "LFE Playback Switch",
11306                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11307                                                               HDA_INPUT));
11308                         if (err < 0)
11309                                 return err;
11310                 } else {
11311                         sprintf(name, "%s Playback Volume", chname[i]);
11312                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11313                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11314                                                               HDA_OUTPUT));
11315                         if (err < 0)
11316                                 return err;
11317                         sprintf(name, "%s Playback Switch", chname[i]);
11318                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11319                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11320                                                               HDA_INPUT));
11321                         if (err < 0)
11322                                 return err;
11323                 }
11324         }
11325         return 0;
11326 }
11327
11328 /* add playback controls for speaker and HP outputs */
11329 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11330                                         const char *pfx)
11331 {
11332         hda_nid_t nid;
11333         int err;
11334         char name[32];
11335
11336         if (!pin)
11337                 return 0;
11338
11339         if (alc880_is_fixed_pin(pin)) {
11340                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11341                 /* printk("DAC nid=%x\n",nid); */
11342                 /* specify the DAC as the extra output */
11343                 if (!spec->multiout.hp_nid)
11344                         spec->multiout.hp_nid = nid;
11345                 else
11346                         spec->multiout.extra_out_nid[0] = nid;
11347                 /* control HP volume/switch on the output mixer amp */
11348                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11349                 sprintf(name, "%s Playback Volume", pfx);
11350                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11351                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11352                 if (err < 0)
11353                         return err;
11354                 sprintf(name, "%s Playback Switch", pfx);
11355                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11356                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11357                 if (err < 0)
11358                         return err;
11359         } else if (alc880_is_multi_pin(pin)) {
11360                 /* set manual connection */
11361                 /* we have only a switch on HP-out PIN */
11362                 sprintf(name, "%s Playback Switch", pfx);
11363                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11364                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11365                 if (err < 0)
11366                         return err;
11367         }
11368         return 0;
11369 }
11370
11371 /* create playback/capture controls for input pins */
11372 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11373                                                 const struct auto_pin_cfg *cfg)
11374 {
11375         struct hda_input_mux *imux = &spec->private_imux;
11376         int i, err, idx;
11377
11378         for (i = 0; i < AUTO_PIN_LAST; i++) {
11379                 if (alc880_is_input_pin(cfg->input_pins[i])) {
11380                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
11381                         err = new_analog_input(spec, cfg->input_pins[i],
11382                                                auto_pin_cfg_labels[i],
11383                                                idx, 0x0b);
11384                         if (err < 0)
11385                                 return err;
11386                         imux->items[imux->num_items].label =
11387                                 auto_pin_cfg_labels[i];
11388                         imux->items[imux->num_items].index =
11389                                 alc880_input_pin_idx(cfg->input_pins[i]);
11390                         imux->num_items++;
11391                 }
11392         }
11393         return 0;
11394 }
11395
11396 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11397                                               hda_nid_t nid, int pin_type,
11398                                               int dac_idx)
11399 {
11400         /* set as output */
11401         snd_hda_codec_write(codec, nid, 0,
11402                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11403         snd_hda_codec_write(codec, nid, 0,
11404                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11405         /* need the manual connection? */
11406         if (alc880_is_multi_pin(nid)) {
11407                 struct alc_spec *spec = codec->spec;
11408                 int idx = alc880_multi_pin_idx(nid);
11409                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11410                                     AC_VERB_SET_CONNECT_SEL,
11411                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11412         }
11413 }
11414
11415 static void alc662_auto_init_multi_out(struct hda_codec *codec)
11416 {
11417         struct alc_spec *spec = codec->spec;
11418         int i;
11419
11420         for (i = 0; i <= HDA_SIDE; i++) {
11421                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11422                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11423                 if (nid)
11424                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11425                                                           i);
11426         }
11427 }
11428
11429 static void alc662_auto_init_hp_out(struct hda_codec *codec)
11430 {
11431         struct alc_spec *spec = codec->spec;
11432         hda_nid_t pin;
11433
11434         pin = spec->autocfg.hp_pins[0];
11435         if (pin) /* connect to front */
11436                 /* use dac 0 */
11437                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11438 }
11439
11440 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
11441 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
11442
11443 static void alc662_auto_init_analog_input(struct hda_codec *codec)
11444 {
11445         struct alc_spec *spec = codec->spec;
11446         int i;
11447
11448         for (i = 0; i < AUTO_PIN_LAST; i++) {
11449                 hda_nid_t nid = spec->autocfg.input_pins[i];
11450                 if (alc662_is_input_pin(nid)) {
11451                         snd_hda_codec_write(codec, nid, 0,
11452                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
11453                                             (i <= AUTO_PIN_FRONT_MIC ?
11454                                              PIN_VREF80 : PIN_IN));
11455                         if (nid != ALC662_PIN_CD_NID)
11456                                 snd_hda_codec_write(codec, nid, 0,
11457                                                     AC_VERB_SET_AMP_GAIN_MUTE,
11458                                                     AMP_OUT_MUTE);
11459                 }
11460         }
11461 }
11462
11463 static int alc662_parse_auto_config(struct hda_codec *codec)
11464 {
11465         struct alc_spec *spec = codec->spec;
11466         int err;
11467         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11468
11469         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11470                                            alc662_ignore);
11471         if (err < 0)
11472                 return err;
11473         if (!spec->autocfg.line_outs)
11474                 return 0; /* can't find valid BIOS pin config */
11475
11476         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11477         if (err < 0)
11478                 return err;
11479         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11480         if (err < 0)
11481                 return err;
11482         err = alc662_auto_create_extra_out(spec,
11483                                            spec->autocfg.speaker_pins[0],
11484                                            "Speaker");
11485         if (err < 0)
11486                 return err;
11487         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11488                                            "Headphone");
11489         if (err < 0)
11490                 return err;
11491         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11492         if (err < 0)
11493                 return err;
11494
11495         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11496
11497         if (spec->autocfg.dig_out_pin)
11498                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11499
11500         if (spec->kctl_alloc)
11501                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11502
11503         spec->num_mux_defs = 1;
11504         spec->input_mux = &spec->private_imux;
11505         
11506         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11507         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11508         spec->num_mixers++;
11509         return 1;
11510 }
11511
11512 /* additional initialization for auto-configuration model */
11513 static void alc662_auto_init(struct hda_codec *codec)
11514 {
11515         alc662_auto_init_multi_out(codec);
11516         alc662_auto_init_hp_out(codec);
11517         alc662_auto_init_analog_input(codec);
11518 }
11519
11520 static int patch_alc662(struct hda_codec *codec)
11521 {
11522         struct alc_spec *spec;
11523         int err, board_config;
11524
11525         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11526         if (!spec)
11527                 return -ENOMEM;
11528
11529         codec->spec = spec;
11530
11531         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11532                                                   alc662_models,
11533                                                   alc662_cfg_tbl);
11534         if (board_config < 0) {
11535                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11536                        "trying auto-probe from BIOS...\n");
11537                 board_config = ALC662_AUTO;
11538         }
11539
11540         if (board_config == ALC662_AUTO) {
11541                 /* automatic parse from the BIOS config */
11542                 err = alc662_parse_auto_config(codec);
11543                 if (err < 0) {
11544                         alc_free(codec);
11545                         return err;
11546                 } else if (!err) {
11547                         printk(KERN_INFO
11548                                "hda_codec: Cannot set up configuration "
11549                                "from BIOS.  Using base mode...\n");
11550                         board_config = ALC662_3ST_2ch_DIG;
11551                 }
11552         }
11553
11554         if (board_config != ALC662_AUTO)
11555                 setup_preset(spec, &alc662_presets[board_config]);
11556
11557         spec->stream_name_analog = "ALC662 Analog";
11558         spec->stream_analog_playback = &alc662_pcm_analog_playback;
11559         spec->stream_analog_capture = &alc662_pcm_analog_capture;
11560
11561         spec->stream_name_digital = "ALC662 Digital";
11562         spec->stream_digital_playback = &alc662_pcm_digital_playback;
11563         spec->stream_digital_capture = &alc662_pcm_digital_capture;
11564
11565         if (!spec->adc_nids && spec->input_mux) {
11566                 spec->adc_nids = alc662_adc_nids;
11567                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11568         }
11569
11570         codec->patch_ops = alc_patch_ops;
11571         if (board_config == ALC662_AUTO)
11572                 spec->init_hook = alc662_auto_init;
11573
11574         return 0;
11575 }
11576
11577 /*
11578  * patch entries
11579  */
11580 struct hda_codec_preset snd_hda_preset_realtek[] = {
11581         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11582         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11583         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11584         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11585           .patch = patch_alc861 },
11586         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11587         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11588         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11589         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11590           .patch = patch_alc883 },
11591         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11592           .patch = patch_alc662 },
11593         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11594         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11595         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11596         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11597         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11598         {} /* terminator */
11599 };