[ALSA] hda-codec - Some fixes for Realtek codec supports
[safe/jmp/linux-2.6] / 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         ALC882_AUTO,
157         ALC882_MODEL_LAST,
158 };
159
160 /* ALC883 models */
161 enum {
162         ALC883_3ST_2ch_DIG,
163         ALC883_3ST_6ch_DIG,
164         ALC883_3ST_6ch,
165         ALC883_6ST_DIG,
166         ALC883_TARGA_DIG,
167         ALC883_TARGA_2ch_DIG,
168         ALC883_ACER,
169         ALC883_MEDION,
170         ALC883_MEDION_MD2,      
171         ALC883_LAPTOP_EAPD,
172         ALC883_LENOVO_101E_2ch,
173         ALC883_LENOVO_NB0763,
174         ALC888_LENOVO_MS7195_DIG,               
175         ALC883_AUTO,
176         ALC883_MODEL_LAST,
177 };
178
179 /* for GPIO Poll */
180 #define GPIO_MASK       0x03
181
182 struct alc_spec {
183         /* codec parameterization */
184         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
185         unsigned int num_mixers;
186
187         const struct hda_verb *init_verbs[5];   /* initialization verbs
188                                                  * don't forget NULL
189                                                  * termination!
190                                                  */
191         unsigned int num_init_verbs;
192
193         char *stream_name_analog;       /* analog PCM stream */
194         struct hda_pcm_stream *stream_analog_playback;
195         struct hda_pcm_stream *stream_analog_capture;
196
197         char *stream_name_digital;      /* digital PCM stream */
198         struct hda_pcm_stream *stream_digital_playback;
199         struct hda_pcm_stream *stream_digital_capture;
200
201         /* playback */
202         struct hda_multi_out multiout;  /* playback set-up
203                                          * max_channels, dacs must be set
204                                          * dig_out_nid and hp_nid are optional
205                                          */
206
207         /* capture */
208         unsigned int num_adc_nids;
209         hda_nid_t *adc_nids;
210         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
211
212         /* capture source */
213         unsigned int num_mux_defs;
214         const struct hda_input_mux *input_mux;
215         unsigned int cur_mux[3];
216
217         /* channel model */
218         const struct hda_channel_mode *channel_mode;
219         int num_channel_mode;
220         int need_dac_fix;
221
222         /* PCM information */
223         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
224
225         /* dynamic controls, init_verbs and input_mux */
226         struct auto_pin_cfg autocfg;
227         unsigned int num_kctl_alloc, num_kctl_used;
228         struct snd_kcontrol_new *kctl_alloc;
229         struct hda_input_mux private_imux;
230         hda_nid_t private_dac_nids[5];
231
232         /* hooks */
233         void (*init_hook)(struct hda_codec *codec);
234         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
235
236         /* for pin sensing */
237         unsigned int sense_updated: 1;
238         unsigned int jack_present: 1;
239 };
240
241 /*
242  * configuration template - to be copied to the spec instance
243  */
244 struct alc_config_preset {
245         struct snd_kcontrol_new *mixers[5]; /* should be identical size
246                                              * with spec
247                                              */
248         const struct hda_verb *init_verbs[5];
249         unsigned int num_dacs;
250         hda_nid_t *dac_nids;
251         hda_nid_t dig_out_nid;          /* optional */
252         hda_nid_t hp_nid;               /* optional */
253         unsigned int num_adc_nids;
254         hda_nid_t *adc_nids;
255         hda_nid_t dig_in_nid;
256         unsigned int num_channel_mode;
257         const struct hda_channel_mode *channel_mode;
258         int need_dac_fix;
259         unsigned int num_mux_defs;
260         const struct hda_input_mux *input_mux;
261         void (*unsol_event)(struct hda_codec *, unsigned int);
262         void (*init_hook)(struct hda_codec *);
263 };
264
265
266 /*
267  * input MUX handling
268  */
269 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
270                              struct snd_ctl_elem_info *uinfo)
271 {
272         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
273         struct alc_spec *spec = codec->spec;
274         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
275         if (mux_idx >= spec->num_mux_defs)
276                 mux_idx = 0;
277         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
278 }
279
280 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
281                             struct snd_ctl_elem_value *ucontrol)
282 {
283         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
284         struct alc_spec *spec = codec->spec;
285         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
286
287         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
288         return 0;
289 }
290
291 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
292                             struct snd_ctl_elem_value *ucontrol)
293 {
294         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
295         struct alc_spec *spec = codec->spec;
296         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
297         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
298         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
299                                      spec->adc_nids[adc_idx],
300                                      &spec->cur_mux[adc_idx]);
301 }
302
303
304 /*
305  * channel mode setting
306  */
307 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
308                             struct snd_ctl_elem_info *uinfo)
309 {
310         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
311         struct alc_spec *spec = codec->spec;
312         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
313                                     spec->num_channel_mode);
314 }
315
316 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
317                            struct snd_ctl_elem_value *ucontrol)
318 {
319         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
320         struct alc_spec *spec = codec->spec;
321         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
322                                    spec->num_channel_mode,
323                                    spec->multiout.max_channels);
324 }
325
326 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
327                            struct snd_ctl_elem_value *ucontrol)
328 {
329         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
330         struct alc_spec *spec = codec->spec;
331         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
332                                       spec->num_channel_mode,
333                                       &spec->multiout.max_channels);
334         if (err >= 0 && spec->need_dac_fix)
335                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
336         return err;
337 }
338
339 /*
340  * Control the mode of pin widget settings via the mixer.  "pc" is used
341  * instead of "%" to avoid consequences of accidently treating the % as 
342  * being part of a format specifier.  Maximum allowed length of a value is
343  * 63 characters plus NULL terminator.
344  *
345  * Note: some retasking pin complexes seem to ignore requests for input
346  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
347  * are requested.  Therefore order this list so that this behaviour will not
348  * cause problems when mixer clients move through the enum sequentially.
349  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
350  * March 2006.
351  */
352 static char *alc_pin_mode_names[] = {
353         "Mic 50pc bias", "Mic 80pc bias",
354         "Line in", "Line out", "Headphone out",
355 };
356 static unsigned char alc_pin_mode_values[] = {
357         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
358 };
359 /* The control can present all 5 options, or it can limit the options based
360  * in the pin being assumed to be exclusively an input or an output pin.  In
361  * addition, "input" pins may or may not process the mic bias option
362  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
363  * accept requests for bias as of chip versions up to March 2006) and/or
364  * wiring in the computer.
365  */
366 #define ALC_PIN_DIR_IN              0x00
367 #define ALC_PIN_DIR_OUT             0x01
368 #define ALC_PIN_DIR_INOUT           0x02
369 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
370 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
371
372 /* Info about the pin modes supported by the different pin direction modes. 
373  * For each direction the minimum and maximum values are given.
374  */
375 static signed char alc_pin_mode_dir_info[5][2] = {
376         { 0, 2 },    /* ALC_PIN_DIR_IN */
377         { 3, 4 },    /* ALC_PIN_DIR_OUT */
378         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
379         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
380         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
381 };
382 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
383 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
384 #define alc_pin_mode_n_items(_dir) \
385         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
386
387 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
388                              struct snd_ctl_elem_info *uinfo)
389 {
390         unsigned int item_num = uinfo->value.enumerated.item;
391         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
392
393         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
394         uinfo->count = 1;
395         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
396
397         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
398                 item_num = alc_pin_mode_min(dir);
399         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
400         return 0;
401 }
402
403 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
404                             struct snd_ctl_elem_value *ucontrol)
405 {
406         unsigned int i;
407         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
408         hda_nid_t nid = kcontrol->private_value & 0xffff;
409         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
410         long *valp = ucontrol->value.integer.value;
411         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
412                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
413                                                  0x00);
414
415         /* Find enumerated value for current pinctl setting */
416         i = alc_pin_mode_min(dir);
417         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
418                 i++;
419         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
420         return 0;
421 }
422
423 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
424                             struct snd_ctl_elem_value *ucontrol)
425 {
426         signed int change;
427         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
428         hda_nid_t nid = kcontrol->private_value & 0xffff;
429         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
430         long val = *ucontrol->value.integer.value;
431         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
432                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
433                                                  0x00);
434
435         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
436                 val = alc_pin_mode_min(dir);
437
438         change = pinctl != alc_pin_mode_values[val];
439         if (change) {
440                 /* Set pin mode to that requested */
441                 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
442                                     alc_pin_mode_values[val]);
443
444                 /* Also enable the retasking pin's input/output as required 
445                  * for the requested pin mode.  Enum values of 2 or less are
446                  * input modes.
447                  *
448                  * Dynamically switching the input/output buffers probably
449                  * reduces noise slightly (particularly on input) so we'll
450                  * do it.  However, having both input and output buffers
451                  * enabled simultaneously doesn't seem to be problematic if
452                  * this turns out to be necessary in the future.
453                  */
454                 if (val <= 2) {
455                         snd_hda_codec_write(codec, nid, 0,
456                                             AC_VERB_SET_AMP_GAIN_MUTE,
457                                             AMP_OUT_MUTE);
458                         snd_hda_codec_write(codec, nid, 0,
459                                             AC_VERB_SET_AMP_GAIN_MUTE,
460                                             AMP_IN_UNMUTE(0));
461                 } else {
462                         snd_hda_codec_write(codec, nid, 0,
463                                             AC_VERB_SET_AMP_GAIN_MUTE,
464                                             AMP_IN_MUTE(0));
465                         snd_hda_codec_write(codec, nid, 0,
466                                             AC_VERB_SET_AMP_GAIN_MUTE,
467                                             AMP_OUT_UNMUTE);
468                 }
469         }
470         return change;
471 }
472
473 #define ALC_PIN_MODE(xname, nid, dir) \
474         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
475           .info = alc_pin_mode_info, \
476           .get = alc_pin_mode_get, \
477           .put = alc_pin_mode_put, \
478           .private_value = nid | (dir<<16) }
479
480 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
481  * together using a mask with more than one bit set.  This control is
482  * currently used only by the ALC260 test model.  At this stage they are not
483  * needed for any "production" models.
484  */
485 #ifdef CONFIG_SND_DEBUG
486 static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
487                               struct snd_ctl_elem_info *uinfo)
488 {
489         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
490         uinfo->count = 1;
491         uinfo->value.integer.min = 0;
492         uinfo->value.integer.max = 1;
493         return 0;
494 }
495
496 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
497                              struct snd_ctl_elem_value *ucontrol)
498 {
499         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500         hda_nid_t nid = kcontrol->private_value & 0xffff;
501         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
502         long *valp = ucontrol->value.integer.value;
503         unsigned int val = snd_hda_codec_read(codec, nid, 0,
504                                               AC_VERB_GET_GPIO_DATA, 0x00);
505
506         *valp = (val & mask) != 0;
507         return 0;
508 }
509 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
510                              struct snd_ctl_elem_value *ucontrol)
511 {
512         signed int change;
513         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
514         hda_nid_t nid = kcontrol->private_value & 0xffff;
515         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
516         long val = *ucontrol->value.integer.value;
517         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
518                                                     AC_VERB_GET_GPIO_DATA,
519                                                     0x00);
520
521         /* Set/unset the masked GPIO bit(s) as needed */
522         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
523         if (val == 0)
524                 gpio_data &= ~mask;
525         else
526                 gpio_data |= mask;
527         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
528
529         return change;
530 }
531 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
532         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
533           .info = alc_gpio_data_info, \
534           .get = alc_gpio_data_get, \
535           .put = alc_gpio_data_put, \
536           .private_value = nid | (mask<<16) }
537 #endif   /* CONFIG_SND_DEBUG */
538
539 /* A switch control to allow the enabling of the digital IO pins on the
540  * ALC260.  This is incredibly simplistic; the intention of this control is
541  * to provide something in the test model allowing digital outputs to be
542  * identified if present.  If models are found which can utilise these
543  * outputs a more complete mixer control can be devised for those models if
544  * necessary.
545  */
546 #ifdef CONFIG_SND_DEBUG
547 static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
548                                struct snd_ctl_elem_info *uinfo)
549 {
550         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
551         uinfo->count = 1;
552         uinfo->value.integer.min = 0;
553         uinfo->value.integer.max = 1;
554         return 0;
555 }
556
557 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
558                               struct snd_ctl_elem_value *ucontrol)
559 {
560         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
561         hda_nid_t nid = kcontrol->private_value & 0xffff;
562         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
563         long *valp = ucontrol->value.integer.value;
564         unsigned int val = snd_hda_codec_read(codec, nid, 0,
565                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
566
567         *valp = (val & mask) != 0;
568         return 0;
569 }
570 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
571                               struct snd_ctl_elem_value *ucontrol)
572 {
573         signed int change;
574         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
575         hda_nid_t nid = kcontrol->private_value & 0xffff;
576         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
577         long val = *ucontrol->value.integer.value;
578         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
579                                                     AC_VERB_GET_DIGI_CONVERT,
580                                                     0x00);
581
582         /* Set/unset the masked control bit(s) as needed */
583         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
584         if (val==0)
585                 ctrl_data &= ~mask;
586         else
587                 ctrl_data |= mask;
588         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
589                             ctrl_data);
590
591         return change;
592 }
593 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
594         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
595           .info = alc_spdif_ctrl_info, \
596           .get = alc_spdif_ctrl_get, \
597           .put = alc_spdif_ctrl_put, \
598           .private_value = nid | (mask<<16) }
599 #endif   /* CONFIG_SND_DEBUG */
600
601 /*
602  * set up from the preset table
603  */
604 static void setup_preset(struct alc_spec *spec,
605                          const struct alc_config_preset *preset)
606 {
607         int i;
608
609         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
610                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
611         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
612              i++)
613                 spec->init_verbs[spec->num_init_verbs++] =
614                         preset->init_verbs[i];
615         
616         spec->channel_mode = preset->channel_mode;
617         spec->num_channel_mode = preset->num_channel_mode;
618         spec->need_dac_fix = preset->need_dac_fix;
619
620         spec->multiout.max_channels = spec->channel_mode[0].channels;
621
622         spec->multiout.num_dacs = preset->num_dacs;
623         spec->multiout.dac_nids = preset->dac_nids;
624         spec->multiout.dig_out_nid = preset->dig_out_nid;
625         spec->multiout.hp_nid = preset->hp_nid;
626         
627         spec->num_mux_defs = preset->num_mux_defs;
628         if (!spec->num_mux_defs)
629                 spec->num_mux_defs = 1;
630         spec->input_mux = preset->input_mux;
631
632         spec->num_adc_nids = preset->num_adc_nids;
633         spec->adc_nids = preset->adc_nids;
634         spec->dig_in_nid = preset->dig_in_nid;
635
636         spec->unsol_event = preset->unsol_event;
637         spec->init_hook = preset->init_hook;
638 }
639
640 /* Enable GPIO mask and set output */
641 static struct hda_verb alc_gpio1_init_verbs[] = {
642         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
643         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
644         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
645         { }
646 };
647
648 static struct hda_verb alc_gpio2_init_verbs[] = {
649         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
650         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
651         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
652         { }
653 };
654
655 static struct hda_verb alc_gpio3_init_verbs[] = {
656         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
657         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
658         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
659         { }
660 };
661
662 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
663  *      31 ~ 16 :       Manufacture ID
664  *      15 ~ 8  :       SKU ID
665  *      7  ~ 0  :       Assembly ID
666  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
667  */
668 static void alc_subsystem_id(struct hda_codec *codec,
669                              unsigned int porta, unsigned int porte,
670                              unsigned int portd)
671 {
672         unsigned int ass, tmp;
673
674         ass = codec->subsystem_id;
675         if (!(ass & 1))
676                 return;
677
678         /* Override */
679         tmp = (ass & 0x38) >> 3;        /* external Amp control */
680         switch (tmp) {
681         case 1:
682                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
683                 break;
684         case 3:
685                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
686                 break;
687         case 7:
688                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
689                 break;
690         case 5:
691                 switch (codec->vendor_id) {
692                 case 0x10ec0862:
693                 case 0x10ec0660:
694                 case 0x10ec0662:        
695                 case 0x10ec0267:
696                 case 0x10ec0268:
697                         snd_hda_codec_write(codec, 0x14, 0,
698                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
699                         snd_hda_codec_write(codec, 0x15, 0,
700                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
701                         return;
702                 }
703         case 6:
704                 if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
705                         hda_nid_t port = 0;
706                         tmp = (ass & 0x1800) >> 11;
707                         switch (tmp) {
708                         case 0: port = porta; break;
709                         case 1: port = porte; break;
710                         case 2: port = portd; break;
711                         }
712                         if (port)
713                                 snd_hda_codec_write(codec, port, 0,
714                                                     AC_VERB_SET_EAPD_BTLENABLE,
715                                                     2);
716                 }
717                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
718                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
719                                     (tmp == 5 ? 0x3040 : 0x3050));
720                 break;
721         }
722 }
723
724 /*
725  * ALC880 3-stack model
726  *
727  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
728  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
729  *                 F-Mic = 0x1b, HP = 0x19
730  */
731
732 static hda_nid_t alc880_dac_nids[4] = {
733         /* front, rear, clfe, rear_surr */
734         0x02, 0x05, 0x04, 0x03
735 };
736
737 static hda_nid_t alc880_adc_nids[3] = {
738         /* ADC0-2 */
739         0x07, 0x08, 0x09,
740 };
741
742 /* The datasheet says the node 0x07 is connected from inputs,
743  * but it shows zero connection in the real implementation on some devices.
744  * Note: this is a 915GAV bug, fixed on 915GLV
745  */
746 static hda_nid_t alc880_adc_nids_alt[2] = {
747         /* ADC1-2 */
748         0x08, 0x09,
749 };
750
751 #define ALC880_DIGOUT_NID       0x06
752 #define ALC880_DIGIN_NID        0x0a
753
754 static struct hda_input_mux alc880_capture_source = {
755         .num_items = 4,
756         .items = {
757                 { "Mic", 0x0 },
758                 { "Front Mic", 0x3 },
759                 { "Line", 0x2 },
760                 { "CD", 0x4 },
761         },
762 };
763
764 /* channel source setting (2/6 channel selection for 3-stack) */
765 /* 2ch mode */
766 static struct hda_verb alc880_threestack_ch2_init[] = {
767         /* set line-in to input, mute it */
768         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
769         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
770         /* set mic-in to input vref 80%, mute it */
771         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
772         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
773         { } /* end */
774 };
775
776 /* 6ch mode */
777 static struct hda_verb alc880_threestack_ch6_init[] = {
778         /* set line-in to output, unmute it */
779         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
780         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
781         /* set mic-in to output, unmute it */
782         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
783         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
784         { } /* end */
785 };
786
787 static struct hda_channel_mode alc880_threestack_modes[2] = {
788         { 2, alc880_threestack_ch2_init },
789         { 6, alc880_threestack_ch6_init },
790 };
791
792 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
793         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
794         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
795         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
796         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
797         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
798         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
799         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
800         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
801         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
802         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
803         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
804         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
805         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
806         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
807         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
808         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
809         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
810         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
811         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
812         {
813                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
814                 .name = "Channel Mode",
815                 .info = alc_ch_mode_info,
816                 .get = alc_ch_mode_get,
817                 .put = alc_ch_mode_put,
818         },
819         { } /* end */
820 };
821
822 /* capture mixer elements */
823 static struct snd_kcontrol_new alc880_capture_mixer[] = {
824         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
825         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
826         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
827         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
828         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
829         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
830         {
831                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
832                 /* The multiple "Capture Source" controls confuse alsamixer
833                  * So call somewhat different..
834                  * FIXME: the controls appear in the "playback" view!
835                  */
836                 /* .name = "Capture Source", */
837                 .name = "Input Source",
838                 .count = 3,
839                 .info = alc_mux_enum_info,
840                 .get = alc_mux_enum_get,
841                 .put = alc_mux_enum_put,
842         },
843         { } /* end */
844 };
845
846 /* capture mixer elements (in case NID 0x07 not available) */
847 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
848         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
849         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
850         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
851         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
852         {
853                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
854                 /* The multiple "Capture Source" controls confuse alsamixer
855                  * So call somewhat different..
856                  * FIXME: the controls appear in the "playback" view!
857                  */
858                 /* .name = "Capture Source", */
859                 .name = "Input Source",
860                 .count = 2,
861                 .info = alc_mux_enum_info,
862                 .get = alc_mux_enum_get,
863                 .put = alc_mux_enum_put,
864         },
865         { } /* end */
866 };
867
868
869
870 /*
871  * ALC880 5-stack model
872  *
873  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
874  *      Side = 0x02 (0xd)
875  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
876  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
877  */
878
879 /* additional mixers to alc880_three_stack_mixer */
880 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
881         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
882         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
883         { } /* end */
884 };
885
886 /* channel source setting (6/8 channel selection for 5-stack) */
887 /* 6ch mode */
888 static struct hda_verb alc880_fivestack_ch6_init[] = {
889         /* set line-in to input, mute it */
890         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
891         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
892         { } /* end */
893 };
894
895 /* 8ch mode */
896 static struct hda_verb alc880_fivestack_ch8_init[] = {
897         /* set line-in to output, unmute it */
898         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
899         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
900         { } /* end */
901 };
902
903 static struct hda_channel_mode alc880_fivestack_modes[2] = {
904         { 6, alc880_fivestack_ch6_init },
905         { 8, alc880_fivestack_ch8_init },
906 };
907
908
909 /*
910  * ALC880 6-stack model
911  *
912  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
913  *      Side = 0x05 (0x0f)
914  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
915  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
916  */
917
918 static hda_nid_t alc880_6st_dac_nids[4] = {
919         /* front, rear, clfe, rear_surr */
920         0x02, 0x03, 0x04, 0x05
921 };
922
923 static struct hda_input_mux alc880_6stack_capture_source = {
924         .num_items = 4,
925         .items = {
926                 { "Mic", 0x0 },
927                 { "Front Mic", 0x1 },
928                 { "Line", 0x2 },
929                 { "CD", 0x4 },
930         },
931 };
932
933 /* fixed 8-channels */
934 static struct hda_channel_mode alc880_sixstack_modes[1] = {
935         { 8, NULL },
936 };
937
938 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
939         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
940         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
941         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
942         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
943         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
944         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
945         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
946         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
947         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
948         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
949         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
950         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
951         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
952         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
953         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
954         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
955         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
956         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
957         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
958         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
959         {
960                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
961                 .name = "Channel Mode",
962                 .info = alc_ch_mode_info,
963                 .get = alc_ch_mode_get,
964                 .put = alc_ch_mode_put,
965         },
966         { } /* end */
967 };
968
969
970 /*
971  * ALC880 W810 model
972  *
973  * W810 has rear IO for:
974  * Front (DAC 02)
975  * Surround (DAC 03)
976  * Center/LFE (DAC 04)
977  * Digital out (06)
978  *
979  * The system also has a pair of internal speakers, and a headphone jack.
980  * These are both connected to Line2 on the codec, hence to DAC 02.
981  * 
982  * There is a variable resistor to control the speaker or headphone
983  * volume. This is a hardware-only device without a software API.
984  *
985  * Plugging headphones in will disable the internal speakers. This is
986  * implemented in hardware, not via the driver using jack sense. In
987  * a similar fashion, plugging into the rear socket marked "front" will
988  * disable both the speakers and headphones.
989  *
990  * For input, there's a microphone jack, and an "audio in" jack.
991  * These may not do anything useful with this driver yet, because I
992  * haven't setup any initialization verbs for these yet...
993  */
994
995 static hda_nid_t alc880_w810_dac_nids[3] = {
996         /* front, rear/surround, clfe */
997         0x02, 0x03, 0x04
998 };
999
1000 /* fixed 6 channels */
1001 static struct hda_channel_mode alc880_w810_modes[1] = {
1002         { 6, NULL }
1003 };
1004
1005 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1006 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1007         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1008         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1009         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1010         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1011         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1012         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1013         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1014         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1015         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1016         { } /* end */
1017 };
1018
1019
1020 /*
1021  * Z710V model
1022  *
1023  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1024  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1025  *                 Line = 0x1a
1026  */
1027
1028 static hda_nid_t alc880_z71v_dac_nids[1] = {
1029         0x02
1030 };
1031 #define ALC880_Z71V_HP_DAC      0x03
1032
1033 /* fixed 2 channels */
1034 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1035         { 2, NULL }
1036 };
1037
1038 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1039         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1040         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1041         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1042         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1043         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1044         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1045         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1046         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1047         { } /* end */
1048 };
1049
1050
1051 /* FIXME! */
1052 /*
1053  * ALC880 F1734 model
1054  *
1055  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1056  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1057  */
1058
1059 static hda_nid_t alc880_f1734_dac_nids[1] = {
1060         0x03
1061 };
1062 #define ALC880_F1734_HP_DAC     0x02
1063
1064 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1065         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1066         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1067         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1068         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1069         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1070         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1071         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1072         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1073         { } /* end */
1074 };
1075
1076
1077 /* FIXME! */
1078 /*
1079  * ALC880 ASUS model
1080  *
1081  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1082  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1083  *  Mic = 0x18, Line = 0x1a
1084  */
1085
1086 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1087 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1088
1089 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1090         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1091         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1092         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1093         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1094         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1095         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1096         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1097         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1098         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1099         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1100         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1101         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1102         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1103         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1104         {
1105                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1106                 .name = "Channel Mode",
1107                 .info = alc_ch_mode_info,
1108                 .get = alc_ch_mode_get,
1109                 .put = alc_ch_mode_put,
1110         },
1111         { } /* end */
1112 };
1113
1114 /* FIXME! */
1115 /*
1116  * ALC880 ASUS W1V model
1117  *
1118  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1119  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1120  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1121  */
1122
1123 /* additional mixers to alc880_asus_mixer */
1124 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1125         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1126         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1127         { } /* end */
1128 };
1129
1130 /* additional mixers to alc880_asus_mixer */
1131 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1132         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1133         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1134         { } /* end */
1135 };
1136
1137 /* TCL S700 */
1138 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1139         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1140         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1141         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1142         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1143         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1144         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1145         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1146         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1147         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1148         {
1149                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1150                 /* The multiple "Capture Source" controls confuse alsamixer
1151                  * So call somewhat different..
1152                  * FIXME: the controls appear in the "playback" view!
1153                  */
1154                 /* .name = "Capture Source", */
1155                 .name = "Input Source",
1156                 .count = 1,
1157                 .info = alc_mux_enum_info,
1158                 .get = alc_mux_enum_get,
1159                 .put = alc_mux_enum_put,
1160         },
1161         { } /* end */
1162 };
1163
1164 /* Uniwill */
1165 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1166         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1167         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1168         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1169         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1170         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1171         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1172         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1173         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1174         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1175         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1176         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1177         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1178         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1179         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1180         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1181         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1182         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1183         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1184         {
1185                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1186                 .name = "Channel Mode",
1187                 .info = alc_ch_mode_info,
1188                 .get = alc_ch_mode_get,
1189                 .put = alc_ch_mode_put,
1190         },
1191         { } /* end */
1192 };
1193
1194 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1195         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1196         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1197         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1198         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1199         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1200         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1201         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1202         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1203         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1204         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1205         { } /* end */
1206 };
1207
1208 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1209         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1210         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1211         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1212         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1213         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1214         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1215         { } /* end */
1216 };
1217
1218 /*
1219  * build control elements
1220  */
1221 static int alc_build_controls(struct hda_codec *codec)
1222 {
1223         struct alc_spec *spec = codec->spec;
1224         int err;
1225         int i;
1226
1227         for (i = 0; i < spec->num_mixers; i++) {
1228                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1229                 if (err < 0)
1230                         return err;
1231         }
1232
1233         if (spec->multiout.dig_out_nid) {
1234                 err = snd_hda_create_spdif_out_ctls(codec,
1235                                                     spec->multiout.dig_out_nid);
1236                 if (err < 0)
1237                         return err;
1238         }
1239         if (spec->dig_in_nid) {
1240                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1241                 if (err < 0)
1242                         return err;
1243         }
1244         return 0;
1245 }
1246
1247
1248 /*
1249  * initialize the codec volumes, etc
1250  */
1251
1252 /*
1253  * generic initialization of ADC, input mixers and output mixers
1254  */
1255 static struct hda_verb alc880_volume_init_verbs[] = {
1256         /*
1257          * Unmute ADC0-2 and set the default input to mic-in
1258          */
1259         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1260         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1261         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1262         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1263         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1264         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1265
1266         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1267          * mixer widget
1268          * Note: PASD motherboards uses the Line In 2 as the input for front
1269          * panel mic (mic 2)
1270          */
1271         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1272         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1273         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1274         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1275         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1276         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1277
1278         /*
1279          * Set up output mixers (0x0c - 0x0f)
1280          */
1281         /* set vol=0 to output mixers */
1282         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1283         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1284         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1285         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1286         /* set up input amps for analog loopback */
1287         /* Amp Indices: DAC = 0, mixer = 1 */
1288         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1289         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1290         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1291         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1292         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1293         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1294         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1295         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1296
1297         { }
1298 };
1299
1300 /*
1301  * 3-stack pin configuration:
1302  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1303  */
1304 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1305         /*
1306          * preset connection lists of input pins
1307          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1308          */
1309         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1310         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1311         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1312
1313         /*
1314          * Set pin mode and muting
1315          */
1316         /* set front pin widgets 0x14 for output */
1317         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1318         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1319         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1320         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1321         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1322         /* Mic2 (as headphone out) for HP output */
1323         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1324         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1325         /* Line In pin widget for input */
1326         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1327         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1328         /* Line2 (as front mic) pin widget for input and vref at 80% */
1329         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1330         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1331         /* CD pin widget for input */
1332         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1333
1334         { }
1335 };
1336
1337 /*
1338  * 5-stack pin configuration:
1339  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1340  * line-in/side = 0x1a, f-mic = 0x1b
1341  */
1342 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1343         /*
1344          * preset connection lists of input pins
1345          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1346          */
1347         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1348         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1349
1350         /*
1351          * Set pin mode and muting
1352          */
1353         /* set pin widgets 0x14-0x17 for output */
1354         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1355         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1356         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1357         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1358         /* unmute pins for output (no gain on this amp) */
1359         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1360         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1361         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1363
1364         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1365         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1366         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1367         /* Mic2 (as headphone out) for HP output */
1368         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1369         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1370         /* Line In pin widget for input */
1371         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1372         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1373         /* Line2 (as front mic) pin widget for input and vref at 80% */
1374         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1375         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1376         /* CD pin widget for input */
1377         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1378
1379         { }
1380 };
1381
1382 /*
1383  * W810 pin configuration:
1384  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1385  */
1386 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1387         /* hphone/speaker input selector: front DAC */
1388         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1389
1390         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1391         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1392         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1393         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1394         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1395         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1396
1397         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1398         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1399
1400         { }
1401 };
1402
1403 /*
1404  * Z71V pin configuration:
1405  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1406  */
1407 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1408         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1409         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1410         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1411         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1412
1413         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1414         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1415         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1416         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1417
1418         { }
1419 };
1420
1421 /*
1422  * 6-stack pin configuration:
1423  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1424  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1425  */
1426 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1427         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1428
1429         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1430         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1431         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1432         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1433         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1434         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1435         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1436         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1437
1438         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1439         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1440         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1441         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1442         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1443         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1444         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1445         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1446         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1447         
1448         { }
1449 };
1450
1451 /*
1452  * Uniwill pin configuration:
1453  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1454  * line = 0x1a
1455  */
1456 static struct hda_verb alc880_uniwill_init_verbs[] = {
1457         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1458
1459         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1460         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1461         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1462         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1464         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1466         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1468         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1469         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1470         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1471         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1472         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1473
1474         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1475         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1476         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1477         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1478         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1479         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1480         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1481         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1482         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1483
1484         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1485         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1486
1487         { }
1488 };
1489
1490 /*
1491 * Uniwill P53
1492 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1493  */
1494 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1495         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1496
1497         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1498         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1500         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1501         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1502         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1503         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1504         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1505         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1506         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1507         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1508         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1509
1510         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1511         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1512         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1513         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1514         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1515         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1516
1517         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1518         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1519
1520         { }
1521 };
1522
1523 static struct hda_verb alc880_beep_init_verbs[] = {
1524         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1525         { }
1526 };
1527
1528 /* toggle speaker-output according to the hp-jack state */
1529 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1530 {
1531         unsigned int present;
1532         unsigned char bits;
1533
1534         present = snd_hda_codec_read(codec, 0x14, 0,
1535                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1536         bits = present ? 0x80 : 0;
1537         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1538                                  0x80, bits);
1539         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1540                                  0x80, bits);
1541         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1542                                  0x80, bits);
1543         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1544                                  0x80, bits);
1545 }
1546
1547 /* auto-toggle front mic */
1548 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1549 {
1550         unsigned int present;
1551         unsigned char bits;
1552
1553         present = snd_hda_codec_read(codec, 0x18, 0,
1554                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1555         bits = present ? 0x80 : 0;
1556         snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
1557                                  0x80, bits);
1558         snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
1559                                  0x80, bits);
1560 }
1561
1562 static void alc880_uniwill_automute(struct hda_codec *codec)
1563 {
1564         alc880_uniwill_hp_automute(codec);
1565         alc880_uniwill_mic_automute(codec);
1566 }
1567
1568 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1569                                        unsigned int res)
1570 {
1571         /* Looks like the unsol event is incompatible with the standard
1572          * definition.  4bit tag is placed at 28 bit!
1573          */
1574         switch (res >> 28) {
1575         case ALC880_HP_EVENT:
1576                 alc880_uniwill_hp_automute(codec);
1577                 break;
1578         case ALC880_MIC_EVENT:
1579                 alc880_uniwill_mic_automute(codec);
1580                 break;
1581         }
1582 }
1583
1584 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1585 {
1586         unsigned int present;
1587         unsigned char bits;
1588
1589         present = snd_hda_codec_read(codec, 0x14, 0,
1590                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1591         bits = present ? 0x80 : 0;
1592         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1593                                  0x80, bits);
1594         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1595                                  0x80, bits);
1596 }
1597
1598 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1599 {
1600         unsigned int present;
1601         
1602         present = snd_hda_codec_read(codec, 0x21, 0,
1603                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1604
1605         snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1606                                  0x7f, present);
1607         snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1608                                  0x7f,  present);
1609
1610         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1611                                  0x7f,  present);
1612         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1613                                  0x7f, present);
1614
1615 }
1616 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1617                                            unsigned int res)
1618 {
1619         /* Looks like the unsol event is incompatible with the standard
1620          * definition.  4bit tag is placed at 28 bit!
1621          */
1622         if ((res >> 28) == ALC880_HP_EVENT)
1623                 alc880_uniwill_p53_hp_automute(codec);
1624         if ((res >> 28) == ALC880_DCVOL_EVENT)
1625                 alc880_uniwill_p53_dcvol_automute(codec);
1626 }
1627
1628 /* FIXME! */
1629 /*
1630  * F1734 pin configuration:
1631  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1632  */
1633 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1634         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1635         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1636         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1637         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1638
1639         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1640         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1641         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1642         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1643
1644         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1645         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1646         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1647         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1648         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1649         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1650         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1651         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1652         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1653
1654         { }
1655 };
1656
1657 /* FIXME! */
1658 /*
1659  * ASUS pin configuration:
1660  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1661  */
1662 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1663         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1664         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1665         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1666         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1667
1668         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1669         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1670         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1671         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1672         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1673         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1674         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1675         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1676
1677         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1678         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1679         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1680         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1681         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1682         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1683         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1684         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1685         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1686         
1687         { }
1688 };
1689
1690 /* Enable GPIO mask and set output */
1691 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1692 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1693
1694 /* Clevo m520g init */
1695 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1696         /* headphone output */
1697         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1698         /* line-out */
1699         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1700         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1701         /* Line-in */
1702         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1703         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704         /* CD */
1705         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1706         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1707         /* Mic1 (rear panel) */
1708         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1709         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710         /* Mic2 (front panel) */
1711         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1712         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1713         /* headphone */
1714         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1715         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1716         /* change to EAPD mode */
1717         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1718         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1719
1720         { }
1721 };
1722
1723 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1724         /* change to EAPD mode */
1725         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1726         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1727
1728         /* Headphone output */
1729         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1730         /* Front output*/
1731         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1732         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1733
1734         /* Line In pin widget for input */
1735         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1736         /* CD pin widget for input */
1737         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1738         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1739         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1740
1741         /* change to EAPD mode */
1742         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1743         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1744
1745         { }
1746 };
1747
1748 /*
1749  * LG m1 express dual
1750  *
1751  * Pin assignment:
1752  *   Rear Line-In/Out (blue): 0x14
1753  *   Build-in Mic-In: 0x15
1754  *   Speaker-out: 0x17
1755  *   HP-Out (green): 0x1b
1756  *   Mic-In/Out (red): 0x19
1757  *   SPDIF-Out: 0x1e
1758  */
1759
1760 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1761 static hda_nid_t alc880_lg_dac_nids[3] = {
1762         0x05, 0x02, 0x03
1763 };
1764
1765 /* seems analog CD is not working */
1766 static struct hda_input_mux alc880_lg_capture_source = {
1767         .num_items = 3,
1768         .items = {
1769                 { "Mic", 0x1 },
1770                 { "Line", 0x5 },
1771                 { "Internal Mic", 0x6 },
1772         },
1773 };
1774
1775 /* 2,4,6 channel modes */
1776 static struct hda_verb alc880_lg_ch2_init[] = {
1777         /* set line-in and mic-in to input */
1778         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1779         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1780         { }
1781 };
1782
1783 static struct hda_verb alc880_lg_ch4_init[] = {
1784         /* set line-in to out and mic-in to input */
1785         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1786         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1787         { }
1788 };
1789
1790 static struct hda_verb alc880_lg_ch6_init[] = {
1791         /* set line-in and mic-in to output */
1792         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1793         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1794         { }
1795 };
1796
1797 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1798         { 2, alc880_lg_ch2_init },
1799         { 4, alc880_lg_ch4_init },
1800         { 6, alc880_lg_ch6_init },
1801 };
1802
1803 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1804         /* FIXME: it's not really "master" but front channels */
1805         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1806         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1807         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1808         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1809         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1810         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1811         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1812         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1813         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1814         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1815         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1816         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1817         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1818         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1819         {
1820                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1821                 .name = "Channel Mode",
1822                 .info = alc_ch_mode_info,
1823                 .get = alc_ch_mode_get,
1824                 .put = alc_ch_mode_put,
1825         },
1826         { } /* end */
1827 };
1828
1829 static struct hda_verb alc880_lg_init_verbs[] = {
1830         /* set capture source to mic-in */
1831         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1832         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1833         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1834         /* mute all amp mixer inputs */
1835         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1836         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1837         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1838         /* line-in to input */
1839         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1840         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1841         /* built-in mic */
1842         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1843         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1844         /* speaker-out */
1845         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1846         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1847         /* mic-in to input */
1848         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1849         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1850         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1851         /* HP-out */
1852         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1853         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1854         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1855         /* jack sense */
1856         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1857         { }
1858 };
1859
1860 /* toggle speaker-output according to the hp-jack state */
1861 static void alc880_lg_automute(struct hda_codec *codec)
1862 {
1863         unsigned int present;
1864         unsigned char bits;
1865
1866         present = snd_hda_codec_read(codec, 0x1b, 0,
1867                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1868         bits = present ? 0x80 : 0;
1869         snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1870                                  0x80, bits);
1871         snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1872                                  0x80, bits);
1873 }
1874
1875 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1876 {
1877         /* Looks like the unsol event is incompatible with the standard
1878          * definition.  4bit tag is placed at 28 bit!
1879          */
1880         if ((res >> 28) == 0x01)
1881                 alc880_lg_automute(codec);
1882 }
1883
1884 /*
1885  * LG LW20
1886  *
1887  * Pin assignment:
1888  *   Speaker-out: 0x14
1889  *   Mic-In: 0x18
1890  *   Built-in Mic-In: 0x19 (?)
1891  *   HP-Out: 0x1b
1892  *   SPDIF-Out: 0x1e
1893  */
1894
1895 /* seems analog CD is not working */
1896 static struct hda_input_mux alc880_lg_lw_capture_source = {
1897         .num_items = 2,
1898         .items = {
1899                 { "Mic", 0x0 },
1900                 { "Internal Mic", 0x1 },
1901         },
1902 };
1903
1904 #define alc880_lg_lw_modes alc880_threestack_modes
1905
1906 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1907         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1908         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1909         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1910         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1911         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1912         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1913         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1914         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1915         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1916         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1917         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1918         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1919         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1920         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1921         {
1922                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1923                 .name = "Channel Mode",
1924                 .info = alc_ch_mode_info,
1925                 .get = alc_ch_mode_get,
1926                 .put = alc_ch_mode_put,
1927         },
1928         { } /* end */
1929 };
1930
1931 static struct hda_verb alc880_lg_lw_init_verbs[] = {
1932         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1933         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1934         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1935
1936         /* set capture source to mic-in */
1937         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1938         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1939         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1940         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1941         /* speaker-out */
1942         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1943         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1944         /* HP-out */
1945         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1946         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1947         /* mic-in to input */
1948         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1949         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1950         /* built-in mic */
1951         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1952         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1953         /* jack sense */
1954         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1955         { }
1956 };
1957
1958 /* toggle speaker-output according to the hp-jack state */
1959 static void alc880_lg_lw_automute(struct hda_codec *codec)
1960 {
1961         unsigned int present;
1962         unsigned char bits;
1963
1964         present = snd_hda_codec_read(codec, 0x1b, 0,
1965                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1966         bits = present ? 0x80 : 0;
1967         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1968                                  0x80, bits);
1969         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1970                                  0x80, bits);
1971 }
1972
1973 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1974 {
1975         /* Looks like the unsol event is incompatible with the standard
1976          * definition.  4bit tag is placed at 28 bit!
1977          */
1978         if ((res >> 28) == 0x01)
1979                 alc880_lg_lw_automute(codec);
1980 }
1981
1982 /*
1983  * Common callbacks
1984  */
1985
1986 static int alc_init(struct hda_codec *codec)
1987 {
1988         struct alc_spec *spec = codec->spec;
1989         unsigned int i;
1990
1991         for (i = 0; i < spec->num_init_verbs; i++)
1992                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1993
1994         if (spec->init_hook)
1995                 spec->init_hook(codec);
1996
1997         return 0;
1998 }
1999
2000 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2001 {
2002         struct alc_spec *spec = codec->spec;
2003
2004         if (spec->unsol_event)
2005                 spec->unsol_event(codec, res);
2006 }
2007
2008 #ifdef CONFIG_PM
2009 /*
2010  * resume
2011  */
2012 static int alc_resume(struct hda_codec *codec)
2013 {
2014         struct alc_spec *spec = codec->spec;
2015         int i;
2016
2017         alc_init(codec);
2018         for (i = 0; i < spec->num_mixers; i++)
2019                 snd_hda_resume_ctls(codec, spec->mixers[i]);
2020         if (spec->multiout.dig_out_nid)
2021                 snd_hda_resume_spdif_out(codec);
2022         if (spec->dig_in_nid)
2023                 snd_hda_resume_spdif_in(codec);
2024
2025         return 0;
2026 }
2027 #endif
2028
2029 /*
2030  * Analog playback callbacks
2031  */
2032 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2033                                     struct hda_codec *codec,
2034                                     struct snd_pcm_substream *substream)
2035 {
2036         struct alc_spec *spec = codec->spec;
2037         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2038 }
2039
2040 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2041                                        struct hda_codec *codec,
2042                                        unsigned int stream_tag,
2043                                        unsigned int format,
2044                                        struct snd_pcm_substream *substream)
2045 {
2046         struct alc_spec *spec = codec->spec;
2047         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2048                                                 stream_tag, format, substream);
2049 }
2050
2051 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2052                                        struct hda_codec *codec,
2053                                        struct snd_pcm_substream *substream)
2054 {
2055         struct alc_spec *spec = codec->spec;
2056         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2057 }
2058
2059 /*
2060  * Digital out
2061  */
2062 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2063                                         struct hda_codec *codec,
2064                                         struct snd_pcm_substream *substream)
2065 {
2066         struct alc_spec *spec = codec->spec;
2067         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2068 }
2069
2070 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2071                                            struct hda_codec *codec,
2072                                            unsigned int stream_tag,
2073                                            unsigned int format,
2074                                            struct snd_pcm_substream *substream)
2075 {
2076         struct alc_spec *spec = codec->spec;
2077         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2078                                              stream_tag, format, substream);
2079 }
2080
2081 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2082                                          struct hda_codec *codec,
2083                                          struct snd_pcm_substream *substream)
2084 {
2085         struct alc_spec *spec = codec->spec;
2086         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2087 }
2088
2089 /*
2090  * Analog capture
2091  */
2092 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2093                                       struct hda_codec *codec,
2094                                       unsigned int stream_tag,
2095                                       unsigned int format,
2096                                       struct snd_pcm_substream *substream)
2097 {
2098         struct alc_spec *spec = codec->spec;
2099
2100         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2101                                    stream_tag, 0, format);
2102         return 0;
2103 }
2104
2105 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2106                                       struct hda_codec *codec,
2107                                       struct snd_pcm_substream *substream)
2108 {
2109         struct alc_spec *spec = codec->spec;
2110
2111         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2112                                    0, 0, 0);
2113         return 0;
2114 }
2115
2116
2117 /*
2118  */
2119 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2120         .substreams = 1,
2121         .channels_min = 2,
2122         .channels_max = 8,
2123         /* NID is set in alc_build_pcms */
2124         .ops = {
2125                 .open = alc880_playback_pcm_open,
2126                 .prepare = alc880_playback_pcm_prepare,
2127                 .cleanup = alc880_playback_pcm_cleanup
2128         },
2129 };
2130
2131 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2132         .substreams = 2,
2133         .channels_min = 2,
2134         .channels_max = 2,
2135         /* NID is set in alc_build_pcms */
2136         .ops = {
2137                 .prepare = alc880_capture_pcm_prepare,
2138                 .cleanup = alc880_capture_pcm_cleanup
2139         },
2140 };
2141
2142 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2143         .substreams = 1,
2144         .channels_min = 2,
2145         .channels_max = 2,
2146         /* NID is set in alc_build_pcms */
2147         .ops = {
2148                 .open = alc880_dig_playback_pcm_open,
2149                 .close = alc880_dig_playback_pcm_close,
2150                 .prepare = alc880_dig_playback_pcm_prepare
2151         },
2152 };
2153
2154 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2155         .substreams = 1,
2156         .channels_min = 2,
2157         .channels_max = 2,
2158         /* NID is set in alc_build_pcms */
2159 };
2160
2161 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2162 static struct hda_pcm_stream alc_pcm_null_playback = {
2163         .substreams = 0,
2164         .channels_min = 0,
2165         .channels_max = 0,
2166 };
2167
2168 static int alc_build_pcms(struct hda_codec *codec)
2169 {
2170         struct alc_spec *spec = codec->spec;
2171         struct hda_pcm *info = spec->pcm_rec;
2172         int i;
2173
2174         codec->num_pcms = 1;
2175         codec->pcm_info = info;
2176
2177         info->name = spec->stream_name_analog;
2178         if (spec->stream_analog_playback) {
2179                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2180                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2181                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2182         }
2183         if (spec->stream_analog_capture) {
2184                 snd_assert(spec->adc_nids, return -EINVAL);
2185                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2186                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2187         }
2188
2189         if (spec->channel_mode) {
2190                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2191                 for (i = 0; i < spec->num_channel_mode; i++) {
2192                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2193                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2194                         }
2195                 }
2196         }
2197
2198         /* SPDIF for stream index #1 */
2199         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2200                 codec->num_pcms = 2;
2201                 info = spec->pcm_rec + 1;
2202                 info->name = spec->stream_name_digital;
2203                 if (spec->multiout.dig_out_nid &&
2204                     spec->stream_digital_playback) {
2205                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2206                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2207                 }
2208                 if (spec->dig_in_nid &&
2209                     spec->stream_digital_capture) {
2210                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2211                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2212                 }
2213         }
2214
2215         /* If the use of more than one ADC is requested for the current
2216          * model, configure a second analog capture-only PCM.
2217          */
2218         /* Additional Analaog capture for index #2 */
2219         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2220             spec->adc_nids) {
2221                 codec->num_pcms = 3;
2222                 info = spec->pcm_rec + 2;
2223                 info->name = spec->stream_name_analog;
2224                 /* No playback stream for second PCM */
2225                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2226                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2227                 if (spec->stream_analog_capture) {
2228                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2229                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2230                 }
2231         }
2232
2233         return 0;
2234 }
2235
2236 static void alc_free(struct hda_codec *codec)
2237 {
2238         struct alc_spec *spec = codec->spec;
2239         unsigned int i;
2240
2241         if (!spec)
2242                 return;
2243
2244         if (spec->kctl_alloc) {
2245                 for (i = 0; i < spec->num_kctl_used; i++)
2246                         kfree(spec->kctl_alloc[i].name);
2247                 kfree(spec->kctl_alloc);
2248         }
2249         kfree(spec);
2250 }
2251
2252 /*
2253  */
2254 static struct hda_codec_ops alc_patch_ops = {
2255         .build_controls = alc_build_controls,
2256         .build_pcms = alc_build_pcms,
2257         .init = alc_init,
2258         .free = alc_free,
2259         .unsol_event = alc_unsol_event,
2260 #ifdef CONFIG_PM
2261         .resume = alc_resume,
2262 #endif
2263 };
2264
2265
2266 /*
2267  * Test configuration for debugging
2268  *
2269  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2270  * enum controls.
2271  */
2272 #ifdef CONFIG_SND_DEBUG
2273 static hda_nid_t alc880_test_dac_nids[4] = {
2274         0x02, 0x03, 0x04, 0x05
2275 };
2276
2277 static struct hda_input_mux alc880_test_capture_source = {
2278         .num_items = 7,
2279         .items = {
2280                 { "In-1", 0x0 },
2281                 { "In-2", 0x1 },
2282                 { "In-3", 0x2 },
2283                 { "In-4", 0x3 },
2284                 { "CD", 0x4 },
2285                 { "Front", 0x5 },
2286                 { "Surround", 0x6 },
2287         },
2288 };
2289
2290 static struct hda_channel_mode alc880_test_modes[4] = {
2291         { 2, NULL },
2292         { 4, NULL },
2293         { 6, NULL },
2294         { 8, NULL },
2295 };
2296
2297 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2298                                  struct snd_ctl_elem_info *uinfo)
2299 {
2300         static char *texts[] = {
2301                 "N/A", "Line Out", "HP Out",
2302                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2303         };
2304         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2305         uinfo->count = 1;
2306         uinfo->value.enumerated.items = 8;
2307         if (uinfo->value.enumerated.item >= 8)
2308                 uinfo->value.enumerated.item = 7;
2309         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2310         return 0;
2311 }
2312
2313 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2314                                 struct snd_ctl_elem_value *ucontrol)
2315 {
2316         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2317         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2318         unsigned int pin_ctl, item = 0;
2319
2320         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2321                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2322         if (pin_ctl & AC_PINCTL_OUT_EN) {
2323                 if (pin_ctl & AC_PINCTL_HP_EN)
2324                         item = 2;
2325                 else
2326                         item = 1;
2327         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2328                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2329                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2330                 case AC_PINCTL_VREF_50:  item = 4; break;
2331                 case AC_PINCTL_VREF_GRD: item = 5; break;
2332                 case AC_PINCTL_VREF_80:  item = 6; break;
2333                 case AC_PINCTL_VREF_100: item = 7; break;
2334                 }
2335         }
2336         ucontrol->value.enumerated.item[0] = item;
2337         return 0;
2338 }
2339
2340 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2341                                 struct snd_ctl_elem_value *ucontrol)
2342 {
2343         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2344         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2345         static unsigned int ctls[] = {
2346                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2347                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2348                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2349                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2350                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2351                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2352         };
2353         unsigned int old_ctl, new_ctl;
2354
2355         old_ctl = snd_hda_codec_read(codec, nid, 0,
2356                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2357         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2358         if (old_ctl != new_ctl) {
2359                 snd_hda_codec_write(codec, nid, 0,
2360                                     AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2361                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2362                                     (ucontrol->value.enumerated.item[0] >= 3 ?
2363                                      0xb080 : 0xb000));
2364                 return 1;
2365         }
2366         return 0;
2367 }
2368
2369 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2370                                  struct snd_ctl_elem_info *uinfo)
2371 {
2372         static char *texts[] = {
2373                 "Front", "Surround", "CLFE", "Side"
2374         };
2375         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2376         uinfo->count = 1;
2377         uinfo->value.enumerated.items = 4;
2378         if (uinfo->value.enumerated.item >= 4)
2379                 uinfo->value.enumerated.item = 3;
2380         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2381         return 0;
2382 }
2383
2384 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2385                                 struct snd_ctl_elem_value *ucontrol)
2386 {
2387         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2388         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2389         unsigned int sel;
2390
2391         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2392         ucontrol->value.enumerated.item[0] = sel & 3;
2393         return 0;
2394 }
2395
2396 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2397                                 struct snd_ctl_elem_value *ucontrol)
2398 {
2399         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2400         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2401         unsigned int sel;
2402
2403         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2404         if (ucontrol->value.enumerated.item[0] != sel) {
2405                 sel = ucontrol->value.enumerated.item[0] & 3;
2406                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2407                 return 1;
2408         }
2409         return 0;
2410 }
2411
2412 #define PIN_CTL_TEST(xname,nid) {                       \
2413                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2414                         .name = xname,                 \
2415                         .info = alc_test_pin_ctl_info, \
2416                         .get = alc_test_pin_ctl_get,   \
2417                         .put = alc_test_pin_ctl_put,   \
2418                         .private_value = nid           \
2419                         }
2420
2421 #define PIN_SRC_TEST(xname,nid) {                       \
2422                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2423                         .name = xname,                 \
2424                         .info = alc_test_pin_src_info, \
2425                         .get = alc_test_pin_src_get,   \
2426                         .put = alc_test_pin_src_put,   \
2427                         .private_value = nid           \
2428                         }
2429
2430 static struct snd_kcontrol_new alc880_test_mixer[] = {
2431         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2432         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2433         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2434         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2435         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2436         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2437         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2438         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2439         PIN_CTL_TEST("Front Pin Mode", 0x14),
2440         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2441         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2442         PIN_CTL_TEST("Side Pin Mode", 0x17),
2443         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2444         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2445         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2446         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2447         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2448         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2449         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2450         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2451         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2452         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2453         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2454         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2455         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2456         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2457         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2458         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2459         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2460         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2461         {
2462                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2463                 .name = "Channel Mode",
2464                 .info = alc_ch_mode_info,
2465                 .get = alc_ch_mode_get,
2466                 .put = alc_ch_mode_put,
2467         },
2468         { } /* end */
2469 };
2470
2471 static struct hda_verb alc880_test_init_verbs[] = {
2472         /* Unmute inputs of 0x0c - 0x0f */
2473         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2474         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2475         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2476         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2477         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2478         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2479         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2480         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2481         /* Vol output for 0x0c-0x0f */
2482         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2483         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2484         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2485         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2486         /* Set output pins 0x14-0x17 */
2487         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2488         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2489         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2490         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2491         /* Unmute output pins 0x14-0x17 */
2492         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2493         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2494         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2495         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2496         /* Set input pins 0x18-0x1c */
2497         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2498         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2499         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2500         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2501         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2502         /* Mute input pins 0x18-0x1b */
2503         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2504         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2505         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2506         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2507         /* ADC set up */
2508         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2509         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2510         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2511         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2512         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2513         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2514         /* Analog input/passthru */
2515         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2516         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2517         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2518         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2519         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2520         { }
2521 };
2522 #endif
2523
2524 /*
2525  */
2526
2527 static const char *alc880_models[ALC880_MODEL_LAST] = {
2528         [ALC880_3ST]            = "3stack",
2529         [ALC880_TCL_S700]       = "tcl",
2530         [ALC880_3ST_DIG]        = "3stack-digout",
2531         [ALC880_CLEVO]          = "clevo",
2532         [ALC880_5ST]            = "5stack",
2533         [ALC880_5ST_DIG]        = "5stack-digout",
2534         [ALC880_W810]           = "w810",
2535         [ALC880_Z71V]           = "z71v",
2536         [ALC880_6ST]            = "6stack",
2537         [ALC880_6ST_DIG]        = "6stack-digout",
2538         [ALC880_ASUS]           = "asus",
2539         [ALC880_ASUS_W1V]       = "asus-w1v",
2540         [ALC880_ASUS_DIG]       = "asus-dig",
2541         [ALC880_ASUS_DIG2]      = "asus-dig2",
2542         [ALC880_UNIWILL_DIG]    = "uniwill",
2543         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2544         [ALC880_FUJITSU]        = "fujitsu",
2545         [ALC880_F1734]          = "F1734",
2546         [ALC880_LG]             = "lg",
2547         [ALC880_LG_LW]          = "lg-lw",
2548 #ifdef CONFIG_SND_DEBUG
2549         [ALC880_TEST]           = "test",
2550 #endif
2551         [ALC880_AUTO]           = "auto",
2552 };
2553
2554 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2555         /* Broken BIOS configuration */
2556         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2557         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2558
2559         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2560         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2561         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2562         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2563         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2564         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2565         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2566         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2567         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2568
2569         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2570         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2571
2572         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2573         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2574         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2575         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2576         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2577         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2578         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2579         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2580         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2581         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2582         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2583         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2584         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2585         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2586         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2587
2588         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2589         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2590         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2591         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2592         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2593         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2594         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2595         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2596         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2597         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2598         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2599         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2600         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2601         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2602         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2603         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2604         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2605         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2606
2607         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2608         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2609         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2610         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2611
2612         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2613         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2614         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2615         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2616
2617         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2618         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2619         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2620         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2621
2622         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2623         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2624         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2625         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2626         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2627         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2628         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2629         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2630         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2631         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2632         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2633
2634         {}
2635 };
2636
2637 /*
2638  * ALC880 codec presets
2639  */
2640 static struct alc_config_preset alc880_presets[] = {
2641         [ALC880_3ST] = {
2642                 .mixers = { alc880_three_stack_mixer },
2643                 .init_verbs = { alc880_volume_init_verbs,
2644                                 alc880_pin_3stack_init_verbs },
2645                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2646                 .dac_nids = alc880_dac_nids,
2647                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2648                 .channel_mode = alc880_threestack_modes,
2649                 .need_dac_fix = 1,
2650                 .input_mux = &alc880_capture_source,
2651         },
2652         [ALC880_3ST_DIG] = {
2653                 .mixers = { alc880_three_stack_mixer },
2654                 .init_verbs = { alc880_volume_init_verbs,
2655                                 alc880_pin_3stack_init_verbs },
2656                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2657                 .dac_nids = alc880_dac_nids,
2658                 .dig_out_nid = ALC880_DIGOUT_NID,
2659                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2660                 .channel_mode = alc880_threestack_modes,
2661                 .need_dac_fix = 1,
2662                 .input_mux = &alc880_capture_source,
2663         },
2664         [ALC880_TCL_S700] = {
2665                 .mixers = { alc880_tcl_s700_mixer },
2666                 .init_verbs = { alc880_volume_init_verbs,
2667                                 alc880_pin_tcl_S700_init_verbs,
2668                                 alc880_gpio2_init_verbs },
2669                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2670                 .dac_nids = alc880_dac_nids,
2671                 .hp_nid = 0x03,
2672                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2673                 .channel_mode = alc880_2_jack_modes,
2674                 .input_mux = &alc880_capture_source,
2675         },
2676         [ALC880_5ST] = {
2677                 .mixers = { alc880_three_stack_mixer,
2678                             alc880_five_stack_mixer},
2679                 .init_verbs = { alc880_volume_init_verbs,
2680                                 alc880_pin_5stack_init_verbs },
2681                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2682                 .dac_nids = alc880_dac_nids,
2683                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2684                 .channel_mode = alc880_fivestack_modes,
2685                 .input_mux = &alc880_capture_source,
2686         },
2687         [ALC880_5ST_DIG] = {
2688                 .mixers = { alc880_three_stack_mixer,
2689                             alc880_five_stack_mixer },
2690                 .init_verbs = { alc880_volume_init_verbs,
2691                                 alc880_pin_5stack_init_verbs },
2692                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2693                 .dac_nids = alc880_dac_nids,
2694                 .dig_out_nid = ALC880_DIGOUT_NID,
2695                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2696                 .channel_mode = alc880_fivestack_modes,
2697                 .input_mux = &alc880_capture_source,
2698         },
2699         [ALC880_6ST] = {
2700                 .mixers = { alc880_six_stack_mixer },
2701                 .init_verbs = { alc880_volume_init_verbs,
2702                                 alc880_pin_6stack_init_verbs },
2703                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2704                 .dac_nids = alc880_6st_dac_nids,
2705                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2706                 .channel_mode = alc880_sixstack_modes,
2707                 .input_mux = &alc880_6stack_capture_source,
2708         },
2709         [ALC880_6ST_DIG] = {
2710                 .mixers = { alc880_six_stack_mixer },
2711                 .init_verbs = { alc880_volume_init_verbs,
2712                                 alc880_pin_6stack_init_verbs },
2713                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2714                 .dac_nids = alc880_6st_dac_nids,
2715                 .dig_out_nid = ALC880_DIGOUT_NID,
2716                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2717                 .channel_mode = alc880_sixstack_modes,
2718                 .input_mux = &alc880_6stack_capture_source,
2719         },
2720         [ALC880_W810] = {
2721                 .mixers = { alc880_w810_base_mixer },
2722                 .init_verbs = { alc880_volume_init_verbs,
2723                                 alc880_pin_w810_init_verbs,
2724                                 alc880_gpio2_init_verbs },
2725                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2726                 .dac_nids = alc880_w810_dac_nids,
2727                 .dig_out_nid = ALC880_DIGOUT_NID,
2728                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2729                 .channel_mode = alc880_w810_modes,
2730                 .input_mux = &alc880_capture_source,
2731         },
2732         [ALC880_Z71V] = {
2733                 .mixers = { alc880_z71v_mixer },
2734                 .init_verbs = { alc880_volume_init_verbs,
2735                                 alc880_pin_z71v_init_verbs },
2736                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2737                 .dac_nids = alc880_z71v_dac_nids,
2738                 .dig_out_nid = ALC880_DIGOUT_NID,
2739                 .hp_nid = 0x03,
2740                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2741                 .channel_mode = alc880_2_jack_modes,
2742                 .input_mux = &alc880_capture_source,
2743         },
2744         [ALC880_F1734] = {
2745                 .mixers = { alc880_f1734_mixer },
2746                 .init_verbs = { alc880_volume_init_verbs,
2747                                 alc880_pin_f1734_init_verbs },
2748                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2749                 .dac_nids = alc880_f1734_dac_nids,
2750                 .hp_nid = 0x02,
2751                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2752                 .channel_mode = alc880_2_jack_modes,
2753                 .input_mux = &alc880_capture_source,
2754         },
2755         [ALC880_ASUS] = {
2756                 .mixers = { alc880_asus_mixer },
2757                 .init_verbs = { alc880_volume_init_verbs,
2758                                 alc880_pin_asus_init_verbs,
2759                                 alc880_gpio1_init_verbs },
2760                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2761                 .dac_nids = alc880_asus_dac_nids,
2762                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2763                 .channel_mode = alc880_asus_modes,
2764                 .need_dac_fix = 1,
2765                 .input_mux = &alc880_capture_source,
2766         },
2767         [ALC880_ASUS_DIG] = {
2768                 .mixers = { alc880_asus_mixer },
2769                 .init_verbs = { alc880_volume_init_verbs,
2770                                 alc880_pin_asus_init_verbs,
2771                                 alc880_gpio1_init_verbs },
2772                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2773                 .dac_nids = alc880_asus_dac_nids,
2774                 .dig_out_nid = ALC880_DIGOUT_NID,
2775                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2776                 .channel_mode = alc880_asus_modes,
2777                 .need_dac_fix = 1,
2778                 .input_mux = &alc880_capture_source,
2779         },
2780         [ALC880_ASUS_DIG2] = {
2781                 .mixers = { alc880_asus_mixer },
2782                 .init_verbs = { alc880_volume_init_verbs,
2783                                 alc880_pin_asus_init_verbs,
2784                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2785                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2786                 .dac_nids = alc880_asus_dac_nids,
2787                 .dig_out_nid = ALC880_DIGOUT_NID,
2788                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2789                 .channel_mode = alc880_asus_modes,
2790                 .need_dac_fix = 1,
2791                 .input_mux = &alc880_capture_source,
2792         },
2793         [ALC880_ASUS_W1V] = {
2794                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2795                 .init_verbs = { alc880_volume_init_verbs,
2796                                 alc880_pin_asus_init_verbs,
2797                                 alc880_gpio1_init_verbs },
2798                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2799                 .dac_nids = alc880_asus_dac_nids,
2800                 .dig_out_nid = ALC880_DIGOUT_NID,
2801                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2802                 .channel_mode = alc880_asus_modes,
2803                 .need_dac_fix = 1,
2804                 .input_mux = &alc880_capture_source,
2805         },
2806         [ALC880_UNIWILL_DIG] = {
2807                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2808                 .init_verbs = { alc880_volume_init_verbs,
2809                                 alc880_pin_asus_init_verbs },
2810                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2811                 .dac_nids = alc880_asus_dac_nids,
2812                 .dig_out_nid = ALC880_DIGOUT_NID,
2813                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2814                 .channel_mode = alc880_asus_modes,
2815                 .need_dac_fix = 1,
2816                 .input_mux = &alc880_capture_source,
2817         },
2818         [ALC880_UNIWILL] = {
2819                 .mixers = { alc880_uniwill_mixer },
2820                 .init_verbs = { alc880_volume_init_verbs,
2821                                 alc880_uniwill_init_verbs },
2822                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2823                 .dac_nids = alc880_asus_dac_nids,
2824                 .dig_out_nid = ALC880_DIGOUT_NID,
2825                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2826                 .channel_mode = alc880_threestack_modes,
2827                 .need_dac_fix = 1,
2828                 .input_mux = &alc880_capture_source,
2829                 .unsol_event = alc880_uniwill_unsol_event,
2830                 .init_hook = alc880_uniwill_automute,
2831         },
2832         [ALC880_UNIWILL_P53] = {
2833                 .mixers = { alc880_uniwill_p53_mixer },
2834                 .init_verbs = { alc880_volume_init_verbs,
2835                                 alc880_uniwill_p53_init_verbs },
2836                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2837                 .dac_nids = alc880_asus_dac_nids,
2838                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2839                 .channel_mode = alc880_threestack_modes,
2840                 .input_mux = &alc880_capture_source,
2841                 .unsol_event = alc880_uniwill_p53_unsol_event,
2842                 .init_hook = alc880_uniwill_p53_hp_automute,
2843         },
2844         [ALC880_FUJITSU] = {
2845                 .mixers = { alc880_fujitsu_mixer,
2846                             alc880_pcbeep_mixer, },
2847                 .init_verbs = { alc880_volume_init_verbs,
2848                                 alc880_uniwill_p53_init_verbs,
2849                                 alc880_beep_init_verbs },
2850                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2851                 .dac_nids = alc880_dac_nids,
2852                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2853                 .channel_mode = alc880_2_jack_modes,
2854                 .input_mux = &alc880_capture_source,
2855                 .unsol_event = alc880_uniwill_p53_unsol_event,
2856                 .init_hook = alc880_uniwill_p53_hp_automute,
2857         },
2858         [ALC880_CLEVO] = {
2859                 .mixers = { alc880_three_stack_mixer },
2860                 .init_verbs = { alc880_volume_init_verbs,
2861                                 alc880_pin_clevo_init_verbs },
2862                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2863                 .dac_nids = alc880_dac_nids,
2864                 .hp_nid = 0x03,
2865                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2866                 .channel_mode = alc880_threestack_modes,
2867                 .need_dac_fix = 1,
2868                 .input_mux = &alc880_capture_source,
2869         },
2870         [ALC880_LG] = {
2871                 .mixers = { alc880_lg_mixer },
2872                 .init_verbs = { alc880_volume_init_verbs,
2873                                 alc880_lg_init_verbs },
2874                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2875                 .dac_nids = alc880_lg_dac_nids,
2876                 .dig_out_nid = ALC880_DIGOUT_NID,
2877                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2878                 .channel_mode = alc880_lg_ch_modes,
2879                 .need_dac_fix = 1,
2880                 .input_mux = &alc880_lg_capture_source,
2881                 .unsol_event = alc880_lg_unsol_event,
2882                 .init_hook = alc880_lg_automute,
2883         },
2884         [ALC880_LG_LW] = {
2885                 .mixers = { alc880_lg_lw_mixer },
2886                 .init_verbs = { alc880_volume_init_verbs,
2887                                 alc880_lg_lw_init_verbs },
2888                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2889                 .dac_nids = alc880_dac_nids,
2890                 .dig_out_nid = ALC880_DIGOUT_NID,
2891                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2892                 .channel_mode = alc880_lg_lw_modes,
2893                 .input_mux = &alc880_lg_lw_capture_source,
2894                 .unsol_event = alc880_lg_lw_unsol_event,
2895                 .init_hook = alc880_lg_lw_automute,
2896         },
2897 #ifdef CONFIG_SND_DEBUG
2898         [ALC880_TEST] = {
2899                 .mixers = { alc880_test_mixer },
2900                 .init_verbs = { alc880_test_init_verbs },
2901                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2902                 .dac_nids = alc880_test_dac_nids,
2903                 .dig_out_nid = ALC880_DIGOUT_NID,
2904                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2905                 .channel_mode = alc880_test_modes,
2906                 .input_mux = &alc880_test_capture_source,
2907         },
2908 #endif
2909 };
2910
2911 /*
2912  * Automatic parse of I/O pins from the BIOS configuration
2913  */
2914
2915 #define NUM_CONTROL_ALLOC       32
2916 #define NUM_VERB_ALLOC          32
2917
2918 enum {
2919         ALC_CTL_WIDGET_VOL,
2920         ALC_CTL_WIDGET_MUTE,
2921         ALC_CTL_BIND_MUTE,
2922 };
2923 static struct snd_kcontrol_new alc880_control_templates[] = {
2924         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2925         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2926         HDA_BIND_MUTE(NULL, 0, 0, 0),
2927 };
2928
2929 /* add dynamic controls */
2930 static int add_control(struct alc_spec *spec, int type, const char *name,
2931                        unsigned long val)
2932 {
2933         struct snd_kcontrol_new *knew;
2934
2935         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2936                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2937
2938                 /* array + terminator */
2939                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2940                 if (!knew)
2941                         return -ENOMEM;
2942                 if (spec->kctl_alloc) {
2943                         memcpy(knew, spec->kctl_alloc,
2944                                sizeof(*knew) * spec->num_kctl_alloc);
2945                         kfree(spec->kctl_alloc);
2946                 }
2947                 spec->kctl_alloc = knew;
2948                 spec->num_kctl_alloc = num;
2949         }
2950
2951         knew = &spec->kctl_alloc[spec->num_kctl_used];
2952         *knew = alc880_control_templates[type];
2953         knew->name = kstrdup(name, GFP_KERNEL);
2954         if (!knew->name)
2955                 return -ENOMEM;
2956         knew->private_value = val;
2957         spec->num_kctl_used++;
2958         return 0;
2959 }
2960
2961 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
2962 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
2963 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
2964 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
2965 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
2966 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
2967 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
2968 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
2969 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
2970 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
2971 #define ALC880_PIN_CD_NID               0x1c
2972
2973 /* fill in the dac_nids table from the parsed pin configuration */
2974 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
2975                                      const struct auto_pin_cfg *cfg)
2976 {
2977         hda_nid_t nid;
2978         int assigned[4];
2979         int i, j;
2980
2981         memset(assigned, 0, sizeof(assigned));
2982         spec->multiout.dac_nids = spec->private_dac_nids;
2983
2984         /* check the pins hardwired to audio widget */
2985         for (i = 0; i < cfg->line_outs; i++) {
2986                 nid = cfg->line_out_pins[i];
2987                 if (alc880_is_fixed_pin(nid)) {
2988                         int idx = alc880_fixed_pin_idx(nid);
2989                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
2990                         assigned[idx] = 1;
2991                 }
2992         }
2993         /* left pins can be connect to any audio widget */
2994         for (i = 0; i < cfg->line_outs; i++) {
2995                 nid = cfg->line_out_pins[i];
2996                 if (alc880_is_fixed_pin(nid))
2997                         continue;
2998                 /* search for an empty channel */
2999                 for (j = 0; j < cfg->line_outs; j++) {
3000                         if (!assigned[j]) {
3001                                 spec->multiout.dac_nids[i] =
3002                                         alc880_idx_to_dac(j);
3003                                 assigned[j] = 1;
3004                                 break;
3005                         }
3006                 }
3007         }
3008         spec->multiout.num_dacs = cfg->line_outs;
3009         return 0;
3010 }
3011
3012 /* add playback controls from the parsed DAC table */
3013 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3014                                              const struct auto_pin_cfg *cfg)
3015 {
3016         char name[32];
3017         static const char *chname[4] = {
3018                 "Front", "Surround", NULL /*CLFE*/, "Side"
3019         };
3020         hda_nid_t nid;
3021         int i, err;
3022
3023         for (i = 0; i < cfg->line_outs; i++) {
3024                 if (!spec->multiout.dac_nids[i])
3025                         continue;
3026                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3027                 if (i == 2) {
3028                         /* Center/LFE */
3029                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3030                                           "Center Playback Volume",
3031                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3032                                                               HDA_OUTPUT));
3033                         if (err < 0)
3034                                 return err;
3035                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3036                                           "LFE Playback Volume",
3037                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3038                                                               HDA_OUTPUT));
3039                         if (err < 0)
3040                                 return err;
3041                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3042                                           "Center Playback Switch",
3043                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3044                                                               HDA_INPUT));
3045                         if (err < 0)
3046                                 return err;
3047                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3048                                           "LFE Playback Switch",
3049                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3050                                                               HDA_INPUT));
3051                         if (err < 0)
3052                                 return err;
3053                 } else {
3054                         sprintf(name, "%s Playback Volume", chname[i]);
3055                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3056                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3057                                                               HDA_OUTPUT));
3058                         if (err < 0)
3059                                 return err;
3060                         sprintf(name, "%s Playback Switch", chname[i]);
3061                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3062                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3063                                                               HDA_INPUT));
3064                         if (err < 0)
3065                                 return err;
3066                 }
3067         }
3068         return 0;
3069 }
3070
3071 /* add playback controls for speaker and HP outputs */
3072 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3073                                         const char *pfx)
3074 {
3075         hda_nid_t nid;
3076         int err;
3077         char name[32];
3078
3079         if (!pin)
3080                 return 0;
3081
3082         if (alc880_is_fixed_pin(pin)) {
3083                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3084                 /* specify the DAC as the extra output */
3085                 if (!spec->multiout.hp_nid)
3086                         spec->multiout.hp_nid = nid;
3087                 else
3088                         spec->multiout.extra_out_nid[0] = nid;
3089                 /* control HP volume/switch on the output mixer amp */
3090                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3091                 sprintf(name, "%s Playback Volume", pfx);
3092                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3093                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3094                 if (err < 0)
3095                         return err;
3096                 sprintf(name, "%s Playback Switch", pfx);
3097                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3098                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3099                 if (err < 0)
3100                         return err;
3101         } else if (alc880_is_multi_pin(pin)) {
3102                 /* set manual connection */
3103                 /* we have only a switch on HP-out PIN */
3104                 sprintf(name, "%s Playback Switch", pfx);
3105                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3106                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3107                 if (err < 0)
3108                         return err;
3109         }
3110         return 0;
3111 }
3112
3113 /* create input playback/capture controls for the given pin */
3114 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3115                             const char *ctlname,
3116                             int idx, hda_nid_t mix_nid)
3117 {
3118         char name[32];
3119         int err;
3120
3121         sprintf(name, "%s Playback Volume", ctlname);
3122         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3123                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3124         if (err < 0)
3125                 return err;
3126         sprintf(name, "%s Playback Switch", ctlname);
3127         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3128                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3129         if (err < 0)
3130                 return err;
3131         return 0;
3132 }
3133
3134 /* create playback/capture controls for input pins */
3135 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3136                                                 const struct auto_pin_cfg *cfg)
3137 {
3138         struct hda_input_mux *imux = &spec->private_imux;
3139         int i, err, idx;
3140
3141         for (i = 0; i < AUTO_PIN_LAST; i++) {
3142                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3143                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3144                         err = new_analog_input(spec, cfg->input_pins[i],
3145                                                auto_pin_cfg_labels[i],
3146                                                idx, 0x0b);
3147                         if (err < 0)
3148                                 return err;
3149                         imux->items[imux->num_items].label =
3150                                 auto_pin_cfg_labels[i];
3151                         imux->items[imux->num_items].index =
3152                                 alc880_input_pin_idx(cfg->input_pins[i]);
3153                         imux->num_items++;
3154                 }
3155         }
3156         return 0;
3157 }
3158
3159 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3160                                               hda_nid_t nid, int pin_type,
3161                                               int dac_idx)
3162 {
3163         /* set as output */
3164         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3165                             pin_type);
3166         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3167                             AMP_OUT_UNMUTE);
3168         /* need the manual connection? */
3169         if (alc880_is_multi_pin(nid)) {
3170                 struct alc_spec *spec = codec->spec;
3171                 int idx = alc880_multi_pin_idx(nid);
3172                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3173                                     AC_VERB_SET_CONNECT_SEL,
3174                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3175         }
3176 }
3177
3178 static int get_pin_type(int line_out_type)
3179 {
3180         if (line_out_type == AUTO_PIN_HP_OUT)
3181                 return PIN_HP;
3182         else
3183                 return PIN_OUT;
3184 }
3185
3186 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3187 {
3188         struct alc_spec *spec = codec->spec;
3189         int i;
3190         
3191         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3192         for (i = 0; i < spec->autocfg.line_outs; i++) {
3193                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3194                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3195                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3196         }
3197 }
3198
3199 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3200 {
3201         struct alc_spec *spec = codec->spec;
3202         hda_nid_t pin;
3203
3204         pin = spec->autocfg.speaker_pins[0];
3205         if (pin) /* connect to front */
3206                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3207         pin = spec->autocfg.hp_pins[0];
3208         if (pin) /* connect to front */
3209                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3210 }
3211
3212 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3213 {
3214         struct alc_spec *spec = codec->spec;
3215         int i;
3216
3217         for (i = 0; i < AUTO_PIN_LAST; i++) {
3218                 hda_nid_t nid = spec->autocfg.input_pins[i];
3219                 if (alc880_is_input_pin(nid)) {
3220                         snd_hda_codec_write(codec, nid, 0,
3221                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3222                                             i <= AUTO_PIN_FRONT_MIC ?
3223                                             PIN_VREF80 : PIN_IN);
3224                         if (nid != ALC880_PIN_CD_NID)
3225                                 snd_hda_codec_write(codec, nid, 0,
3226                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3227                                                     AMP_OUT_MUTE);
3228                 }
3229         }
3230 }
3231
3232 /* parse the BIOS configuration and set up the alc_spec */
3233 /* return 1 if successful, 0 if the proper config is not found,
3234  * or a negative error code
3235  */
3236 static int alc880_parse_auto_config(struct hda_codec *codec)
3237 {
3238         struct alc_spec *spec = codec->spec;
3239         int err;
3240         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3241
3242         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3243                                            alc880_ignore);
3244         if (err < 0)
3245                 return err;
3246         if (!spec->autocfg.line_outs)
3247                 return 0; /* can't find valid BIOS pin config */
3248
3249         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3250         if (err < 0)
3251                 return err;
3252         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3253         if (err < 0)
3254                 return err;
3255         err = alc880_auto_create_extra_out(spec,
3256                                            spec->autocfg.speaker_pins[0],
3257                                            "Speaker");
3258         if (err < 0)
3259                 return err;
3260         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3261                                            "Headphone");
3262         if (err < 0)
3263                 return err;
3264         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3265         if (err < 0)
3266                 return err;
3267
3268         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3269
3270         if (spec->autocfg.dig_out_pin)
3271                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3272         if (spec->autocfg.dig_in_pin)
3273                 spec->dig_in_nid = ALC880_DIGIN_NID;
3274
3275         if (spec->kctl_alloc)
3276                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3277
3278         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3279
3280         spec->num_mux_defs = 1;
3281         spec->input_mux = &spec->private_imux;
3282
3283         return 1;
3284 }
3285
3286 /* additional initialization for auto-configuration model */
3287 static void alc880_auto_init(struct hda_codec *codec)
3288 {
3289         alc880_auto_init_multi_out(codec);
3290         alc880_auto_init_extra_out(codec);
3291         alc880_auto_init_analog_input(codec);
3292 }
3293
3294 /*
3295  * OK, here we have finally the patch for ALC880
3296  */
3297
3298 static int patch_alc880(struct hda_codec *codec)
3299 {
3300         struct alc_spec *spec;
3301         int board_config;
3302         int err;
3303
3304         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3305         if (spec == NULL)
3306                 return -ENOMEM;
3307
3308         codec->spec = spec;
3309
3310         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3311                                                   alc880_models,
3312                                                   alc880_cfg_tbl);
3313         if (board_config < 0) {
3314                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3315                        "trying auto-probe from BIOS...\n");
3316                 board_config = ALC880_AUTO;
3317         }
3318
3319         if (board_config == ALC880_AUTO) {
3320                 /* automatic parse from the BIOS config */
3321                 err = alc880_parse_auto_config(codec);
3322                 if (err < 0) {
3323                         alc_free(codec);
3324                         return err;
3325                 } else if (!err) {
3326                         printk(KERN_INFO
3327                                "hda_codec: Cannot set up configuration "
3328                                "from BIOS.  Using 3-stack mode...\n");
3329                         board_config = ALC880_3ST;
3330                 }
3331         }
3332
3333         if (board_config != ALC880_AUTO)
3334                 setup_preset(spec, &alc880_presets[board_config]);
3335
3336         spec->stream_name_analog = "ALC880 Analog";
3337         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3338         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3339
3340         spec->stream_name_digital = "ALC880 Digital";
3341         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3342         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3343
3344         if (!spec->adc_nids && spec->input_mux) {
3345                 /* check whether NID 0x07 is valid */
3346                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3347                 /* get type */
3348                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3349                 if (wcap != AC_WID_AUD_IN) {
3350                         spec->adc_nids = alc880_adc_nids_alt;
3351                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3352                         spec->mixers[spec->num_mixers] =
3353                                 alc880_capture_alt_mixer;
3354                         spec->num_mixers++;
3355                 } else {
3356                         spec->adc_nids = alc880_adc_nids;
3357                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3358                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3359                         spec->num_mixers++;
3360                 }
3361         }
3362
3363         codec->patch_ops = alc_patch_ops;
3364         if (board_config == ALC880_AUTO)
3365                 spec->init_hook = alc880_auto_init;
3366
3367         return 0;
3368 }
3369
3370
3371 /*
3372  * ALC260 support
3373  */
3374
3375 static hda_nid_t alc260_dac_nids[1] = {
3376         /* front */
3377         0x02,
3378 };
3379
3380 static hda_nid_t alc260_adc_nids[1] = {
3381         /* ADC0 */
3382         0x04,
3383 };
3384
3385 static hda_nid_t alc260_adc_nids_alt[1] = {
3386         /* ADC1 */
3387         0x05,
3388 };
3389
3390 static hda_nid_t alc260_hp_adc_nids[2] = {
3391         /* ADC1, 0 */
3392         0x05, 0x04
3393 };
3394
3395 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3396  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3397  */
3398 static hda_nid_t alc260_dual_adc_nids[2] = {
3399         /* ADC0, ADC1 */
3400         0x04, 0x05
3401 };
3402
3403 #define ALC260_DIGOUT_NID       0x03
3404 #define ALC260_DIGIN_NID        0x06
3405
3406 static struct hda_input_mux alc260_capture_source = {
3407         .num_items = 4,
3408         .items = {
3409                 { "Mic", 0x0 },
3410                 { "Front Mic", 0x1 },
3411                 { "Line", 0x2 },
3412                 { "CD", 0x4 },
3413         },
3414 };
3415
3416 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3417  * headphone jack and the internal CD lines since these are the only pins at
3418  * which audio can appear.  For flexibility, also allow the option of
3419  * recording the mixer output on the second ADC (ADC0 doesn't have a
3420  * connection to the mixer output).
3421  */
3422 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3423         {
3424                 .num_items = 3,
3425                 .items = {
3426                         { "Mic/Line", 0x0 },
3427                         { "CD", 0x4 },
3428                         { "Headphone", 0x2 },
3429                 },
3430         },
3431         {
3432                 .num_items = 4,
3433                 .items = {
3434                         { "Mic/Line", 0x0 },
3435                         { "CD", 0x4 },
3436                         { "Headphone", 0x2 },
3437                         { "Mixer", 0x5 },
3438                 },
3439         },
3440
3441 };
3442
3443 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3444  * the Fujitsu S702x, but jacks are marked differently.
3445  */
3446 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3447         {
3448                 .num_items = 4,
3449                 .items = {
3450                         { "Mic", 0x0 },
3451                         { "Line", 0x2 },
3452                         { "CD", 0x4 },
3453                         { "Headphone", 0x5 },
3454                 },
3455         },
3456         {
3457                 .num_items = 5,
3458                 .items = {
3459                         { "Mic", 0x0 },
3460                         { "Line", 0x2 },
3461                         { "CD", 0x4 },
3462                         { "Headphone", 0x6 },
3463                         { "Mixer", 0x5 },
3464                 },
3465         },
3466 };
3467 /*
3468  * This is just place-holder, so there's something for alc_build_pcms to look
3469  * at when it calculates the maximum number of channels. ALC260 has no mixer
3470  * element which allows changing the channel mode, so the verb list is
3471  * never used.
3472  */
3473 static struct hda_channel_mode alc260_modes[1] = {
3474         { 2, NULL },
3475 };
3476
3477
3478 /* Mixer combinations
3479  *
3480  * basic: base_output + input + pc_beep + capture
3481  * HP: base_output + input + capture_alt
3482  * HP_3013: hp_3013 + input + capture
3483  * fujitsu: fujitsu + capture
3484  * acer: acer + capture
3485  */
3486
3487 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3488         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3489         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3490         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3491         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3492         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3493         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3494         { } /* end */
3495 };
3496
3497 static struct snd_kcontrol_new alc260_input_mixer[] = {
3498         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3499         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3500         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3501         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3502         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3503         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3504         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3505         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3506         { } /* end */
3507 };
3508
3509 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3510         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3511         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3512         { } /* end */
3513 };
3514
3515 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3516         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3517         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3518         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3519         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3520         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3521         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3522         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3523         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3524         { } /* end */
3525 };
3526
3527 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3528  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3529  */
3530 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3531         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3532         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3533         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3534         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3535         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3536         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3537         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3538         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3539         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3540         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3541         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3542         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3543         { } /* end */
3544 };
3545
3546 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3547  * versions of the ALC260 don't act on requests to enable mic bias from NID
3548  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3549  * datasheet doesn't mention this restriction.  At this stage it's not clear
3550  * whether this behaviour is intentional or is a hardware bug in chip
3551  * revisions available in early 2006.  Therefore for now allow the
3552  * "Headphone Jack Mode" control to span all choices, but if it turns out
3553  * that the lack of mic bias for this NID is intentional we could change the
3554  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3555  *
3556  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3557  * don't appear to make the mic bias available from the "line" jack, even
3558  * though the NID used for this jack (0x14) can supply it.  The theory is
3559  * that perhaps Acer have included blocking capacitors between the ALC260
3560  * and the output jack.  If this turns out to be the case for all such
3561  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3562  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3563  *
3564  * The C20x Tablet series have a mono internal speaker which is controlled
3565  * via the chip's Mono sum widget and pin complex, so include the necessary
3566  * controls for such models.  On models without a "mono speaker" the control
3567  * won't do anything.
3568  */
3569 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3570         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3571         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3572         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3573         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3574                               HDA_OUTPUT),
3575         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3576                            HDA_INPUT),
3577         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3578         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3579         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3580         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3581         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3582         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3583         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3584         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3585         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3586         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3587         { } /* end */
3588 };
3589
3590 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3591  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3592  */
3593 static struct snd_kcontrol_new alc260_will_mixer[] = {
3594         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3595         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3596         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3597         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3598         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3599         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3600         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3601         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3602         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3603         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3604         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3605         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3606         { } /* end */
3607 };
3608
3609 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3610  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3611  */
3612 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3613         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3614         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3615         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3616         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3617         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3618         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3619         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3620         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3621         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3622         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3623         { } /* end */
3624 };
3625
3626 /* capture mixer elements */
3627 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3628         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3629         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3630         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3631         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3632         {
3633                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3634                 /* The multiple "Capture Source" controls confuse alsamixer
3635                  * So call somewhat different..
3636                  * FIXME: the controls appear in the "playback" view!
3637                  */
3638                 /* .name = "Capture Source", */
3639                 .name = "Input Source",
3640                 .count = 2,
3641                 .info = alc_mux_enum_info,
3642                 .get = alc_mux_enum_get,
3643                 .put = alc_mux_enum_put,
3644         },
3645         { } /* end */
3646 };
3647
3648 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3649         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3650         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3651         {
3652                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3653                 /* The multiple "Capture Source" controls confuse alsamixer
3654                  * So call somewhat different..
3655                  * FIXME: the controls appear in the "playback" view!
3656                  */
3657                 /* .name = "Capture Source", */
3658                 .name = "Input Source",
3659                 .count = 1,
3660                 .info = alc_mux_enum_info,
3661                 .get = alc_mux_enum_get,
3662                 .put = alc_mux_enum_put,
3663         },
3664         { } /* end */
3665 };
3666
3667 /*
3668  * initialization verbs
3669  */
3670 static struct hda_verb alc260_init_verbs[] = {
3671         /* Line In pin widget for input */
3672         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3673         /* CD pin widget for input */
3674         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3675         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3676         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3677         /* Mic2 (front panel) pin widget for input and vref at 80% */
3678         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3679         /* LINE-2 is used for line-out in rear */
3680         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3681         /* select line-out */
3682         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3683         /* LINE-OUT pin */
3684         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3685         /* enable HP */
3686         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3687         /* enable Mono */
3688         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3689         /* mute capture amp left and right */
3690         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3691         /* set connection select to line in (default select for this ADC) */
3692         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3693         /* mute capture amp left and right */
3694         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3695         /* set connection select to line in (default select for this ADC) */
3696         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3697         /* set vol=0 Line-Out mixer amp left and right */
3698         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3699         /* unmute pin widget amp left and right (no gain on this amp) */
3700         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3701         /* set vol=0 HP mixer amp left and right */
3702         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3703         /* unmute pin widget amp left and right (no gain on this amp) */
3704         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3705         /* set vol=0 Mono mixer amp left and right */
3706         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3707         /* unmute pin widget amp left and right (no gain on this amp) */
3708         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3709         /* unmute LINE-2 out pin */
3710         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3711         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3712          * Line In 2 = 0x03
3713          */
3714         /* mute CD */
3715         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3716         /* mute Line In */
3717         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3718         /* mute Mic */
3719         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3720         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3721         /* mute Front out path */
3722         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3723         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3724         /* mute Headphone out path */
3725         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3726         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3727         /* mute Mono out path */
3728         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3729         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3730         { }
3731 };
3732
3733 #if 0 /* should be identical with alc260_init_verbs? */
3734 static struct hda_verb alc260_hp_init_verbs[] = {
3735         /* Headphone and output */
3736         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3737         /* mono output */
3738         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3739         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3740         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3741         /* Mic2 (front panel) pin widget for input and vref at 80% */
3742         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3743         /* Line In pin widget for input */
3744         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3745         /* Line-2 pin widget for output */
3746         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3747         /* CD pin widget for input */
3748         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3749         /* unmute amp left and right */
3750         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3751         /* set connection select to line in (default select for this ADC) */
3752         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3753         /* unmute Line-Out mixer amp left and right (volume = 0) */
3754         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3755         /* mute pin widget amp left and right (no gain on this amp) */
3756         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3757         /* unmute HP mixer amp left and right (volume = 0) */
3758         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3759         /* mute pin widget amp left and right (no gain on this amp) */
3760         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3761         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3762          * Line In 2 = 0x03
3763          */
3764         /* unmute CD */
3765         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3766         /* unmute Line In */
3767         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3768         /* unmute Mic */
3769         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3770         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3771         /* Unmute Front out path */
3772         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3773         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3774         /* Unmute Headphone out path */
3775         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3776         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3777         /* Unmute Mono out path */
3778         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3779         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3780         { }
3781 };
3782 #endif
3783
3784 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3785         /* Line out and output */
3786         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3787         /* mono output */
3788         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3789         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3790         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3791         /* Mic2 (front panel) pin widget for input and vref at 80% */
3792         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3793         /* Line In pin widget for input */
3794         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3795         /* Headphone pin widget for output */
3796         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3797         /* CD pin widget for input */
3798         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3799         /* unmute amp left and right */
3800         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3801         /* set connection select to line in (default select for this ADC) */
3802         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3803         /* unmute Line-Out mixer amp left and right (volume = 0) */
3804         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3805         /* mute pin widget amp left and right (no gain on this amp) */
3806         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3807         /* unmute HP mixer amp left and right (volume = 0) */
3808         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3809         /* mute pin widget amp left and right (no gain on this amp) */
3810         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3811         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3812          * Line In 2 = 0x03
3813          */
3814         /* unmute CD */
3815         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3816         /* unmute Line In */
3817         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3818         /* unmute Mic */
3819         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3820         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3821         /* Unmute Front out path */
3822         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3823         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3824         /* Unmute Headphone out path */
3825         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3826         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3827         /* Unmute Mono out path */
3828         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3829         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3830         { }
3831 };
3832
3833 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3834  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3835  * audio = 0x16, internal speaker = 0x10.
3836  */
3837 static struct hda_verb alc260_fujitsu_init_verbs[] = {
3838         /* Disable all GPIOs */
3839         {0x01, AC_VERB_SET_GPIO_MASK, 0},
3840         /* Internal speaker is connected to headphone pin */
3841         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3842         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3843         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3844         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3845         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3846         /* Ensure all other unused pins are disabled and muted. */
3847         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3848         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3849         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3850         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3851         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3852         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3853         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3854         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3855
3856         /* Disable digital (SPDIF) pins */
3857         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3858         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3859
3860         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
3861          * when acting as an output.
3862          */
3863         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3864
3865         /* Start with output sum widgets muted and their output gains at min */
3866         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3867         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3868         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3869         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3870         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3871         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3872         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3873         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3874         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3875
3876         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3877         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3878         /* Unmute Line1 pin widget output buffer since it starts as an output.
3879          * If the pin mode is changed by the user the pin mode control will
3880          * take care of enabling the pin's input/output buffers as needed.
3881          * Therefore there's no need to enable the input buffer at this
3882          * stage.
3883          */
3884         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3885         /* Unmute input buffer of pin widget used for Line-in (no equiv 
3886          * mixer ctrl)
3887          */
3888         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3889
3890         /* Mute capture amp left and right */
3891         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3892         /* Set ADC connection select to match default mixer setting - line 
3893          * in (on mic1 pin)
3894          */
3895         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3896
3897         /* Do the same for the second ADC: mute capture input amp and
3898          * set ADC connection to line in (on mic1 pin)
3899          */
3900         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3901         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3902
3903         /* Mute all inputs to mixer widget (even unconnected ones) */
3904         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3905         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3906         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3907         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3908         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3909         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3910         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3911         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3912
3913         { }
3914 };
3915
3916 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3917  * similar laptops (adapted from Fujitsu init verbs).
3918  */
3919 static struct hda_verb alc260_acer_init_verbs[] = {
3920         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3921          * the headphone jack.  Turn this on and rely on the standard mute
3922          * methods whenever the user wants to turn these outputs off.
3923          */
3924         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3925         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3926         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3927         /* Internal speaker/Headphone jack is connected to Line-out pin */
3928         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3929         /* Internal microphone/Mic jack is connected to Mic1 pin */
3930         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3931         /* Line In jack is connected to Line1 pin */
3932         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3933         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3934         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3935         /* Ensure all other unused pins are disabled and muted. */
3936         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3937         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3938         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3939         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3940         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3941         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3942         /* Disable digital (SPDIF) pins */
3943         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3944         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3945
3946         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
3947          * bus when acting as outputs.
3948          */
3949         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3950         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3951
3952         /* Start with output sum widgets muted and their output gains at min */
3953         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3954         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3955         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3956         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3957         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3958         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3959         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3960         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3961         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3962
3963         /* Unmute Line-out pin widget amp left and right
3964          * (no equiv mixer ctrl)
3965          */
3966         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3967         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3968         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3969         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3970          * inputs. If the pin mode is changed by the user the pin mode control
3971          * will take care of enabling the pin's input/output buffers as needed.
3972          * Therefore there's no need to enable the input buffer at this
3973          * stage.
3974          */
3975         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3976         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3977
3978         /* Mute capture amp left and right */
3979         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3980         /* Set ADC connection select to match default mixer setting - mic
3981          * (on mic1 pin)
3982          */
3983         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3984
3985         /* Do similar with the second ADC: mute capture input amp and
3986          * set ADC connection to mic to match ALSA's default state.
3987          */
3988         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3989         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3990
3991         /* Mute all inputs to mixer widget (even unconnected ones) */
3992         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3993         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3994         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3995         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3996         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3997         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3998         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3999         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4000
4001         { }
4002 };
4003
4004 static struct hda_verb alc260_will_verbs[] = {
4005         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4006         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4007         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4008         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4009         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4010         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4011         {}
4012 };
4013
4014 static struct hda_verb alc260_replacer_672v_verbs[] = {
4015         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4016         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4017         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4018
4019         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4020         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4021         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4022
4023         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4024         {}
4025 };
4026
4027 /* toggle speaker-output according to the hp-jack state */
4028 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4029 {
4030         unsigned int present;
4031
4032         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4033         present = snd_hda_codec_read(codec, 0x0f, 0,
4034                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4035         if (present) {
4036                 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
4037                 snd_hda_codec_write(codec, 0x0f, 0,
4038                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4039         } else {
4040                 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4041                 snd_hda_codec_write(codec, 0x0f, 0,
4042                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4043         }
4044 }
4045
4046 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4047                                        unsigned int res)
4048 {
4049         if ((res >> 26) == ALC880_HP_EVENT)
4050                 alc260_replacer_672v_automute(codec);
4051 }
4052
4053 /* Test configuration for debugging, modelled after the ALC880 test
4054  * configuration.
4055  */
4056 #ifdef CONFIG_SND_DEBUG
4057 static hda_nid_t alc260_test_dac_nids[1] = {
4058         0x02,
4059 };
4060 static hda_nid_t alc260_test_adc_nids[2] = {
4061         0x04, 0x05,
4062 };
4063 /* For testing the ALC260, each input MUX needs its own definition since
4064  * the signal assignments are different.  This assumes that the first ADC 
4065  * is NID 0x04.
4066  */
4067 static struct hda_input_mux alc260_test_capture_sources[2] = {
4068         {
4069                 .num_items = 7,
4070                 .items = {
4071                         { "MIC1 pin", 0x0 },
4072                         { "MIC2 pin", 0x1 },
4073                         { "LINE1 pin", 0x2 },
4074                         { "LINE2 pin", 0x3 },
4075                         { "CD pin", 0x4 },
4076                         { "LINE-OUT pin", 0x5 },
4077                         { "HP-OUT pin", 0x6 },
4078                 },
4079         },
4080         {
4081                 .num_items = 8,
4082                 .items = {
4083                         { "MIC1 pin", 0x0 },
4084                         { "MIC2 pin", 0x1 },
4085                         { "LINE1 pin", 0x2 },
4086                         { "LINE2 pin", 0x3 },
4087                         { "CD pin", 0x4 },
4088                         { "Mixer", 0x5 },
4089                         { "LINE-OUT pin", 0x6 },
4090                         { "HP-OUT pin", 0x7 },
4091                 },
4092         },
4093 };
4094 static struct snd_kcontrol_new alc260_test_mixer[] = {
4095         /* Output driver widgets */
4096         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4097         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4098         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4099         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4100         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4101         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4102
4103         /* Modes for retasking pin widgets
4104          * Note: the ALC260 doesn't seem to act on requests to enable mic
4105          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4106          * mention this restriction.  At this stage it's not clear whether
4107          * this behaviour is intentional or is a hardware bug in chip
4108          * revisions available at least up until early 2006.  Therefore for
4109          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4110          * choices, but if it turns out that the lack of mic bias for these
4111          * NIDs is intentional we could change their modes from
4112          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4113          */
4114         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4115         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4116         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4117         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4118         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4119         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4120
4121         /* Loopback mixer controls */
4122         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4123         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4124         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4125         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4126         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4127         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4128         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4129         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4130         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4131         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4132         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4133         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4134         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4135         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4136         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4137         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4138
4139         /* Controls for GPIO pins, assuming they are configured as outputs */
4140         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4141         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4142         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4143         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4144
4145         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4146          * is ambigious as to which NID is which; testing on laptops which
4147          * make this output available should provide clarification. 
4148          */
4149         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4150         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4151
4152         { } /* end */
4153 };
4154 static struct hda_verb alc260_test_init_verbs[] = {
4155         /* Enable all GPIOs as outputs with an initial value of 0 */
4156         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4157         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4158         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4159
4160         /* Enable retasking pins as output, initially without power amp */
4161         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4162         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4163         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4164         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4165         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4166         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4167
4168         /* Disable digital (SPDIF) pins initially, but users can enable
4169          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4170          * payload also sets the generation to 0, output to be in "consumer"
4171          * PCM format, copyright asserted, no pre-emphasis and no validity
4172          * control.
4173          */
4174         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4175         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4176
4177         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4178          * OUT1 sum bus when acting as an output.
4179          */
4180         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4181         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4182         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4183         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4184
4185         /* Start with output sum widgets muted and their output gains at min */
4186         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4187         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4188         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4189         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4190         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4191         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4192         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4193         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4194         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4195
4196         /* Unmute retasking pin widget output buffers since the default
4197          * state appears to be output.  As the pin mode is changed by the
4198          * user the pin mode control will take care of enabling the pin's
4199          * input/output buffers as needed.
4200          */
4201         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4202         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4203         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4204         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4205         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4206         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4207         /* Also unmute the mono-out pin widget */
4208         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4209
4210         /* Mute capture amp left and right */
4211         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4212         /* Set ADC connection select to match default mixer setting (mic1
4213          * pin)
4214          */
4215         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4216
4217         /* Do the same for the second ADC: mute capture input amp and
4218          * set ADC connection to mic1 pin
4219          */
4220         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4221         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4222
4223         /* Mute all inputs to mixer widget (even unconnected ones) */
4224         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4225         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4226         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4227         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4228         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4229         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4230         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4231         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4232
4233         { }
4234 };
4235 #endif
4236
4237 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4238         .substreams = 1,
4239         .channels_min = 2,
4240         .channels_max = 2,
4241 };
4242
4243 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4244         .substreams = 1,
4245         .channels_min = 2,
4246         .channels_max = 2,
4247 };
4248
4249 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4250 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4251
4252 /*
4253  * for BIOS auto-configuration
4254  */
4255
4256 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4257                                         const char *pfx)
4258 {
4259         hda_nid_t nid_vol;
4260         unsigned long vol_val, sw_val;
4261         char name[32];
4262         int err;
4263
4264         if (nid >= 0x0f && nid < 0x11) {
4265                 nid_vol = nid - 0x7;
4266                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4267                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4268         } else if (nid == 0x11) {
4269                 nid_vol = nid - 0x7;
4270                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4271                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4272         } else if (nid >= 0x12 && nid <= 0x15) {
4273                 nid_vol = 0x08;
4274                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4275                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4276         } else
4277                 return 0; /* N/A */
4278         
4279         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4280         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4281         if (err < 0)
4282                 return err;
4283         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4284         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4285         if (err < 0)
4286                 return err;
4287         return 1;
4288 }
4289
4290 /* add playback controls from the parsed DAC table */
4291 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4292                                              const struct auto_pin_cfg *cfg)
4293 {
4294         hda_nid_t nid;
4295         int err;
4296
4297         spec->multiout.num_dacs = 1;
4298         spec->multiout.dac_nids = spec->private_dac_nids;
4299         spec->multiout.dac_nids[0] = 0x02;
4300
4301         nid = cfg->line_out_pins[0];
4302         if (nid) {
4303                 err = alc260_add_playback_controls(spec, nid, "Front");
4304                 if (err < 0)
4305                         return err;
4306         }
4307
4308         nid = cfg->speaker_pins[0];
4309         if (nid) {
4310                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4311                 if (err < 0)
4312                         return err;
4313         }
4314
4315         nid = cfg->hp_pins[0];
4316         if (nid) {
4317                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4318                 if (err < 0)
4319                         return err;
4320         }
4321         return 0;
4322 }
4323
4324 /* create playback/capture controls for input pins */
4325 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4326                                                 const struct auto_pin_cfg *cfg)
4327 {
4328         struct hda_input_mux *imux = &spec->private_imux;
4329         int i, err, idx;
4330
4331         for (i = 0; i < AUTO_PIN_LAST; i++) {
4332                 if (cfg->input_pins[i] >= 0x12) {
4333                         idx = cfg->input_pins[i] - 0x12;
4334                         err = new_analog_input(spec, cfg->input_pins[i],
4335                                                auto_pin_cfg_labels[i], idx,
4336                                                0x07);
4337                         if (err < 0)
4338                                 return err;
4339                         imux->items[imux->num_items].label =
4340                                 auto_pin_cfg_labels[i];
4341                         imux->items[imux->num_items].index = idx;
4342                         imux->num_items++;
4343                 }
4344                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4345                         idx = cfg->input_pins[i] - 0x09;
4346                         err = new_analog_input(spec, cfg->input_pins[i],
4347                                                auto_pin_cfg_labels[i], idx,
4348                                                0x07);
4349                         if (err < 0)
4350                                 return err;
4351                         imux->items[imux->num_items].label =
4352                                 auto_pin_cfg_labels[i];
4353                         imux->items[imux->num_items].index = idx;
4354                         imux->num_items++;
4355                 }
4356         }
4357         return 0;
4358 }
4359
4360 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4361                                               hda_nid_t nid, int pin_type,
4362                                               int sel_idx)
4363 {
4364         /* set as output */
4365         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4366                             pin_type);
4367         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4368                             AMP_OUT_UNMUTE);
4369         /* need the manual connection? */
4370         if (nid >= 0x12) {
4371                 int idx = nid - 0x12;
4372                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4373                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4374         }
4375 }
4376
4377 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4378 {
4379         struct alc_spec *spec = codec->spec;
4380         hda_nid_t nid;
4381
4382         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4383         nid = spec->autocfg.line_out_pins[0];
4384         if (nid) {
4385                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4386                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4387         }
4388         
4389         nid = spec->autocfg.speaker_pins[0];
4390         if (nid)
4391                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4392
4393         nid = spec->autocfg.hp_pins[0];
4394         if (nid)
4395                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4396 }
4397
4398 #define ALC260_PIN_CD_NID               0x16
4399 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4400 {
4401         struct alc_spec *spec = codec->spec;
4402         int i;
4403
4404         for (i = 0; i < AUTO_PIN_LAST; i++) {
4405                 hda_nid_t nid = spec->autocfg.input_pins[i];
4406                 if (nid >= 0x12) {
4407                         snd_hda_codec_write(codec, nid, 0,
4408                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4409                                             i <= AUTO_PIN_FRONT_MIC ?
4410                                             PIN_VREF80 : PIN_IN);
4411                         if (nid != ALC260_PIN_CD_NID)
4412                                 snd_hda_codec_write(codec, nid, 0,
4413                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4414                                                     AMP_OUT_MUTE);
4415                 }
4416         }
4417 }
4418
4419 /*
4420  * generic initialization of ADC, input mixers and output mixers
4421  */
4422 static struct hda_verb alc260_volume_init_verbs[] = {
4423         /*
4424          * Unmute ADC0-1 and set the default input to mic-in
4425          */
4426         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4427         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4428         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4429         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4430         
4431         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4432          * mixer widget
4433          * Note: PASD motherboards uses the Line In 2 as the input for
4434          * front panel mic (mic 2)
4435          */
4436         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4437         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4438         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4439         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4440         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4441         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4442
4443         /*
4444          * Set up output mixers (0x08 - 0x0a)
4445          */
4446         /* set vol=0 to output mixers */
4447         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4448         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4449         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4450         /* set up input amps for analog loopback */
4451         /* Amp Indices: DAC = 0, mixer = 1 */
4452         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4453         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4454         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4455         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4456         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4457         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4458         
4459         { }
4460 };
4461
4462 static int alc260_parse_auto_config(struct hda_codec *codec)
4463 {
4464         struct alc_spec *spec = codec->spec;
4465         unsigned int wcap;
4466         int err;
4467         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4468
4469         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4470                                            alc260_ignore);
4471         if (err < 0)
4472                 return err;
4473         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4474         if (err < 0)
4475                 return err;
4476         if (!spec->kctl_alloc)
4477                 return 0; /* can't find valid BIOS pin config */
4478         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4479         if (err < 0)
4480                 return err;
4481
4482         spec->multiout.max_channels = 2;
4483
4484         if (spec->autocfg.dig_out_pin)
4485                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4486         if (spec->kctl_alloc)
4487                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4488
4489         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4490
4491         spec->num_mux_defs = 1;
4492         spec->input_mux = &spec->private_imux;
4493
4494         /* check whether NID 0x04 is valid */
4495         wcap = get_wcaps(codec, 0x04);
4496         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4497         if (wcap != AC_WID_AUD_IN) {
4498                 spec->adc_nids = alc260_adc_nids_alt;
4499                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4500                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4501         } else {
4502                 spec->adc_nids = alc260_adc_nids;
4503                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4504                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4505         }
4506         spec->num_mixers++;
4507
4508         return 1;
4509 }
4510
4511 /* additional initialization for auto-configuration model */
4512 static void alc260_auto_init(struct hda_codec *codec)
4513 {
4514         alc260_auto_init_multi_out(codec);
4515         alc260_auto_init_analog_input(codec);
4516 }
4517
4518 /*
4519  * ALC260 configurations
4520  */
4521 static const char *alc260_models[ALC260_MODEL_LAST] = {
4522         [ALC260_BASIC]          = "basic",
4523         [ALC260_HP]             = "hp",
4524         [ALC260_HP_3013]        = "hp-3013",
4525         [ALC260_FUJITSU_S702X]  = "fujitsu",
4526         [ALC260_ACER]           = "acer",
4527         [ALC260_WILL]           = "will",
4528         [ALC260_REPLACER_672V]  = "replacer",
4529 #ifdef CONFIG_SND_DEBUG
4530         [ALC260_TEST]           = "test",
4531 #endif
4532         [ALC260_AUTO]           = "auto",
4533 };
4534
4535 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4536         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4537         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4538         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4539         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4540         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4541         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4542         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4543         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4544         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4545         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4546         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4547         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4548         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4549         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4550         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4551         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4552         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4553         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4554         {}
4555 };
4556
4557 static struct alc_config_preset alc260_presets[] = {
4558         [ALC260_BASIC] = {
4559                 .mixers = { alc260_base_output_mixer,
4560                             alc260_input_mixer,
4561                             alc260_pc_beep_mixer,
4562                             alc260_capture_mixer },
4563                 .init_verbs = { alc260_init_verbs },
4564                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4565                 .dac_nids = alc260_dac_nids,
4566                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4567                 .adc_nids = alc260_adc_nids,
4568                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4569                 .channel_mode = alc260_modes,
4570                 .input_mux = &alc260_capture_source,
4571         },
4572         [ALC260_HP] = {
4573                 .mixers = { alc260_base_output_mixer,
4574                             alc260_input_mixer,
4575                             alc260_capture_alt_mixer },
4576                 .init_verbs = { alc260_init_verbs },
4577                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4578                 .dac_nids = alc260_dac_nids,
4579                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4580                 .adc_nids = alc260_hp_adc_nids,
4581                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4582                 .channel_mode = alc260_modes,
4583                 .input_mux = &alc260_capture_source,
4584         },
4585         [ALC260_HP_3013] = {
4586                 .mixers = { alc260_hp_3013_mixer,
4587                             alc260_input_mixer,
4588                             alc260_capture_alt_mixer },
4589                 .init_verbs = { alc260_hp_3013_init_verbs },
4590                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4591                 .dac_nids = alc260_dac_nids,
4592                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4593                 .adc_nids = alc260_hp_adc_nids,
4594                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4595                 .channel_mode = alc260_modes,
4596                 .input_mux = &alc260_capture_source,
4597         },
4598         [ALC260_FUJITSU_S702X] = {
4599                 .mixers = { alc260_fujitsu_mixer,
4600                             alc260_capture_mixer },
4601                 .init_verbs = { alc260_fujitsu_init_verbs },
4602                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4603                 .dac_nids = alc260_dac_nids,
4604                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4605                 .adc_nids = alc260_dual_adc_nids,
4606                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4607                 .channel_mode = alc260_modes,
4608                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4609                 .input_mux = alc260_fujitsu_capture_sources,
4610         },
4611         [ALC260_ACER] = {
4612                 .mixers = { alc260_acer_mixer,
4613                             alc260_capture_mixer },
4614                 .init_verbs = { alc260_acer_init_verbs },
4615                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4616                 .dac_nids = alc260_dac_nids,
4617                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4618                 .adc_nids = alc260_dual_adc_nids,
4619                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4620                 .channel_mode = alc260_modes,
4621                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4622                 .input_mux = alc260_acer_capture_sources,
4623         },
4624         [ALC260_WILL] = {
4625                 .mixers = { alc260_will_mixer,
4626                             alc260_capture_mixer },
4627                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4628                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4629                 .dac_nids = alc260_dac_nids,
4630                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4631                 .adc_nids = alc260_adc_nids,
4632                 .dig_out_nid = ALC260_DIGOUT_NID,
4633                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4634                 .channel_mode = alc260_modes,
4635                 .input_mux = &alc260_capture_source,
4636         },
4637         [ALC260_REPLACER_672V] = {
4638                 .mixers = { alc260_replacer_672v_mixer,
4639                             alc260_capture_mixer },
4640                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4641                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4642                 .dac_nids = alc260_dac_nids,
4643                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4644                 .adc_nids = alc260_adc_nids,
4645                 .dig_out_nid = ALC260_DIGOUT_NID,
4646                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4647                 .channel_mode = alc260_modes,
4648                 .input_mux = &alc260_capture_source,
4649                 .unsol_event = alc260_replacer_672v_unsol_event,
4650                 .init_hook = alc260_replacer_672v_automute,
4651         },
4652 #ifdef CONFIG_SND_DEBUG
4653         [ALC260_TEST] = {
4654                 .mixers = { alc260_test_mixer,
4655                             alc260_capture_mixer },
4656                 .init_verbs = { alc260_test_init_verbs },
4657                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4658                 .dac_nids = alc260_test_dac_nids,
4659                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4660                 .adc_nids = alc260_test_adc_nids,
4661                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4662                 .channel_mode = alc260_modes,
4663                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4664                 .input_mux = alc260_test_capture_sources,
4665         },
4666 #endif
4667 };
4668
4669 static int patch_alc260(struct hda_codec *codec)
4670 {
4671         struct alc_spec *spec;
4672         int err, board_config;
4673
4674         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4675         if (spec == NULL)
4676                 return -ENOMEM;
4677
4678         codec->spec = spec;
4679
4680         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4681                                                   alc260_models,
4682                                                   alc260_cfg_tbl);
4683         if (board_config < 0) {
4684                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4685                            "trying auto-probe from BIOS...\n");
4686                 board_config = ALC260_AUTO;
4687         }
4688
4689         if (board_config == ALC260_AUTO) {
4690                 /* automatic parse from the BIOS config */
4691                 err = alc260_parse_auto_config(codec);
4692                 if (err < 0) {
4693                         alc_free(codec);
4694                         return err;
4695                 } else if (!err) {
4696                         printk(KERN_INFO
4697                                "hda_codec: Cannot set up configuration "
4698                                "from BIOS.  Using base mode...\n");
4699                         board_config = ALC260_BASIC;
4700                 }
4701         }
4702
4703         if (board_config != ALC260_AUTO)
4704                 setup_preset(spec, &alc260_presets[board_config]);
4705
4706         spec->stream_name_analog = "ALC260 Analog";
4707         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4708         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4709
4710         spec->stream_name_digital = "ALC260 Digital";
4711         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4712         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4713
4714         codec->patch_ops = alc_patch_ops;
4715         if (board_config == ALC260_AUTO)
4716                 spec->init_hook = alc260_auto_init;
4717
4718         return 0;
4719 }
4720
4721
4722 /*
4723  * ALC882 support
4724  *
4725  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4726  * configuration.  Each pin widget can choose any input DACs and a mixer.
4727  * Each ADC is connected from a mixer of all inputs.  This makes possible
4728  * 6-channel independent captures.
4729  *
4730  * In addition, an independent DAC for the multi-playback (not used in this
4731  * driver yet).
4732  */
4733 #define ALC882_DIGOUT_NID       0x06
4734 #define ALC882_DIGIN_NID        0x0a
4735
4736 static struct hda_channel_mode alc882_ch_modes[1] = {
4737         { 8, NULL }
4738 };
4739
4740 static hda_nid_t alc882_dac_nids[4] = {
4741         /* front, rear, clfe, rear_surr */
4742         0x02, 0x03, 0x04, 0x05
4743 };
4744
4745 /* identical with ALC880 */
4746 #define alc882_adc_nids         alc880_adc_nids
4747 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4748
4749 /* input MUX */
4750 /* FIXME: should be a matrix-type input source selection */
4751
4752 static struct hda_input_mux alc882_capture_source = {
4753         .num_items = 4,
4754         .items = {
4755                 { "Mic", 0x0 },
4756                 { "Front Mic", 0x1 },
4757                 { "Line", 0x2 },
4758                 { "CD", 0x4 },
4759         },
4760 };
4761 #define alc882_mux_enum_info alc_mux_enum_info
4762 #define alc882_mux_enum_get alc_mux_enum_get
4763
4764 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4765                                struct snd_ctl_elem_value *ucontrol)
4766 {
4767         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4768         struct alc_spec *spec = codec->spec;
4769         const struct hda_input_mux *imux = spec->input_mux;
4770         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4771         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4772         hda_nid_t nid = capture_mixers[adc_idx];
4773         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4774         unsigned int i, idx;
4775
4776         idx = ucontrol->value.enumerated.item[0];
4777         if (idx >= imux->num_items)
4778                 idx = imux->num_items - 1;
4779         if (*cur_val == idx && !codec->in_resume)
4780                 return 0;
4781         for (i = 0; i < imux->num_items; i++) {
4782                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4783                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4784                                     v | (imux->items[i].index << 8));
4785         }
4786         *cur_val = idx;
4787         return 1;
4788 }
4789
4790 /*
4791  * 2ch mode
4792  */
4793 static struct hda_verb alc882_3ST_ch2_init[] = {
4794         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4795         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4796         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4797         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4798         { } /* end */
4799 };
4800
4801 /*
4802  * 6ch mode
4803  */
4804 static struct hda_verb alc882_3ST_ch6_init[] = {
4805         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4806         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4807         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4808         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4809         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4810         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4811         { } /* end */
4812 };
4813
4814 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4815         { 2, alc882_3ST_ch2_init },
4816         { 6, alc882_3ST_ch6_init },
4817 };
4818
4819 /*
4820  * 6ch mode
4821  */
4822 static struct hda_verb alc882_sixstack_ch6_init[] = {
4823         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4824         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4825         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4826         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4827         { } /* end */
4828 };
4829
4830 /*
4831  * 8ch mode
4832  */
4833 static struct hda_verb alc882_sixstack_ch8_init[] = {
4834         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4835         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4836         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4837         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4838         { } /* end */
4839 };
4840
4841 static struct hda_channel_mode alc882_sixstack_modes[2] = {
4842         { 6, alc882_sixstack_ch6_init },
4843         { 8, alc882_sixstack_ch8_init },
4844 };
4845
4846 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4847  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4848  */
4849 static struct snd_kcontrol_new alc882_base_mixer[] = {
4850         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4851         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4852         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4853         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4854         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4855         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4856         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4857         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4858         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4859         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4860         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4861         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4862         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4863         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4864         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4865         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4866         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4867         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4868         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4869         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4870         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4871         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4872         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4873         { } /* end */
4874 };
4875
4876 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4877         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4878         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4879         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4880         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4881         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4882         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4883         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4884         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4885         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4886         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4887         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4888         { } /* end */
4889 };
4890
4891 static struct snd_kcontrol_new alc882_targa_mixer[] = {
4892         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4893         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4894         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4895         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4896         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4897         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4898         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4899         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4900         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4901         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4902         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4903         { } /* end */
4904 };
4905
4906 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4907  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4908  */
4909 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4910         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4911         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4912         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4913         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4914         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4915         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4916         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4917         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4918         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4919         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4920         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4921         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4922         { } /* end */
4923 };
4924
4925 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4926         {
4927                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4928                 .name = "Channel Mode",
4929                 .info = alc_ch_mode_info,
4930                 .get = alc_ch_mode_get,
4931                 .put = alc_ch_mode_put,
4932         },
4933         { } /* end */
4934 };
4935
4936 static struct hda_verb alc882_init_verbs[] = {
4937         /* Front mixer: unmute input/output amp left and right (volume = 0) */
4938         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4939         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4940         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4941         /* Rear mixer */
4942         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4943         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4944         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4945         /* CLFE mixer */
4946         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4947         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4948         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4949         /* Side mixer */
4950         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4951         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4952         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4953
4954         /* Front Pin: output 0 (0x0c) */
4955         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4956         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4957         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4958         /* Rear Pin: output 1 (0x0d) */
4959         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4960         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4961         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4962         /* CLFE Pin: output 2 (0x0e) */
4963         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4964         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4965         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4966         /* Side Pin: output 3 (0x0f) */
4967         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4968         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4969         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4970         /* Mic (rear) pin: input vref at 80% */
4971         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4972         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4973         /* Front Mic pin: input vref at 80% */
4974         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4975         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4976         /* Line In pin: input */
4977         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4978         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4979         /* Line-2 In: Headphone output (output 0 - 0x0c) */
4980         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4981         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4982         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
4983         /* CD pin widget for input */
4984         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4985
4986         /* FIXME: use matrix-type input source selection */
4987         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4988         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4989         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4990         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4991         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4992         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4993         /* Input mixer2 */
4994         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4995         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4996         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4997         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4998         /* Input mixer3 */
4999         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5000         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5001         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5002         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5003         /* ADC1: mute amp left and right */
5004         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5005         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5006         /* ADC2: mute amp left and right */
5007         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5008         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5009         /* ADC3: mute amp left and right */
5010         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5011         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5012
5013         { }
5014 };
5015
5016 static struct hda_verb alc882_eapd_verbs[] = {
5017         /* change to EAPD mode */
5018         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5019         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5020         { }
5021 };
5022
5023 /* Mac Pro test */
5024 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5025         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5026         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5027         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5028         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5029         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5030         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5031         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5032         { } /* end */
5033 };
5034
5035 static struct hda_verb alc882_macpro_init_verbs[] = {
5036         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5037         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5038         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5039         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5040         /* Front Pin: output 0 (0x0c) */
5041         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5042         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5043         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5044         /* Front Mic pin: input vref at 80% */
5045         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5046         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5047         /* Speaker:  output */
5048         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5049         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5050         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5051         /* Headphone output (output 0 - 0x0c) */
5052         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5053         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5054         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5055
5056         /* FIXME: use matrix-type input source selection */
5057         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5058         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5059         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5060         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5061         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5062         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5063         /* Input mixer2 */
5064         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5065         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5066         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5067         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5068         /* Input mixer3 */
5069         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5070         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5071         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5072         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5073         /* ADC1: mute amp left and right */
5074         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5075         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5076         /* ADC2: mute amp left and right */
5077         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5078         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5079         /* ADC3: mute amp left and right */
5080         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5081         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5082
5083         { }
5084 };
5085
5086 static struct hda_verb alc882_targa_verbs[] = {
5087         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5088         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5089
5090         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5091         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5092         
5093         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5094         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5095         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5096
5097         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5098         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5099         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5100         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5101         { } /* end */
5102 };
5103
5104 /* toggle speaker-output according to the hp-jack state */
5105 static void alc882_targa_automute(struct hda_codec *codec)
5106 {
5107         unsigned int present;
5108  
5109         present = snd_hda_codec_read(codec, 0x14, 0,
5110                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5111         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5112                                  0x80, present ? 0x80 : 0);
5113         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5114                                  0x80, present ? 0x80 : 0);
5115         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5116 }
5117
5118 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5119 {
5120         /* Looks like the unsol event is incompatible with the standard
5121          * definition.  4bit tag is placed at 26 bit!
5122          */
5123         if (((res >> 26) == ALC880_HP_EVENT)) {
5124                 alc882_targa_automute(codec);
5125         }
5126 }
5127
5128 static struct hda_verb alc882_asus_a7j_verbs[] = {
5129         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5130         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5131
5132         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5133         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5134         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5135         
5136         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5137         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5138         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5139
5140         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5141         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5142         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5143         { } /* end */
5144 };
5145
5146 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5147 {
5148         unsigned int gpiostate, gpiomask, gpiodir;
5149
5150         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5151                                        AC_VERB_GET_GPIO_DATA, 0);
5152
5153         if (!muted)
5154                 gpiostate |= (1 << pin);
5155         else
5156                 gpiostate &= ~(1 << pin);
5157
5158         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5159                                       AC_VERB_GET_GPIO_MASK, 0);
5160         gpiomask |= (1 << pin);
5161
5162         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5163                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5164         gpiodir |= (1 << pin);
5165
5166
5167         snd_hda_codec_write(codec, codec->afg, 0,
5168                             AC_VERB_SET_GPIO_MASK, gpiomask);
5169         snd_hda_codec_write(codec, codec->afg, 0,
5170                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5171
5172         msleep(1);
5173
5174         snd_hda_codec_write(codec, codec->afg, 0,
5175                             AC_VERB_SET_GPIO_DATA, gpiostate);
5176 }
5177
5178 /*
5179  * generic initialization of ADC, input mixers and output mixers
5180  */
5181 static struct hda_verb alc882_auto_init_verbs[] = {
5182         /*
5183          * Unmute ADC0-2 and set the default input to mic-in
5184          */
5185         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5186         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5187         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5188         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5189         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5190         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5191
5192         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5193          * mixer widget
5194          * Note: PASD motherboards uses the Line In 2 as the input for
5195          * front panel mic (mic 2)
5196          */
5197         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5198         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5199         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5200         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5201         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5202         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5203
5204         /*
5205          * Set up output mixers (0x0c - 0x0f)
5206          */
5207         /* set vol=0 to output mixers */
5208         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5209         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5210         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5211         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5212         /* set up input amps for analog loopback */
5213         /* Amp Indices: DAC = 0, mixer = 1 */
5214         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5215         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5216         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5217         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5218         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5219         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5220         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5221         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5222         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5223         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5224
5225         /* FIXME: use matrix-type input source selection */
5226         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5227         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5228         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5229         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5230         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5231         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5232         /* Input mixer2 */
5233         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5234         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5235         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5236         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5237         /* Input mixer3 */
5238         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5239         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5240         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5241         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5242
5243         { }
5244 };
5245
5246 /* capture mixer elements */
5247 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5248         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5249         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5250         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5251         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5252         {
5253                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5254                 /* The multiple "Capture Source" controls confuse alsamixer
5255                  * So call somewhat different..
5256                  * FIXME: the controls appear in the "playback" view!
5257                  */
5258                 /* .name = "Capture Source", */
5259                 .name = "Input Source",
5260                 .count = 2,
5261                 .info = alc882_mux_enum_info,
5262                 .get = alc882_mux_enum_get,
5263                 .put = alc882_mux_enum_put,
5264         },
5265         { } /* end */
5266 };
5267
5268 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5269         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5270         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5271         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5272         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5273         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5274         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5275         {
5276                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5277                 /* The multiple "Capture Source" controls confuse alsamixer
5278                  * So call somewhat different..
5279                  * FIXME: the controls appear in the "playback" view!
5280                  */
5281                 /* .name = "Capture Source", */
5282                 .name = "Input Source",
5283                 .count = 3,
5284                 .info = alc882_mux_enum_info,
5285                 .get = alc882_mux_enum_get,
5286                 .put = alc882_mux_enum_put,
5287         },
5288         { } /* end */
5289 };
5290
5291 /* pcm configuration: identiacal with ALC880 */
5292 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5293 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5294 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5295 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5296
5297 /*
5298  * configuration and preset
5299  */
5300 static const char *alc882_models[ALC882_MODEL_LAST] = {
5301         [ALC882_3ST_DIG]        = "3stack-dig",
5302         [ALC882_6ST_DIG]        = "6stack-dig",
5303         [ALC882_ARIMA]          = "arima",
5304         [ALC882_W2JC]           = "w2jc",
5305         [ALC885_MACPRO]         = "macpro",
5306         [ALC882_AUTO]           = "auto",
5307 };
5308
5309 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5310         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5311         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5312         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5313         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5314         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5315         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5316         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5317         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5318         {}
5319 };
5320
5321 static struct alc_config_preset alc882_presets[] = {
5322         [ALC882_3ST_DIG] = {
5323                 .mixers = { alc882_base_mixer },
5324                 .init_verbs = { alc882_init_verbs },
5325                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5326                 .dac_nids = alc882_dac_nids,
5327                 .dig_out_nid = ALC882_DIGOUT_NID,
5328                 .dig_in_nid = ALC882_DIGIN_NID,
5329                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5330                 .channel_mode = alc882_ch_modes,
5331                 .need_dac_fix = 1,
5332                 .input_mux = &alc882_capture_source,
5333         },
5334         [ALC882_6ST_DIG] = {
5335                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5336                 .init_verbs = { alc882_init_verbs },
5337                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5338                 .dac_nids = alc882_dac_nids,
5339                 .dig_out_nid = ALC882_DIGOUT_NID,
5340                 .dig_in_nid = ALC882_DIGIN_NID,
5341                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5342                 .channel_mode = alc882_sixstack_modes,
5343                 .input_mux = &alc882_capture_source,
5344         },
5345         [ALC882_ARIMA] = {
5346                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5347                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5348                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5349                 .dac_nids = alc882_dac_nids,
5350                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5351                 .channel_mode = alc882_sixstack_modes,
5352                 .input_mux = &alc882_capture_source,
5353         },
5354         [ALC882_W2JC] = {
5355                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5356                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5357                                 alc880_gpio1_init_verbs },
5358                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5359                 .dac_nids = alc882_dac_nids,
5360                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5361                 .channel_mode = alc880_threestack_modes,
5362                 .need_dac_fix = 1,
5363                 .input_mux = &alc882_capture_source,
5364                 .dig_out_nid = ALC882_DIGOUT_NID,
5365         },
5366         [ALC885_MACPRO] = {
5367                 .mixers = { alc882_macpro_mixer },
5368                 .init_verbs = { alc882_macpro_init_verbs },
5369                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5370                 .dac_nids = alc882_dac_nids,
5371                 .dig_out_nid = ALC882_DIGOUT_NID,
5372                 .dig_in_nid = ALC882_DIGIN_NID,
5373                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5374                 .channel_mode = alc882_ch_modes,
5375                 .input_mux = &alc882_capture_source,
5376         },
5377         [ALC882_TARGA] = {
5378                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5379                             alc882_capture_mixer },
5380                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5381                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5382                 .dac_nids = alc882_dac_nids,
5383                 .dig_out_nid = ALC882_DIGOUT_NID,
5384                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5385                 .adc_nids = alc882_adc_nids,
5386                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5387                 .channel_mode = alc882_3ST_6ch_modes,
5388                 .need_dac_fix = 1,
5389                 .input_mux = &alc882_capture_source,
5390                 .unsol_event = alc882_targa_unsol_event,
5391                 .init_hook = alc882_targa_automute,
5392         },
5393         [ALC882_ASUS_A7J] = {
5394                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5395                             alc882_capture_mixer },
5396                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5397                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5398                 .dac_nids = alc882_dac_nids,
5399                 .dig_out_nid = ALC882_DIGOUT_NID,
5400                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5401                 .adc_nids = alc882_adc_nids,
5402                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5403                 .channel_mode = alc882_3ST_6ch_modes,
5404                 .need_dac_fix = 1,
5405                 .input_mux = &alc882_capture_source,
5406         },      
5407 };
5408
5409
5410 /*
5411  * BIOS auto configuration
5412  */
5413 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5414                                               hda_nid_t nid, int pin_type,
5415                                               int dac_idx)
5416 {
5417         /* set as output */
5418         struct alc_spec *spec = codec->spec;
5419         int idx;
5420
5421         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5422                 idx = 4;
5423         else
5424                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5425
5426         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5427                             pin_type);
5428         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5429                             AMP_OUT_UNMUTE);
5430         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5431
5432 }
5433
5434 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5435 {
5436         struct alc_spec *spec = codec->spec;
5437         int i;
5438
5439         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5440         for (i = 0; i <= HDA_SIDE; i++) {
5441                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5442                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5443                 if (nid)
5444                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5445                                                           i);
5446         }
5447 }
5448
5449 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5450 {
5451         struct alc_spec *spec = codec->spec;
5452         hda_nid_t pin;
5453
5454         pin = spec->autocfg.hp_pins[0];
5455         if (pin) /* connect to front */
5456                 /* use dac 0 */
5457                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5458 }
5459
5460 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5461 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5462
5463 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5464 {
5465         struct alc_spec *spec = codec->spec;
5466         int i;
5467
5468         for (i = 0; i < AUTO_PIN_LAST; i++) {
5469                 hda_nid_t nid = spec->autocfg.input_pins[i];
5470                 if (alc882_is_input_pin(nid)) {
5471                         snd_hda_codec_write(codec, nid, 0,
5472                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5473                                             i <= AUTO_PIN_FRONT_MIC ?
5474                                             PIN_VREF80 : PIN_IN);
5475                         if (nid != ALC882_PIN_CD_NID)
5476                                 snd_hda_codec_write(codec, nid, 0,
5477                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5478                                                     AMP_OUT_MUTE);
5479                 }
5480         }
5481 }
5482
5483 /* almost identical with ALC880 parser... */
5484 static int alc882_parse_auto_config(struct hda_codec *codec)
5485 {
5486         struct alc_spec *spec = codec->spec;
5487         int err = alc880_parse_auto_config(codec);
5488
5489         if (err < 0)
5490                 return err;
5491         else if (err > 0)
5492                 /* hack - override the init verbs */
5493                 spec->init_verbs[0] = alc882_auto_init_verbs;
5494         return err;
5495 }
5496
5497 /* additional initialization for auto-configuration model */
5498 static void alc882_auto_init(struct hda_codec *codec)
5499 {
5500         alc882_auto_init_multi_out(codec);
5501         alc882_auto_init_hp_out(codec);
5502         alc882_auto_init_analog_input(codec);
5503 }
5504
5505 static int patch_alc882(struct hda_codec *codec)
5506 {
5507         struct alc_spec *spec;
5508         int err, board_config;
5509
5510         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5511         if (spec == NULL)
5512                 return -ENOMEM;
5513
5514         codec->spec = spec;
5515
5516         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5517                                                   alc882_models,
5518                                                   alc882_cfg_tbl);
5519
5520         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5521                 /* Pick up systems that don't supply PCI SSID */
5522                 switch (codec->subsystem_id) {
5523                 case 0x106b0c00: /* Mac Pro */
5524                         board_config = ALC885_MACPRO;
5525                         break;
5526                 default:
5527                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5528                                          "trying auto-probe from BIOS...\n");
5529                         board_config = ALC882_AUTO;
5530                 }
5531         }
5532
5533         if (board_config == ALC882_AUTO) {
5534                 /* automatic parse from the BIOS config */
5535                 err = alc882_parse_auto_config(codec);
5536                 if (err < 0) {
5537                         alc_free(codec);
5538                         return err;
5539                 } else if (!err) {
5540                         printk(KERN_INFO
5541                                "hda_codec: Cannot set up configuration "
5542                                "from BIOS.  Using base mode...\n");
5543                         board_config = ALC882_3ST_DIG;
5544                 }
5545         }
5546
5547         if (board_config != ALC882_AUTO)
5548                 setup_preset(spec, &alc882_presets[board_config]);
5549
5550         if (board_config == ALC885_MACPRO) {
5551                 alc882_gpio_mute(codec, 0, 0);
5552                 alc882_gpio_mute(codec, 1, 0);
5553         }
5554
5555         spec->stream_name_analog = "ALC882 Analog";
5556         spec->stream_analog_playback = &alc882_pcm_analog_playback;
5557         spec->stream_analog_capture = &alc882_pcm_analog_capture;
5558
5559         spec->stream_name_digital = "ALC882 Digital";
5560         spec->stream_digital_playback = &alc882_pcm_digital_playback;
5561         spec->stream_digital_capture = &alc882_pcm_digital_capture;
5562
5563         if (!spec->adc_nids && spec->input_mux) {
5564                 /* check whether NID 0x07 is valid */
5565                 unsigned int wcap = get_wcaps(codec, 0x07);
5566                 /* get type */
5567                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5568                 if (wcap != AC_WID_AUD_IN) {
5569                         spec->adc_nids = alc882_adc_nids_alt;
5570                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5571                         spec->mixers[spec->num_mixers] =
5572                                 alc882_capture_alt_mixer;
5573                         spec->num_mixers++;
5574                 } else {
5575                         spec->adc_nids = alc882_adc_nids;
5576                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5577                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5578                         spec->num_mixers++;
5579                 }
5580         }
5581
5582         codec->patch_ops = alc_patch_ops;
5583         if (board_config == ALC882_AUTO)
5584                 spec->init_hook = alc882_auto_init;
5585
5586         return 0;
5587 }
5588
5589 /*
5590  * ALC883 support
5591  *
5592  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5593  * configuration.  Each pin widget can choose any input DACs and a mixer.
5594  * Each ADC is connected from a mixer of all inputs.  This makes possible
5595  * 6-channel independent captures.
5596  *
5597  * In addition, an independent DAC for the multi-playback (not used in this
5598  * driver yet).
5599  */
5600 #define ALC883_DIGOUT_NID       0x06
5601 #define ALC883_DIGIN_NID        0x0a
5602
5603 static hda_nid_t alc883_dac_nids[4] = {
5604         /* front, rear, clfe, rear_surr */
5605         0x02, 0x04, 0x03, 0x05
5606 };
5607
5608 static hda_nid_t alc883_adc_nids[2] = {
5609         /* ADC1-2 */
5610         0x08, 0x09,
5611 };
5612
5613 /* input MUX */
5614 /* FIXME: should be a matrix-type input source selection */
5615
5616 static struct hda_input_mux alc883_capture_source = {
5617         .num_items = 4,
5618         .items = {
5619                 { "Mic", 0x0 },
5620                 { "Front Mic", 0x1 },
5621                 { "Line", 0x2 },
5622                 { "CD", 0x4 },
5623         },
5624 };
5625
5626 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5627         .num_items = 2,
5628         .items = {
5629                 { "Mic", 0x1 },
5630                 { "Line", 0x2 },
5631         },
5632 };
5633
5634 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5635         .num_items = 4,
5636         .items = {
5637                 { "Mic", 0x0 },
5638                 { "iMic", 0x1 },
5639                 { "Line", 0x2 },
5640                 { "CD", 0x4 },
5641         },
5642 };
5643
5644 #define alc883_mux_enum_info alc_mux_enum_info
5645 #define alc883_mux_enum_get alc_mux_enum_get
5646
5647 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5648                                struct snd_ctl_elem_value *ucontrol)
5649 {
5650         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5651         struct alc_spec *spec = codec->spec;
5652         const struct hda_input_mux *imux = spec->input_mux;
5653         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5654         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5655         hda_nid_t nid = capture_mixers[adc_idx];
5656         unsigned int *cur_val = &spec->cur_mux[adc_idx];
5657         unsigned int i, idx;
5658
5659         idx = ucontrol->value.enumerated.item[0];
5660         if (idx >= imux->num_items)
5661                 idx = imux->num_items - 1;
5662         if (*cur_val == idx && !codec->in_resume)
5663                 return 0;
5664         for (i = 0; i < imux->num_items; i++) {
5665                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
5666                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5667                                     v | (imux->items[i].index << 8));
5668         }
5669         *cur_val = idx;
5670         return 1;
5671 }
5672
5673 /*
5674  * 2ch mode
5675  */
5676 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5677         { 2, NULL }
5678 };
5679
5680 /*
5681  * 2ch mode
5682  */
5683 static struct hda_verb alc883_3ST_ch2_init[] = {
5684         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5685         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5686         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5687         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5688         { } /* end */
5689 };
5690
5691 /*
5692  * 6ch mode
5693  */
5694 static struct hda_verb alc883_3ST_ch6_init[] = {
5695         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5696         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5697         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5698         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5699         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5700         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5701         { } /* end */
5702 };
5703
5704 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5705         { 2, alc883_3ST_ch2_init },
5706         { 6, alc883_3ST_ch6_init },
5707 };
5708
5709 /*
5710  * 6ch mode
5711  */
5712 static struct hda_verb alc883_sixstack_ch6_init[] = {
5713         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5714         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5715         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5716         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5717         { } /* end */
5718 };
5719
5720 /*
5721  * 8ch mode
5722  */
5723 static struct hda_verb alc883_sixstack_ch8_init[] = {
5724         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5725         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5726         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5727         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5728         { } /* end */
5729 };
5730
5731 static struct hda_channel_mode alc883_sixstack_modes[2] = {
5732         { 6, alc883_sixstack_ch6_init },
5733         { 8, alc883_sixstack_ch8_init },
5734 };
5735
5736 static struct hda_verb alc883_medion_eapd_verbs[] = {
5737         /* eanable EAPD on medion laptop */
5738         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5739         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5740         { }
5741 };
5742
5743 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5744  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5745  */
5746
5747 static struct snd_kcontrol_new alc883_base_mixer[] = {
5748         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5749         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5750         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5751         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5752         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5753         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5754         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5755         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5756         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5757         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5758         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5759         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5760         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5761         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5762         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5763         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5764         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5765         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5766         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5767         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5768         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5769         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5770         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5771         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5772         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5773         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5774         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5775         {
5776                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5777                 /* .name = "Capture Source", */
5778                 .name = "Input Source",
5779                 .count = 2,
5780                 .info = alc883_mux_enum_info,
5781                 .get = alc883_mux_enum_get,
5782                 .put = alc883_mux_enum_put,
5783         },
5784         { } /* end */
5785 };
5786
5787 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5788         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5789         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5790         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5791         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5792         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5793         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5794         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5795         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5796         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5797         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5798         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5799         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5800         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5801         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5802         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5803         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5804         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5805         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5806         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5807         {
5808                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5809                 /* .name = "Capture Source", */
5810                 .name = "Input Source",
5811                 .count = 2,
5812                 .info = alc883_mux_enum_info,
5813                 .get = alc883_mux_enum_get,
5814                 .put = alc883_mux_enum_put,
5815         },
5816         { } /* end */
5817 };
5818
5819 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5820         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5821         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5822         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5823         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5824         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5825         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5826         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5827         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5828         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5829         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5830         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5831         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5832         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5833         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5834         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5835         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5836         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5837         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5838         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5839         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5840         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5841         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5842         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5843         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5844         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5845         {
5846                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5847                 /* .name = "Capture Source", */
5848                 .name = "Input Source",
5849                 .count = 2,
5850                 .info = alc883_mux_enum_info,
5851                 .get = alc883_mux_enum_get,
5852                 .put = alc883_mux_enum_put,
5853         },
5854         { } /* end */
5855 };
5856
5857 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5858         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5859         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5860         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5861         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5862         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5863         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5864         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5865         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5866         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5867         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5868         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5869         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5870         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5871         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5872         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5873         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5874         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5875         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5876         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5877         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5878         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5879         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5880         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5881
5882         {
5883                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5884                 /* .name = "Capture Source", */
5885                 .name = "Input Source",
5886                 .count = 1,
5887                 .info = alc883_mux_enum_info,
5888                 .get = alc883_mux_enum_get,
5889                 .put = alc883_mux_enum_put,
5890         },
5891         { } /* end */
5892 };
5893
5894 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5895         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5896         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5897         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5898         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5899         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5900         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5901         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5902         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5903         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5904         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5905         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5906         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5907         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5908         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5909         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5910         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5911         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5912         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5913         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5914         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5915         {
5916                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5917                 /* .name = "Capture Source", */
5918                 .name = "Input Source",
5919                 .count = 2,
5920                 .info = alc883_mux_enum_info,
5921                 .get = alc883_mux_enum_get,
5922                 .put = alc883_mux_enum_put,
5923         },
5924         { } /* end */
5925 };
5926
5927 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5928         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5929         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5930         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5931         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5932         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5933         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5934         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5935         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5936         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5937         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5938         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5939         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5940         {
5941                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5942                 /* .name = "Capture Source", */
5943                 .name = "Input Source",
5944                 .count = 2,
5945                 .info = alc883_mux_enum_info,
5946                 .get = alc883_mux_enum_get,
5947                 .put = alc883_mux_enum_put,
5948         },
5949         { } /* end */
5950 };
5951
5952 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
5953         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5954         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5955         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5956         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
5957         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5958         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5959         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5960         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5961         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5962         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5963         {
5964                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5965                 /* .name = "Capture Source", */
5966                 .name = "Input Source",
5967                 .count = 1,
5968                 .info = alc883_mux_enum_info,
5969                 .get = alc883_mux_enum_get,
5970                 .put = alc883_mux_enum_put,
5971         },
5972         { } /* end */
5973 };
5974
5975 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
5976         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5977         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
5978         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5979         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5980         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5981         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5982         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5983         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5984         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5985         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5986         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5987         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5988         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5989         {
5990                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5991                 /* .name = "Capture Source", */
5992                 .name = "Input Source",
5993                 .count = 2,
5994                 .info = alc883_mux_enum_info,
5995                 .get = alc883_mux_enum_get,
5996                 .put = alc883_mux_enum_put,
5997         },
5998         { } /* end */
5999 };
6000
6001 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6002         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6003         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6004         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6005         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6006         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6007         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6008         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6009         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6010         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6011         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6012         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6013         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6014         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6015         {
6016                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6017                 /* .name = "Capture Source", */
6018                 .name = "Input Source",
6019                 .count = 2,
6020                 .info = alc883_mux_enum_info,
6021                 .get = alc883_mux_enum_get,
6022                 .put = alc883_mux_enum_put,
6023         },
6024         { } /* end */
6025 };      
6026
6027 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6028         {
6029                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6030                 .name = "Channel Mode",
6031                 .info = alc_ch_mode_info,
6032                 .get = alc_ch_mode_get,
6033                 .put = alc_ch_mode_put,
6034         },
6035         { } /* end */
6036 };
6037
6038 static struct hda_verb alc883_init_verbs[] = {
6039         /* ADC1: mute amp left and right */
6040         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6041         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6042         /* ADC2: mute amp left and right */
6043         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6044         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6045         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6046         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6047         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6048         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6049         /* Rear mixer */
6050         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6051         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6052         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6053         /* CLFE mixer */
6054         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6055         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6056         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6057         /* Side mixer */
6058         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6059         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6060         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6061
6062         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6063         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6064         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6065         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6066         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6067
6068         /* Front Pin: output 0 (0x0c) */
6069         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6070         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6071         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6072         /* Rear Pin: output 1 (0x0d) */
6073         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6074         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6075         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6076         /* CLFE Pin: output 2 (0x0e) */
6077         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6078         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6079         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6080         /* Side Pin: output 3 (0x0f) */
6081         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6082         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6083         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6084         /* Mic (rear) pin: input vref at 80% */
6085         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6086         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6087         /* Front Mic pin: input vref at 80% */
6088         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6089         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6090         /* Line In pin: input */
6091         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6092         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6093         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6094         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6095         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6096         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6097         /* CD pin widget for input */
6098         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6099
6100         /* FIXME: use matrix-type input source selection */
6101         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6102         /* Input mixer2 */
6103         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6104         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6105         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6106         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6107         /* Input mixer3 */
6108         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6109         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6110         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6111         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6112         { }
6113 };
6114
6115 static struct hda_verb alc883_tagra_verbs[] = {
6116         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6117         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6118
6119         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6120         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6121         
6122         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6123         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6124         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6125
6126         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6127         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6128         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6129         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6130
6131         { } /* end */
6132 };
6133
6134 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6135         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6136         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6137         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6138         { } /* end */
6139 };
6140
6141 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6142         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6143         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6144         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6145         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6146         { } /* end */
6147 };
6148
6149 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6150         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6151         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6152         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6153         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6154         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6155         { } /* end */
6156 };
6157
6158 /* toggle front-jack and RCA according to the hp-jack state */
6159 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6160 {
6161         unsigned int present;
6162  
6163         present = snd_hda_codec_read(codec, 0x1b, 0,
6164                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6165         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6166                                  0x80, present ? 0x80 : 0);
6167         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6168                                  0x80, present ? 0x80 : 0);
6169         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6170                                  0x80, present ? 0x80 : 0);
6171         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6172                                  0x80, present ? 0x80 : 0);
6173         
6174 }
6175
6176 /* toggle RCA according to the front-jack state */
6177 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6178 {
6179         unsigned int present;
6180  
6181         present = snd_hda_codec_read(codec, 0x14, 0,
6182                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6183         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6184                                  0x80, present ? 0x80 : 0);
6185         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6186                                  0x80, present ? 0x80 : 0);
6187         
6188 }
6189 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6190                                              unsigned int res)
6191 {
6192         if ((res >> 26) == ALC880_HP_EVENT)
6193                 alc888_lenovo_ms7195_front_automute(codec);
6194         if ((res >> 26) == ALC880_FRONT_EVENT)
6195                 alc888_lenovo_ms7195_rca_automute(codec);
6196 }
6197
6198 static struct hda_verb alc883_medion_md2_verbs[] = {
6199         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6200         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6201
6202         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6203
6204         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6205         { } /* end */
6206 };
6207
6208 /* toggle speaker-output according to the hp-jack state */
6209 static void alc883_medion_md2_automute(struct hda_codec *codec)
6210 {
6211         unsigned int present;
6212  
6213         present = snd_hda_codec_read(codec, 0x14, 0,
6214                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6215         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6216                                  0x80, present ? 0x80 : 0);
6217         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6218                                  0x80, present ? 0x80 : 0);
6219 }
6220
6221 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6222                                           unsigned int res)
6223 {
6224         if ((res >> 26) == ALC880_HP_EVENT)
6225                 alc883_medion_md2_automute(codec);
6226 }
6227
6228 /* toggle speaker-output according to the hp-jack state */
6229 static void alc883_tagra_automute(struct hda_codec *codec)
6230 {
6231         unsigned int present;
6232         unsigned char bits;
6233
6234         present = snd_hda_codec_read(codec, 0x14, 0,
6235                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6236         bits = present ? 0x80 : 0;
6237         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
6238                                  0x80, bits);
6239         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
6240                                  0x80, bits);
6241         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6242                             present ? 1 : 3);
6243 }
6244
6245 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6246 {
6247         if ((res >> 26) == ALC880_HP_EVENT)
6248                 alc883_tagra_automute(codec);
6249 }
6250
6251 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6252 {
6253         unsigned int present;
6254         unsigned char bits;
6255
6256         present = snd_hda_codec_read(codec, 0x14, 0,
6257                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6258         bits = present ? 0x80 : 0;
6259         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6260                                  0x80, bits);
6261         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6262                                  0x80, bits);
6263 }
6264
6265 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6266 {
6267         unsigned int present;
6268         unsigned char bits;
6269
6270         present = snd_hda_codec_read(codec, 0x1b, 0,
6271                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6272         bits = present ? 0x80 : 0;
6273         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6274                                  0x80, bits);
6275         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6276                                  0x80, bits);
6277         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6278                                  0x80, bits);
6279         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6280                                  0x80, bits);
6281 }
6282
6283 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6284                                            unsigned int res)
6285 {
6286         if ((res >> 26) == ALC880_HP_EVENT)
6287                 alc883_lenovo_101e_all_automute(codec);
6288         if ((res >> 26) == ALC880_FRONT_EVENT)
6289                 alc883_lenovo_101e_ispeaker_automute(codec);
6290 }
6291
6292 /*
6293  * generic initialization of ADC, input mixers and output mixers
6294  */
6295 static struct hda_verb alc883_auto_init_verbs[] = {
6296         /*
6297          * Unmute ADC0-2 and set the default input to mic-in
6298          */
6299         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6300         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6301         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6302         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6303
6304         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6305          * mixer widget
6306          * Note: PASD motherboards uses the Line In 2 as the input for
6307          * front panel mic (mic 2)
6308          */
6309         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6310         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6311         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6312         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6313         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6314         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6315
6316         /*
6317          * Set up output mixers (0x0c - 0x0f)
6318          */
6319         /* set vol=0 to output mixers */
6320         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6321         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6322         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6323         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6324         /* set up input amps for analog loopback */
6325         /* Amp Indices: DAC = 0, mixer = 1 */
6326         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6327         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6328         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6329         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6330         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6331         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6332         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6333         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6334         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6335         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6336
6337         /* FIXME: use matrix-type input source selection */
6338         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6339         /* Input mixer1 */
6340         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6341         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6342         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6343         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6344         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6345         /* Input mixer2 */
6346         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6347         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6348         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6349         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6350         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6351
6352         { }
6353 };
6354
6355 /* capture mixer elements */
6356 static struct snd_kcontrol_new alc883_capture_mixer[] = {
6357         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6358         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6359         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6360         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6361         {
6362                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6363                 /* The multiple "Capture Source" controls confuse alsamixer
6364                  * So call somewhat different..
6365                  * FIXME: the controls appear in the "playback" view!
6366                  */
6367                 /* .name = "Capture Source", */
6368                 .name = "Input Source",
6369                 .count = 2,
6370                 .info = alc882_mux_enum_info,
6371                 .get = alc882_mux_enum_get,
6372                 .put = alc882_mux_enum_put,
6373         },
6374         { } /* end */
6375 };
6376
6377 /* pcm configuration: identiacal with ALC880 */
6378 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
6379 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
6380 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
6381 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
6382
6383 /*
6384  * configuration and preset
6385  */
6386 static const char *alc883_models[ALC883_MODEL_LAST] = {
6387         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
6388         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
6389         [ALC883_3ST_6ch]        = "3stack-6ch",
6390         [ALC883_6ST_DIG]        = "6stack-dig",
6391         [ALC883_TARGA_DIG]      = "targa-dig",
6392         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
6393         [ALC883_ACER]           = "acer",
6394         [ALC883_MEDION]         = "medion",
6395         [ALC883_MEDION_MD2]     = "medion-md2",
6396         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
6397         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6398         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
6399         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6400         [ALC883_AUTO]           = "auto",
6401 };
6402
6403 static struct snd_pci_quirk alc883_cfg_tbl[] = {
6404         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6405         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6406         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6407         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6408         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6409         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6410         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6411         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6412         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6413         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6414         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6415         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6416         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6417         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6418         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6419         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6420         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6421         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6422         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6423         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6424         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6425         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6426         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6427         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6428         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6429         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6430         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6431         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6432         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6433         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6434         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
6435         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6436         {}
6437 };
6438
6439 static struct alc_config_preset alc883_presets[] = {
6440         [ALC883_3ST_2ch_DIG] = {
6441                 .mixers = { alc883_3ST_2ch_mixer },
6442                 .init_verbs = { alc883_init_verbs },
6443                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6444                 .dac_nids = alc883_dac_nids,
6445                 .dig_out_nid = ALC883_DIGOUT_NID,
6446                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6447                 .adc_nids = alc883_adc_nids,
6448                 .dig_in_nid = ALC883_DIGIN_NID,
6449                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6450                 .channel_mode = alc883_3ST_2ch_modes,
6451                 .input_mux = &alc883_capture_source,
6452         },
6453         [ALC883_3ST_6ch_DIG] = {
6454                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6455                 .init_verbs = { alc883_init_verbs },
6456                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6457                 .dac_nids = alc883_dac_nids,
6458                 .dig_out_nid = ALC883_DIGOUT_NID,
6459                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6460                 .adc_nids = alc883_adc_nids,
6461                 .dig_in_nid = ALC883_DIGIN_NID,
6462                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6463                 .channel_mode = alc883_3ST_6ch_modes,
6464                 .need_dac_fix = 1,
6465                 .input_mux = &alc883_capture_source,
6466         },
6467         [ALC883_3ST_6ch] = {
6468                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6469                 .init_verbs = { alc883_init_verbs },
6470                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6471                 .dac_nids = alc883_dac_nids,
6472                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6473                 .adc_nids = alc883_adc_nids,
6474                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6475                 .channel_mode = alc883_3ST_6ch_modes,
6476                 .need_dac_fix = 1,
6477                 .input_mux = &alc883_capture_source,
6478         },
6479         [ALC883_6ST_DIG] = {
6480                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
6481                 .init_verbs = { alc883_init_verbs },
6482                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6483                 .dac_nids = alc883_dac_nids,
6484                 .dig_out_nid = ALC883_DIGOUT_NID,
6485                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6486                 .adc_nids = alc883_adc_nids,
6487                 .dig_in_nid = ALC883_DIGIN_NID,
6488                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6489                 .channel_mode = alc883_sixstack_modes,
6490                 .input_mux = &alc883_capture_source,
6491         },
6492         [ALC883_TARGA_DIG] = {
6493                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6494                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6495                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6496                 .dac_nids = alc883_dac_nids,
6497                 .dig_out_nid = ALC883_DIGOUT_NID,
6498                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6499                 .adc_nids = alc883_adc_nids,
6500                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6501                 .channel_mode = alc883_3ST_6ch_modes,
6502                 .need_dac_fix = 1,
6503                 .input_mux = &alc883_capture_source,
6504                 .unsol_event = alc883_tagra_unsol_event,
6505                 .init_hook = alc883_tagra_automute,
6506         },
6507         [ALC883_TARGA_2ch_DIG] = {
6508                 .mixers = { alc883_tagra_2ch_mixer},
6509                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6510                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6511                 .dac_nids = alc883_dac_nids,
6512                 .dig_out_nid = ALC883_DIGOUT_NID,
6513                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6514                 .adc_nids = alc883_adc_nids,
6515                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6516                 .channel_mode = alc883_3ST_2ch_modes,
6517                 .input_mux = &alc883_capture_source,
6518                 .unsol_event = alc883_tagra_unsol_event,
6519                 .init_hook = alc883_tagra_automute,
6520         },
6521         [ALC883_ACER] = {
6522                 .mixers = { alc883_base_mixer,
6523                             alc883_chmode_mixer },
6524                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
6525                  * and the headphone jack.  Turn this on and rely on the
6526                  * standard mute methods whenever the user wants to turn
6527                  * these outputs off.
6528                  */
6529                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6530                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6531                 .dac_nids = alc883_dac_nids,
6532                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6533                 .adc_nids = alc883_adc_nids,
6534                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6535                 .channel_mode = alc883_3ST_2ch_modes,
6536                 .input_mux = &alc883_capture_source,
6537         },
6538         [ALC883_MEDION] = {
6539                 .mixers = { alc883_fivestack_mixer,
6540                             alc883_chmode_mixer },
6541                 .init_verbs = { alc883_init_verbs,
6542                                 alc883_medion_eapd_verbs },
6543                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6544                 .dac_nids = alc883_dac_nids,
6545                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6546                 .adc_nids = alc883_adc_nids,
6547                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6548                 .channel_mode = alc883_sixstack_modes,
6549                 .input_mux = &alc883_capture_source,
6550         },
6551         [ALC883_MEDION_MD2] = {
6552                 .mixers = { alc883_medion_md2_mixer},
6553                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6554                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6555                 .dac_nids = alc883_dac_nids,
6556                 .dig_out_nid = ALC883_DIGOUT_NID,
6557                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6558                 .adc_nids = alc883_adc_nids,
6559                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6560                 .channel_mode = alc883_3ST_2ch_modes,
6561                 .input_mux = &alc883_capture_source,
6562                 .unsol_event = alc883_medion_md2_unsol_event,
6563                 .init_hook = alc883_medion_md2_automute,
6564         },      
6565         [ALC883_LAPTOP_EAPD] = {
6566                 .mixers = { alc883_base_mixer,
6567                             alc883_chmode_mixer },
6568                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6569                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6570                 .dac_nids = alc883_dac_nids,
6571                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6572                 .adc_nids = alc883_adc_nids,
6573                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6574                 .channel_mode = alc883_3ST_2ch_modes,
6575                 .input_mux = &alc883_capture_source,
6576         },
6577         [ALC883_LENOVO_101E_2ch] = {
6578                 .mixers = { alc883_lenovo_101e_2ch_mixer},
6579                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6580                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6581                 .dac_nids = alc883_dac_nids,
6582                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6583                 .adc_nids = alc883_adc_nids,
6584                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6585                 .channel_mode = alc883_3ST_2ch_modes,
6586                 .input_mux = &alc883_lenovo_101e_capture_source,
6587                 .unsol_event = alc883_lenovo_101e_unsol_event,
6588                 .init_hook = alc883_lenovo_101e_all_automute,
6589         },
6590         [ALC883_LENOVO_NB0763] = {
6591                 .mixers = { alc883_lenovo_nb0763_mixer },
6592                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6593                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6594                 .dac_nids = alc883_dac_nids,
6595                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6596                 .adc_nids = alc883_adc_nids,
6597                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6598                 .channel_mode = alc883_3ST_2ch_modes,
6599                 .need_dac_fix = 1,
6600                 .input_mux = &alc883_lenovo_nb0763_capture_source,
6601                 .unsol_event = alc883_medion_md2_unsol_event,
6602                 .init_hook = alc883_medion_md2_automute,
6603         },
6604         [ALC888_LENOVO_MS7195_DIG] = {
6605                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6606                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6607                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6608                 .dac_nids = alc883_dac_nids,
6609                 .dig_out_nid = ALC883_DIGOUT_NID,
6610                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6611                 .adc_nids = alc883_adc_nids,
6612                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6613                 .channel_mode = alc883_3ST_6ch_modes,
6614                 .need_dac_fix = 1,
6615                 .input_mux = &alc883_capture_source,
6616                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
6617                 .init_hook = alc888_lenovo_ms7195_front_automute,
6618         },      
6619 };
6620
6621
6622 /*
6623  * BIOS auto configuration
6624  */
6625 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6626                                               hda_nid_t nid, int pin_type,
6627                                               int dac_idx)
6628 {
6629         /* set as output */
6630         struct alc_spec *spec = codec->spec;
6631         int idx;
6632
6633         if (spec->multiout.dac_nids[dac_idx] == 0x25)
6634                 idx = 4;
6635         else
6636                 idx = spec->multiout.dac_nids[dac_idx] - 2;
6637
6638         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6639                             pin_type);
6640         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6641                             AMP_OUT_UNMUTE);
6642         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6643
6644 }
6645
6646 static void alc883_auto_init_multi_out(struct hda_codec *codec)
6647 {
6648         struct alc_spec *spec = codec->spec;
6649         int i;
6650
6651         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6652         for (i = 0; i <= HDA_SIDE; i++) {
6653                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6654                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6655                 if (nid)
6656                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6657                                                           i);
6658         }
6659 }
6660
6661 static void alc883_auto_init_hp_out(struct hda_codec *codec)
6662 {
6663         struct alc_spec *spec = codec->spec;
6664         hda_nid_t pin;
6665
6666         pin = spec->autocfg.hp_pins[0];
6667         if (pin) /* connect to front */
6668                 /* use dac 0 */
6669                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6670 }
6671
6672 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
6673 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
6674
6675 static void alc883_auto_init_analog_input(struct hda_codec *codec)
6676 {
6677         struct alc_spec *spec = codec->spec;
6678         int i;
6679
6680         for (i = 0; i < AUTO_PIN_LAST; i++) {
6681                 hda_nid_t nid = spec->autocfg.input_pins[i];
6682                 if (alc883_is_input_pin(nid)) {
6683                         snd_hda_codec_write(codec, nid, 0,
6684                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
6685                                             (i <= AUTO_PIN_FRONT_MIC ?
6686                                              PIN_VREF80 : PIN_IN));
6687                         if (nid != ALC883_PIN_CD_NID)
6688                                 snd_hda_codec_write(codec, nid, 0,
6689                                                     AC_VERB_SET_AMP_GAIN_MUTE,
6690                                                     AMP_OUT_MUTE);
6691                 }
6692         }
6693 }
6694
6695 /* almost identical with ALC880 parser... */
6696 static int alc883_parse_auto_config(struct hda_codec *codec)
6697 {
6698         struct alc_spec *spec = codec->spec;
6699         int err = alc880_parse_auto_config(codec);
6700
6701         if (err < 0)
6702                 return err;
6703         else if (err > 0)
6704                 /* hack - override the init verbs */
6705                 spec->init_verbs[0] = alc883_auto_init_verbs;
6706         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
6707         spec->num_mixers++;
6708         return err;
6709 }
6710
6711 /* additional initialization for auto-configuration model */
6712 static void alc883_auto_init(struct hda_codec *codec)
6713 {
6714         alc883_auto_init_multi_out(codec);
6715         alc883_auto_init_hp_out(codec);
6716         alc883_auto_init_analog_input(codec);
6717 }
6718
6719 static int patch_alc883(struct hda_codec *codec)
6720 {
6721         struct alc_spec *spec;
6722         int err, board_config;
6723
6724         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6725         if (spec == NULL)
6726                 return -ENOMEM;
6727
6728         codec->spec = spec;
6729
6730         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
6731                                                   alc883_models,
6732                                                   alc883_cfg_tbl);
6733         if (board_config < 0) {
6734                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
6735                        "trying auto-probe from BIOS...\n");
6736                 board_config = ALC883_AUTO;
6737         }
6738
6739         if (board_config == ALC883_AUTO) {
6740                 /* automatic parse from the BIOS config */
6741                 err = alc883_parse_auto_config(codec);
6742                 if (err < 0) {
6743                         alc_free(codec);
6744                         return err;
6745                 } else if (!err) {
6746                         printk(KERN_INFO
6747                                "hda_codec: Cannot set up configuration "
6748                                "from BIOS.  Using base mode...\n");
6749                         board_config = ALC883_3ST_2ch_DIG;
6750                 }
6751         }
6752
6753         if (board_config != ALC883_AUTO)
6754                 setup_preset(spec, &alc883_presets[board_config]);
6755
6756         spec->stream_name_analog = "ALC883 Analog";
6757         spec->stream_analog_playback = &alc883_pcm_analog_playback;
6758         spec->stream_analog_capture = &alc883_pcm_analog_capture;
6759
6760         spec->stream_name_digital = "ALC883 Digital";
6761         spec->stream_digital_playback = &alc883_pcm_digital_playback;
6762         spec->stream_digital_capture = &alc883_pcm_digital_capture;
6763
6764         if (!spec->adc_nids && spec->input_mux) {
6765                 spec->adc_nids = alc883_adc_nids;
6766                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
6767         }
6768
6769         codec->patch_ops = alc_patch_ops;
6770         if (board_config == ALC883_AUTO)
6771                 spec->init_hook = alc883_auto_init;
6772
6773         return 0;
6774 }
6775
6776 /*
6777  * ALC262 support
6778  */
6779
6780 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
6781 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
6782
6783 #define alc262_dac_nids         alc260_dac_nids
6784 #define alc262_adc_nids         alc882_adc_nids
6785 #define alc262_adc_nids_alt     alc882_adc_nids_alt
6786
6787 #define alc262_modes            alc260_modes
6788 #define alc262_capture_source   alc882_capture_source
6789
6790 static struct snd_kcontrol_new alc262_base_mixer[] = {
6791         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6792         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6793         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6794         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6795         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6796         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6797         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6798         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6799         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6800         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6801         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6802         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6803         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6804            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
6805         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
6806         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6807         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6808         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6809         { } /* end */
6810 };
6811
6812 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
6813         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6814         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6815         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6816         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6817         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6818         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6819         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6820         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6821         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6822         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6823         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6824         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6825         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6826            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
6827         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
6828         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6829         { } /* end */
6830 };
6831
6832 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
6833         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6834         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6835         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6836         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6837         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6838
6839         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6840         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6841         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6842         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6843         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6844         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6845         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6846         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6847         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6848         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6849         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6850         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
6851         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
6852         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
6853         { } /* end */
6854 };
6855
6856 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
6857         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6858         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6859         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6860         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6861         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6862         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6863         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
6864         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
6865         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
6866         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6867         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6868         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6869         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6870         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6871         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
6872         { } /* end */
6873 };
6874
6875 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
6876         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6877         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6878         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
6879         { } /* end */
6880 };
6881
6882 static struct snd_kcontrol_new alc262_sony_mixer[] = {
6883         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6884         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6885         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6886         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6887         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6888         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6889         { } /* end */
6890 };
6891
6892 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
6893         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6894         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6895         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6896         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6897         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6898         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6899         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6900         { } /* end */
6901 };
6902
6903 #define alc262_capture_mixer            alc882_capture_mixer
6904 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
6905
6906 /*
6907  * generic initialization of ADC, input mixers and output mixers
6908  */
6909 static struct hda_verb alc262_init_verbs[] = {
6910         /*
6911          * Unmute ADC0-2 and set the default input to mic-in
6912          */
6913         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6914         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6915         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6916         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6917         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6918         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6919
6920         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6921          * mixer widget
6922          * Note: PASD motherboards uses the Line In 2 as the input for
6923          * front panel mic (mic 2)
6924          */
6925         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6926         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6927         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6928         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6929         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6930         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6931
6932         /*
6933          * Set up output mixers (0x0c - 0x0e)
6934          */
6935         /* set vol=0 to output mixers */
6936         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6937         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6938         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6939         /* set up input amps for analog loopback */
6940         /* Amp Indices: DAC = 0, mixer = 1 */
6941         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6942         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6943         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6944         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6945         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6946         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6947
6948         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6949         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6950         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6951         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6952         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6953         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6954
6955         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6956         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6957         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6958         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6959         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6960         
6961         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6962         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6963         
6964         /* FIXME: use matrix-type input source selection */
6965         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6966         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6967         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6968         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6969         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6970         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6971         /* Input mixer2 */
6972         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6973         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6974         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6975         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6976         /* Input mixer3 */
6977         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6978         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6979         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6980         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6981
6982         { }
6983 };
6984
6985 static struct hda_verb alc262_hippo_unsol_verbs[] = {
6986         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6987         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6988         {}
6989 };
6990
6991 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
6992         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6993         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6994         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6995
6996         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6997         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6998         {}
6999 };
7000
7001 static struct hda_verb alc262_sony_unsol_verbs[] = {
7002         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7003         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7004         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7005
7006         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7007         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7008 };
7009
7010 /* mute/unmute internal speaker according to the hp jack and mute state */
7011 static void alc262_hippo_automute(struct hda_codec *codec, int force)
7012 {
7013         struct alc_spec *spec = codec->spec;
7014         unsigned int mute;
7015
7016         if (force || !spec->sense_updated) {
7017                 unsigned int present;
7018                 /* need to execute and sync at first */
7019                 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7020                 present = snd_hda_codec_read(codec, 0x15, 0,
7021                                          AC_VERB_GET_PIN_SENSE, 0);
7022                 spec->jack_present = (present & 0x80000000) != 0;
7023                 spec->sense_updated = 1;
7024         }
7025         if (spec->jack_present) {
7026                 /* mute internal speaker */
7027                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7028                                          0x80, 0x80);
7029                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7030                                          0x80, 0x80);
7031         } else {
7032                 /* unmute internal speaker if necessary */
7033                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7034                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7035                                          0x80, mute & 0x80);
7036                 mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
7037                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7038                                          0x80, mute & 0x80);
7039         }
7040 }
7041
7042 /* unsolicited event for HP jack sensing */
7043 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7044                                        unsigned int res)
7045 {
7046         if ((res >> 26) != ALC880_HP_EVENT)
7047                 return;
7048         alc262_hippo_automute(codec, 1);
7049 }
7050
7051 static void alc262_hippo1_automute(struct hda_codec *codec, int force)
7052 {
7053         struct alc_spec *spec = codec->spec;
7054         unsigned int mute;
7055
7056         if (force || !spec->sense_updated) {
7057                 unsigned int present;
7058                 /* need to execute and sync at first */
7059                 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7060                 present = snd_hda_codec_read(codec, 0x1b, 0,
7061                                          AC_VERB_GET_PIN_SENSE, 0);
7062                 spec->jack_present = (present & 0x80000000) != 0;
7063                 spec->sense_updated = 1;
7064         }
7065         if (spec->jack_present) {
7066                 /* mute internal speaker */
7067                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7068                                          0x80, 0x80);
7069                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7070                                          0x80, 0x80);
7071         } else {
7072                 /* unmute internal speaker if necessary */
7073                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7074                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7075                                          0x80, mute & 0x80);
7076                 mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
7077                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7078                                          0x80, mute & 0x80);
7079         }
7080 }
7081
7082 /* unsolicited event for HP jack sensing */
7083 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7084                                        unsigned int res)
7085 {
7086         if ((res >> 26) != ALC880_HP_EVENT)
7087                 return;
7088         alc262_hippo1_automute(codec, 1);
7089 }
7090
7091 /*
7092  * fujitsu model
7093  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7094  */
7095
7096 #define ALC_HP_EVENT    0x37
7097
7098 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7099         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7100         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7101         {}
7102 };
7103
7104 static struct hda_input_mux alc262_fujitsu_capture_source = {
7105         .num_items = 2,
7106         .items = {
7107                 { "Mic", 0x0 },
7108                 { "CD", 0x4 },
7109         },
7110 };
7111
7112 static struct hda_input_mux alc262_HP_capture_source = {
7113         .num_items = 5,
7114         .items = {
7115                 { "Mic", 0x0 },
7116                 { "Front Mic", 0x3 },
7117                 { "Line", 0x2 },
7118                 { "CD", 0x4 },
7119                 { "AUX IN", 0x6 },
7120         },
7121 };
7122
7123 /* mute/unmute internal speaker according to the hp jack and mute state */
7124 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7125 {
7126         struct alc_spec *spec = codec->spec;
7127         unsigned int mute;
7128
7129         if (force || !spec->sense_updated) {
7130                 unsigned int present;
7131                 /* need to execute and sync at first */
7132                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7133                 present = snd_hda_codec_read(codec, 0x14, 0,
7134                                          AC_VERB_GET_PIN_SENSE, 0);
7135                 spec->jack_present = (present & 0x80000000) != 0;
7136                 spec->sense_updated = 1;
7137         }
7138         if (spec->jack_present) {
7139                 /* mute internal speaker */
7140                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7141                                          0x80, 0x80);
7142                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7143                                          0x80, 0x80);
7144         } else {
7145                 /* unmute internal speaker if necessary */
7146                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7147                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7148                                          0x80, mute & 0x80);
7149                 mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
7150                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7151                                          0x80, mute & 0x80);
7152         }
7153 }
7154
7155 /* unsolicited event for HP jack sensing */
7156 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7157                                        unsigned int res)
7158 {
7159         if ((res >> 26) != ALC_HP_EVENT)
7160                 return;
7161         alc262_fujitsu_automute(codec, 1);
7162 }
7163
7164 /* bind volumes of both NID 0x0c and 0x0d */
7165 static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
7166                                          struct snd_ctl_elem_value *ucontrol)
7167 {
7168         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7169         long *valp = ucontrol->value.integer.value;
7170         int change;
7171
7172         change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
7173                                           0x7f, valp[0] & 0x7f);
7174         change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
7175                                            0x7f, valp[1] & 0x7f);
7176         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
7177                                  0x7f, valp[0] & 0x7f);
7178         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
7179                                  0x7f, valp[1] & 0x7f);
7180         return change;
7181 }
7182
7183 /* bind hp and internal speaker mute (with plug check) */
7184 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7185                                          struct snd_ctl_elem_value *ucontrol)
7186 {
7187         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7188         long *valp = ucontrol->value.integer.value;
7189         int change;
7190
7191         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7192                                           0x80, valp[0] ? 0 : 0x80);
7193         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7194                                            0x80, valp[1] ? 0 : 0x80);
7195         if (change || codec->in_resume)
7196                 alc262_fujitsu_automute(codec, codec->in_resume);
7197         return change;
7198 }
7199
7200 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7201         {
7202                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7203                 .name = "Master Playback Volume",
7204                 .info = snd_hda_mixer_amp_volume_info,
7205                 .get = snd_hda_mixer_amp_volume_get,
7206                 .put = alc262_fujitsu_master_vol_put,
7207                 .tlv = { .c = snd_hda_mixer_amp_tlv },
7208                 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7209         },
7210         {
7211                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7212                 .name = "Master Playback Switch",
7213                 .info = snd_hda_mixer_amp_switch_info,
7214                 .get = snd_hda_mixer_amp_switch_get,
7215                 .put = alc262_fujitsu_master_sw_put,
7216                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7217         },
7218         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7219         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7220         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7221         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7222         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7223         { } /* end */
7224 };
7225
7226 /* additional init verbs for Benq laptops */
7227 static struct hda_verb alc262_EAPD_verbs[] = {
7228         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7229         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7230         {}
7231 };
7232
7233 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7234         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7235         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7236
7237         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7238         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7239         {}
7240 };
7241
7242 /* add playback controls from the parsed DAC table */
7243 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7244                                              const struct auto_pin_cfg *cfg)
7245 {
7246         hda_nid_t nid;
7247         int err;
7248
7249         spec->multiout.num_dacs = 1;    /* only use one dac */
7250         spec->multiout.dac_nids = spec->private_dac_nids;
7251         spec->multiout.dac_nids[0] = 2;
7252
7253         nid = cfg->line_out_pins[0];
7254         if (nid) {
7255                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7256                                   "Front Playback Volume",
7257                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7258                 if (err < 0)
7259                         return err;
7260                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7261                                   "Front Playback Switch",
7262                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7263                 if (err < 0)
7264                         return err;
7265         }
7266
7267         nid = cfg->speaker_pins[0];
7268         if (nid) {
7269                 if (nid == 0x16) {
7270                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7271                                           "Speaker Playback Volume",
7272                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7273                                                               HDA_OUTPUT));
7274                         if (err < 0)
7275                                 return err;
7276                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7277                                           "Speaker Playback Switch",
7278                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7279                                                               HDA_OUTPUT));
7280                         if (err < 0)
7281                                 return err;
7282                 } else {
7283                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7284                                           "Speaker Playback Switch",
7285                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7286                                                               HDA_OUTPUT));
7287                         if (err < 0)
7288                                 return err;
7289                 }
7290         }
7291         nid = cfg->hp_pins[0];
7292         if (nid) {
7293                 /* spec->multiout.hp_nid = 2; */
7294                 if (nid == 0x16) {
7295                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7296                                           "Headphone Playback Volume",
7297                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7298                                                               HDA_OUTPUT));
7299                         if (err < 0)
7300                                 return err;
7301                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7302                                           "Headphone Playback Switch",
7303                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7304                                                               HDA_OUTPUT));
7305                         if (err < 0)
7306                                 return err;
7307                 } else {
7308                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7309                                           "Headphone Playback Switch",
7310                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7311                                                               HDA_OUTPUT));
7312                         if (err < 0)
7313                                 return err;
7314                 }
7315         }
7316         return 0;
7317 }
7318
7319 /* identical with ALC880 */
7320 #define alc262_auto_create_analog_input_ctls \
7321         alc880_auto_create_analog_input_ctls
7322
7323 /*
7324  * generic initialization of ADC, input mixers and output mixers
7325  */
7326 static struct hda_verb alc262_volume_init_verbs[] = {
7327         /*
7328          * Unmute ADC0-2 and set the default input to mic-in
7329          */
7330         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7331         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7332         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7333         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7334         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7335         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7336
7337         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7338          * mixer widget
7339          * Note: PASD motherboards uses the Line In 2 as the input for
7340          * front panel mic (mic 2)
7341          */
7342         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7343         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7344         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7345         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7346         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7347         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7348
7349         /*
7350          * Set up output mixers (0x0c - 0x0f)
7351          */
7352         /* set vol=0 to output mixers */
7353         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7354         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7355         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7356         
7357         /* set up input amps for analog loopback */
7358         /* Amp Indices: DAC = 0, mixer = 1 */
7359         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7360         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7361         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7362         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7363         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7364         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7365
7366         /* FIXME: use matrix-type input source selection */
7367         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7368         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7369         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7370         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7371         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7372         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7373         /* Input mixer2 */
7374         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7375         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7376         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7377         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7378         /* Input mixer3 */
7379         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7380         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7381         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7382         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7383
7384         { }
7385 };
7386
7387 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7388         /*
7389          * Unmute ADC0-2 and set the default input to mic-in
7390          */
7391         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7392         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7393         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7394         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7395         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7396         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7397
7398         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7399          * mixer widget
7400          * Note: PASD motherboards uses the Line In 2 as the input for
7401          * front panel mic (mic 2)
7402          */
7403         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7404         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7405         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7406         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7407         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7408         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7409         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7410         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7411         
7412         /*
7413          * Set up output mixers (0x0c - 0x0e)
7414          */
7415         /* set vol=0 to output mixers */
7416         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7417         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7418         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7419
7420         /* set up input amps for analog loopback */
7421         /* Amp Indices: DAC = 0, mixer = 1 */
7422         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7423         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7424         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7425         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7426         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7427         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7428
7429         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7430         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7431         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7432
7433         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7434         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7435
7436         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7437         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7438
7439         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7440         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7441         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7442         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7443         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7444
7445         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7446         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7447         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7448         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7449         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7450         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7451
7452
7453         /* FIXME: use matrix-type input source selection */
7454         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7455         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7456         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7457         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7458         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7459         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7460         /* Input mixer2 */
7461         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7462         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7463         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7464         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7465         /* Input mixer3 */
7466         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7467         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7468         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7469         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7470
7471         { }
7472 };
7473
7474 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7475         /*
7476          * Unmute ADC0-2 and set the default input to mic-in
7477          */
7478         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7479         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7480         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7481         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7482         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7483         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7484
7485         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7486          * mixer widget
7487          * Note: PASD motherboards uses the Line In 2 as the input for front
7488          * panel mic (mic 2)
7489          */
7490         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7491         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7492         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7493         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7494         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7495         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7496         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7497         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7498         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
7499         /*
7500          * Set up output mixers (0x0c - 0x0e)
7501          */
7502         /* set vol=0 to output mixers */
7503         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7504         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7505         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7506
7507         /* set up input amps for analog loopback */
7508         /* Amp Indices: DAC = 0, mixer = 1 */
7509         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7510         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7511         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7512         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7513         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7514         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7515
7516
7517         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
7518         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
7519         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
7520         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
7521         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
7522         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
7523         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
7524
7525         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7526         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7527
7528         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7529         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7530
7531         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7532         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7533         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7534         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7535         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7536         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7537
7538         /* FIXME: use matrix-type input source selection */
7539         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7540         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7541         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7542         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7543         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7544         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7545         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7546         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7547         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7548         /* Input mixer2 */
7549         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7550         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7551         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7552         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7553         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7554         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7555         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7556         /* Input mixer3 */
7557         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7558         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7559         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7560         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7561         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7562         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7563         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7564
7565         { }
7566 };
7567
7568 /* pcm configuration: identiacal with ALC880 */
7569 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
7570 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
7571 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
7572 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
7573
7574 /*
7575  * BIOS auto configuration
7576  */
7577 static int alc262_parse_auto_config(struct hda_codec *codec)
7578 {
7579         struct alc_spec *spec = codec->spec;
7580         int err;
7581         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7582
7583         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7584                                            alc262_ignore);
7585         if (err < 0)
7586                 return err;
7587         if (!spec->autocfg.line_outs)
7588                 return 0; /* can't find valid BIOS pin config */
7589         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7590         if (err < 0)
7591                 return err;
7592         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7593         if (err < 0)
7594                 return err;
7595
7596         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7597
7598         if (spec->autocfg.dig_out_pin)
7599                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7600         if (spec->autocfg.dig_in_pin)
7601                 spec->dig_in_nid = ALC262_DIGIN_NID;
7602
7603         if (spec->kctl_alloc)
7604                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7605
7606         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7607         spec->num_mux_defs = 1;
7608         spec->input_mux = &spec->private_imux;
7609
7610         return 1;
7611 }
7612
7613 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
7614 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
7615 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
7616
7617
7618 /* init callback for auto-configuration model -- overriding the default init */
7619 static void alc262_auto_init(struct hda_codec *codec)
7620 {
7621         alc262_auto_init_multi_out(codec);
7622         alc262_auto_init_hp_out(codec);
7623         alc262_auto_init_analog_input(codec);
7624 }
7625
7626 /*
7627  * configuration and preset
7628  */
7629 static const char *alc262_models[ALC262_MODEL_LAST] = {
7630         [ALC262_BASIC]          = "basic",
7631         [ALC262_HIPPO]          = "hippo",
7632         [ALC262_HIPPO_1]        = "hippo_1",
7633         [ALC262_FUJITSU]        = "fujitsu",
7634         [ALC262_HP_BPC]         = "hp-bpc",
7635         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7636         [ALC262_BENQ_ED8]       = "benq",
7637         [ALC262_BENQ_ED8]       = "sony-assamd",
7638         [ALC262_AUTO]           = "auto",
7639 };
7640
7641 static struct snd_pci_quirk alc262_cfg_tbl[] = {
7642         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7643         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7644         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7645         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7646         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7647         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7648         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7649         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7650         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7651         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7652         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7653         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7654         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7655         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7656         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7657         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7658         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7659         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7660         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7661         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7662         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7663         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7664         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7665         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7666         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7667         {}
7668 };
7669
7670 static struct alc_config_preset alc262_presets[] = {
7671         [ALC262_BASIC] = {
7672                 .mixers = { alc262_base_mixer },
7673                 .init_verbs = { alc262_init_verbs },
7674                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7675                 .dac_nids = alc262_dac_nids,
7676                 .hp_nid = 0x03,
7677                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7678                 .channel_mode = alc262_modes,
7679                 .input_mux = &alc262_capture_source,
7680         },
7681         [ALC262_HIPPO] = {
7682                 .mixers = { alc262_base_mixer },
7683                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
7684                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7685                 .dac_nids = alc262_dac_nids,
7686                 .hp_nid = 0x03,
7687                 .dig_out_nid = ALC262_DIGOUT_NID,
7688                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7689                 .channel_mode = alc262_modes,
7690                 .input_mux = &alc262_capture_source,
7691                 .unsol_event = alc262_hippo_unsol_event,
7692         },
7693         [ALC262_HIPPO_1] = {
7694                 .mixers = { alc262_hippo1_mixer },
7695                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
7696                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7697                 .dac_nids = alc262_dac_nids,
7698                 .hp_nid = 0x02,
7699                 .dig_out_nid = ALC262_DIGOUT_NID,
7700                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7701                 .channel_mode = alc262_modes,
7702                 .input_mux = &alc262_capture_source,
7703                 .unsol_event = alc262_hippo1_unsol_event,
7704         },
7705         [ALC262_FUJITSU] = {
7706                 .mixers = { alc262_fujitsu_mixer },
7707                 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
7708                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7709                 .dac_nids = alc262_dac_nids,
7710                 .hp_nid = 0x03,
7711                 .dig_out_nid = ALC262_DIGOUT_NID,
7712                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7713                 .channel_mode = alc262_modes,
7714                 .input_mux = &alc262_fujitsu_capture_source,
7715                 .unsol_event = alc262_fujitsu_unsol_event,
7716         },
7717         [ALC262_HP_BPC] = {
7718                 .mixers = { alc262_HP_BPC_mixer },
7719                 .init_verbs = { alc262_HP_BPC_init_verbs },
7720                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7721                 .dac_nids = alc262_dac_nids,
7722                 .hp_nid = 0x03,
7723                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7724                 .channel_mode = alc262_modes,
7725                 .input_mux = &alc262_HP_capture_source,
7726         },
7727         [ALC262_HP_BPC_D7000_WF] = {
7728                 .mixers = { alc262_HP_BPC_WildWest_mixer },
7729                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7730                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7731                 .dac_nids = alc262_dac_nids,
7732                 .hp_nid = 0x03,
7733                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7734                 .channel_mode = alc262_modes,
7735                 .input_mux = &alc262_HP_capture_source,
7736         },
7737         [ALC262_HP_BPC_D7000_WL] = {
7738                 .mixers = { alc262_HP_BPC_WildWest_mixer,
7739                             alc262_HP_BPC_WildWest_option_mixer },
7740                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7741                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7742                 .dac_nids = alc262_dac_nids,
7743                 .hp_nid = 0x03,
7744                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7745                 .channel_mode = alc262_modes,
7746                 .input_mux = &alc262_HP_capture_source,
7747         },
7748         [ALC262_BENQ_ED8] = {
7749                 .mixers = { alc262_base_mixer },
7750                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
7751                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7752                 .dac_nids = alc262_dac_nids,
7753                 .hp_nid = 0x03,
7754                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7755                 .channel_mode = alc262_modes,
7756                 .input_mux = &alc262_capture_source,
7757         },
7758         [ALC262_SONY_ASSAMD] = {
7759                 .mixers = { alc262_sony_mixer },
7760                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
7761                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7762                 .dac_nids = alc262_dac_nids,
7763                 .hp_nid = 0x02,
7764                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7765                 .channel_mode = alc262_modes,
7766                 .input_mux = &alc262_capture_source,
7767                 .unsol_event = alc262_hippo_unsol_event,
7768         },
7769         [ALC262_BENQ_T31] = {
7770                 .mixers = { alc262_benq_t31_mixer },
7771                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
7772                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7773                 .dac_nids = alc262_dac_nids,
7774                 .hp_nid = 0x03,
7775                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7776                 .channel_mode = alc262_modes,
7777                 .input_mux = &alc262_capture_source,
7778                 .unsol_event = alc262_hippo_unsol_event,
7779         },      
7780 };
7781
7782 static int patch_alc262(struct hda_codec *codec)
7783 {
7784         struct alc_spec *spec;
7785         int board_config;
7786         int err;
7787
7788         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7789         if (spec == NULL)
7790                 return -ENOMEM;
7791
7792         codec->spec = spec;
7793 #if 0
7794         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
7795          * under-run
7796          */
7797         {
7798         int tmp;
7799         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
7800         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
7801         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
7802         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
7803         }
7804 #endif
7805
7806         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
7807                                                   alc262_models,
7808                                                   alc262_cfg_tbl);
7809
7810         if (board_config < 0) {
7811                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
7812                        "trying auto-probe from BIOS...\n");
7813                 board_config = ALC262_AUTO;
7814         }
7815
7816         if (board_config == ALC262_AUTO) {
7817                 /* automatic parse from the BIOS config */
7818                 err = alc262_parse_auto_config(codec);
7819                 if (err < 0) {
7820                         alc_free(codec);
7821                         return err;
7822                 } else if (!err) {
7823                         printk(KERN_INFO
7824                                "hda_codec: Cannot set up configuration "
7825                                "from BIOS.  Using base mode...\n");
7826                         board_config = ALC262_BASIC;
7827                 }
7828         }
7829
7830         if (board_config != ALC262_AUTO)
7831                 setup_preset(spec, &alc262_presets[board_config]);
7832
7833         spec->stream_name_analog = "ALC262 Analog";
7834         spec->stream_analog_playback = &alc262_pcm_analog_playback;
7835         spec->stream_analog_capture = &alc262_pcm_analog_capture;
7836                 
7837         spec->stream_name_digital = "ALC262 Digital";
7838         spec->stream_digital_playback = &alc262_pcm_digital_playback;
7839         spec->stream_digital_capture = &alc262_pcm_digital_capture;
7840
7841         if (!spec->adc_nids && spec->input_mux) {
7842                 /* check whether NID 0x07 is valid */
7843                 unsigned int wcap = get_wcaps(codec, 0x07);
7844
7845                 /* get type */
7846                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7847                 if (wcap != AC_WID_AUD_IN) {
7848                         spec->adc_nids = alc262_adc_nids_alt;
7849                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
7850                         spec->mixers[spec->num_mixers] =
7851                                 alc262_capture_alt_mixer;
7852                         spec->num_mixers++;
7853                 } else {
7854                         spec->adc_nids = alc262_adc_nids;
7855                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
7856                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
7857                         spec->num_mixers++;
7858                 }
7859         }
7860
7861         codec->patch_ops = alc_patch_ops;
7862         if (board_config == ALC262_AUTO)
7863                 spec->init_hook = alc262_auto_init;
7864                 
7865         return 0;
7866 }
7867
7868 /*
7869  *  ALC268 channel source setting (2 channel)
7870  */
7871 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
7872 #define alc268_modes            alc260_modes
7873         
7874 static hda_nid_t alc268_dac_nids[2] = {
7875         /* front, hp */
7876         0x02, 0x03
7877 };
7878
7879 static hda_nid_t alc268_adc_nids[2] = {
7880         /* ADC0-1 */
7881         0x08, 0x07
7882 };
7883
7884 static hda_nid_t alc268_adc_nids_alt[1] = {
7885         /* ADC0 */
7886         0x08
7887 };
7888
7889 static struct snd_kcontrol_new alc268_base_mixer[] = {
7890         /* output mixer control */
7891         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7892         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7893         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7894         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7895         { }
7896 };
7897
7898 /*
7899  * generic initialization of ADC, input mixers and output mixers
7900  */
7901 static struct hda_verb alc268_base_init_verbs[] = {
7902         /* Unmute DAC0-1 and set vol = 0 */
7903         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7904         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7905         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7906         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7907         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7908         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7909
7910         /*
7911          * Set up output mixers (0x0c - 0x0e)
7912          */
7913         /* set vol=0 to output mixers */
7914         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7915         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7916         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7917         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
7918
7919         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7920         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7921
7922         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7923         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7924         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7925         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7926         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7927         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7928         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7929         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7930
7931         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7932         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7933         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7934         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7935         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7936         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7937         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7938         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7939
7940         /* FIXME: use matrix-type input source selection */
7941         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
7942         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7943         /* Input mixer2 */
7944         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7945         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7946         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7947         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7948
7949         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7950         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7951         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7952         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7953         { }
7954 };
7955
7956 /*
7957  * generic initialization of ADC, input mixers and output mixers
7958  */
7959 static struct hda_verb alc268_volume_init_verbs[] = {
7960         /* set output DAC */
7961         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7962         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7963         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7964         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7965
7966         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7967         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7968         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7969         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7970         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7971
7972         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7973         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7974         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7975         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7976         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7977
7978         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7979         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7980         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7981         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7982
7983         /* set PCBEEP vol = 0 */
7984         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
7985
7986         { }
7987 };
7988
7989 #define alc268_mux_enum_info alc_mux_enum_info
7990 #define alc268_mux_enum_get alc_mux_enum_get
7991
7992 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
7993                                struct snd_ctl_elem_value *ucontrol)
7994 {
7995         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7996         struct alc_spec *spec = codec->spec;
7997         const struct hda_input_mux *imux = spec->input_mux;
7998         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
7999         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8000         hda_nid_t nid = capture_mixers[adc_idx];
8001         unsigned int *cur_val = &spec->cur_mux[adc_idx];
8002         unsigned int i, idx;
8003
8004         idx = ucontrol->value.enumerated.item[0];
8005         if (idx >= imux->num_items)
8006                 idx = imux->num_items - 1;
8007         if (*cur_val == idx && !codec->in_resume)
8008                 return 0;
8009         for (i = 0; i < imux->num_items; i++) {
8010                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8011                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8012                                     v | (imux->items[i].index << 8));
8013                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
8014                                     idx );
8015         }
8016         *cur_val = idx;
8017         return 1;
8018 }
8019
8020 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8021         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8022         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8023         {
8024                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8025                 /* The multiple "Capture Source" controls confuse alsamixer
8026                  * So call somewhat different..
8027                  * FIXME: the controls appear in the "playback" view!
8028                  */
8029                 /* .name = "Capture Source", */
8030                 .name = "Input Source",
8031                 .count = 1,
8032                 .info = alc268_mux_enum_info,
8033                 .get = alc268_mux_enum_get,
8034                 .put = alc268_mux_enum_put,
8035         },
8036         { } /* end */
8037 };
8038
8039 static struct snd_kcontrol_new alc268_capture_mixer[] = {
8040         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8041         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8042         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8043         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8044         {
8045                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8046                 /* The multiple "Capture Source" controls confuse alsamixer
8047                  * So call somewhat different..
8048                  * FIXME: the controls appear in the "playback" view!
8049                  */
8050                 /* .name = "Capture Source", */
8051                 .name = "Input Source",
8052                 .count = 2,
8053                 .info = alc268_mux_enum_info,
8054                 .get = alc268_mux_enum_get,
8055                 .put = alc268_mux_enum_put,
8056         },
8057         { } /* end */
8058 };
8059
8060 static struct hda_input_mux alc268_capture_source = {
8061         .num_items = 4,
8062         .items = {
8063                 { "Mic", 0x0 },
8064                 { "Front Mic", 0x1 },
8065                 { "Line", 0x2 },
8066                 { "CD", 0x3 },
8067         },
8068 };
8069
8070 /* create input playback/capture controls for the given pin */
8071 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8072                                     const char *ctlname, int idx)
8073 {
8074         char name[32];
8075         int err;
8076
8077         sprintf(name, "%s Playback Volume", ctlname);
8078         if (nid == 0x14) {
8079                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8080                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8081                                                       HDA_OUTPUT));
8082                 if (err < 0)
8083                         return err;
8084         } else if (nid == 0x15) {
8085                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8086                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8087                                                       HDA_OUTPUT));
8088                 if (err < 0)
8089                         return err;
8090         } else
8091                 return -1;
8092         sprintf(name, "%s Playback Switch", ctlname);
8093         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8094                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8095         if (err < 0)
8096                 return err;
8097         return 0;
8098 }
8099
8100 /* add playback controls from the parsed DAC table */
8101 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8102                                              const struct auto_pin_cfg *cfg)
8103 {
8104         hda_nid_t nid;
8105         int err;
8106
8107         spec->multiout.num_dacs = 2;    /* only use one dac */
8108         spec->multiout.dac_nids = spec->private_dac_nids;
8109         spec->multiout.dac_nids[0] = 2;
8110         spec->multiout.dac_nids[1] = 3;
8111
8112         nid = cfg->line_out_pins[0];
8113         if (nid)
8114                 alc268_new_analog_output(spec, nid, "Front", 0);        
8115
8116         nid = cfg->speaker_pins[0];
8117         if (nid == 0x1d) {
8118                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8119                                   "Speaker Playback Volume",
8120                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8121                 if (err < 0)
8122                         return err;
8123         }
8124         nid = cfg->hp_pins[0];
8125         if (nid)
8126                 alc268_new_analog_output(spec, nid, "Headphone", 0);
8127
8128         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8129         if (nid == 0x16) {
8130                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8131                                   "Mono Playback Switch",
8132                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8133                 if (err < 0)
8134                         return err;
8135         }
8136         return 0;       
8137 }
8138
8139 /* create playback/capture controls for input pins */
8140 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8141                                                 const struct auto_pin_cfg *cfg)
8142 {
8143         struct hda_input_mux *imux = &spec->private_imux;
8144         int i, idx1;
8145
8146         for (i = 0; i < AUTO_PIN_LAST; i++) {
8147                 switch(cfg->input_pins[i]) {
8148                 case 0x18:
8149                         idx1 = 0;       /* Mic 1 */
8150                         break;
8151                 case 0x19:
8152                         idx1 = 1;       /* Mic 2 */
8153                         break;
8154                 case 0x1a:
8155                         idx1 = 2;       /* Line In */
8156                         break;
8157                 case 0x1c:      
8158                         idx1 = 3;       /* CD */
8159                         break;
8160                 default:
8161                         continue;
8162                 }
8163                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8164                 imux->items[imux->num_items].index = idx1;
8165                 imux->num_items++;      
8166         }
8167         return 0;
8168 }
8169
8170 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8171 {
8172         struct alc_spec *spec = codec->spec;
8173         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8174         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8175         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8176         unsigned int    dac_vol1, dac_vol2;
8177
8178         if (speaker_nid) {
8179                 snd_hda_codec_write(codec, speaker_nid, 0,
8180                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8181                 snd_hda_codec_write(codec, 0x0f, 0,
8182                                     AC_VERB_SET_AMP_GAIN_MUTE,
8183                                     AMP_IN_UNMUTE(1));
8184                 snd_hda_codec_write(codec, 0x10, 0,
8185                                     AC_VERB_SET_AMP_GAIN_MUTE,
8186                                     AMP_IN_UNMUTE(1));
8187         } else {
8188                 snd_hda_codec_write(codec, 0x0f, 0,
8189                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8190                 snd_hda_codec_write(codec, 0x10, 0,
8191                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8192         }
8193
8194         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
8195         if (line_nid == 0x14)   
8196                 dac_vol2 = AMP_OUT_ZERO;
8197         else if (line_nid == 0x15)
8198                 dac_vol1 = AMP_OUT_ZERO;
8199         if (hp_nid == 0x14)     
8200                 dac_vol2 = AMP_OUT_ZERO;
8201         else if (hp_nid == 0x15)
8202                 dac_vol1 = AMP_OUT_ZERO;
8203         if (line_nid != 0x16 || hp_nid != 0x16 ||
8204             spec->autocfg.line_out_pins[1] != 0x16 ||
8205             spec->autocfg.line_out_pins[2] != 0x16)
8206                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8207
8208         snd_hda_codec_write(codec, 0x02, 0,
8209                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8210         snd_hda_codec_write(codec, 0x03, 0,
8211                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8212 }
8213
8214 /* pcm configuration: identiacal with ALC880 */
8215 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
8216 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
8217 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
8218
8219 /*
8220  * BIOS auto configuration
8221  */
8222 static int alc268_parse_auto_config(struct hda_codec *codec)
8223 {
8224         struct alc_spec *spec = codec->spec;
8225         int err;
8226         static hda_nid_t alc268_ignore[] = { 0 };
8227
8228         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8229                                            alc268_ignore);
8230         if (err < 0)
8231                 return err;
8232         if (!spec->autocfg.line_outs)
8233                 return 0; /* can't find valid BIOS pin config */
8234
8235         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8236         if (err < 0)
8237                 return err;
8238         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8239         if (err < 0)
8240                 return err;
8241
8242         spec->multiout.max_channels = 2;
8243
8244         /* digital only support output */
8245         if (spec->autocfg.dig_out_pin)
8246                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8247
8248         if (spec->kctl_alloc)
8249                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8250
8251         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8252         spec->num_mux_defs = 1;
8253         spec->input_mux = &spec->private_imux;
8254
8255         return 1;
8256 }
8257
8258 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
8259 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
8260 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
8261
8262 /* init callback for auto-configuration model -- overriding the default init */
8263 static void alc268_auto_init(struct hda_codec *codec)
8264 {
8265         alc268_auto_init_multi_out(codec);
8266         alc268_auto_init_hp_out(codec);
8267         alc268_auto_init_mono_speaker_out(codec);
8268         alc268_auto_init_analog_input(codec);
8269 }
8270
8271 /*
8272  * configuration and preset
8273  */
8274 static const char *alc268_models[ALC268_MODEL_LAST] = {
8275         [ALC268_3ST]            = "3stack",
8276         [ALC268_AUTO]           = "auto",
8277 };
8278
8279 static struct snd_pci_quirk alc268_cfg_tbl[] = {
8280         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8281         {}
8282 };
8283
8284 static struct alc_config_preset alc268_presets[] = {
8285         [ALC268_3ST] = {
8286                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8287                 .init_verbs = { alc268_base_init_verbs },
8288                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8289                 .dac_nids = alc268_dac_nids,
8290                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8291                 .adc_nids = alc268_adc_nids_alt,
8292                 .hp_nid = 0x03,
8293                 .dig_out_nid = ALC268_DIGOUT_NID,
8294                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8295                 .channel_mode = alc268_modes,
8296                 .input_mux = &alc268_capture_source,
8297         },
8298 };
8299
8300 static int patch_alc268(struct hda_codec *codec)
8301 {
8302         struct alc_spec *spec;
8303         int board_config;
8304         int err;
8305
8306         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8307         if (spec == NULL)
8308                 return -ENOMEM;
8309
8310         codec->spec = spec;
8311
8312         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8313                                                   alc268_models,
8314                                                   alc268_cfg_tbl);
8315
8316         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8317                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8318                        "trying auto-probe from BIOS...\n");
8319                 board_config = ALC268_AUTO;
8320         }
8321
8322         if (board_config == ALC268_AUTO) {
8323                 /* automatic parse from the BIOS config */
8324                 err = alc268_parse_auto_config(codec);
8325                 if (err < 0) {
8326                         alc_free(codec);
8327                         return err;
8328                 } else if (!err) {
8329                         printk(KERN_INFO
8330                                "hda_codec: Cannot set up configuration "
8331                                "from BIOS.  Using base mode...\n");
8332                         board_config = ALC268_3ST;
8333                 }
8334         }
8335
8336         if (board_config != ALC268_AUTO)
8337                 setup_preset(spec, &alc268_presets[board_config]);
8338
8339         spec->stream_name_analog = "ALC268 Analog";
8340         spec->stream_analog_playback = &alc268_pcm_analog_playback;
8341         spec->stream_analog_capture = &alc268_pcm_analog_capture;
8342
8343         spec->stream_name_digital = "ALC268 Digital";
8344         spec->stream_digital_playback = &alc268_pcm_digital_playback;
8345
8346         if (board_config == ALC268_AUTO) {
8347                 if (!spec->adc_nids && spec->input_mux) {
8348                         /* check whether NID 0x07 is valid */
8349                         unsigned int wcap = get_wcaps(codec, 0x07);
8350
8351                         /* get type */
8352                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8353                         if (wcap != AC_WID_AUD_IN) {
8354                                 spec->adc_nids = alc268_adc_nids_alt;
8355                                 spec->num_adc_nids =
8356                                         ARRAY_SIZE(alc268_adc_nids_alt);
8357                                 spec->mixers[spec->num_mixers] =
8358                                         alc268_capture_alt_mixer;
8359                                 spec->num_mixers++;
8360                         } else {
8361                                 spec->adc_nids = alc268_adc_nids;
8362                                 spec->num_adc_nids =
8363                                         ARRAY_SIZE(alc268_adc_nids);
8364                                 spec->mixers[spec->num_mixers] =
8365                                         alc268_capture_mixer;
8366                                 spec->num_mixers++;
8367                         }
8368                 }
8369         }
8370         codec->patch_ops = alc_patch_ops;
8371         if (board_config == ALC268_AUTO)
8372                 spec->init_hook = alc268_auto_init;
8373                 
8374         return 0;
8375 }
8376
8377 /*
8378  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8379  */
8380
8381 /*
8382  * set the path ways for 2 channel output
8383  * need to set the codec line out and mic 1 pin widgets to inputs
8384  */
8385 static struct hda_verb alc861_threestack_ch2_init[] = {
8386         /* set pin widget 1Ah (line in) for input */
8387         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8388         /* set pin widget 18h (mic1/2) for input, for mic also enable
8389          * the vref
8390          */
8391         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8392
8393         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8394 #if 0
8395         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8396         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8397 #endif
8398         { } /* end */
8399 };
8400 /*
8401  * 6ch mode
8402  * need to set the codec line out and mic 1 pin widgets to outputs
8403  */
8404 static struct hda_verb alc861_threestack_ch6_init[] = {
8405         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8406         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8407         /* set pin widget 18h (mic1) for output (CLFE)*/
8408         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8409
8410         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8411         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8412
8413         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8414 #if 0
8415         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8416         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8417 #endif
8418         { } /* end */
8419 };
8420
8421 static struct hda_channel_mode alc861_threestack_modes[2] = {
8422         { 2, alc861_threestack_ch2_init },
8423         { 6, alc861_threestack_ch6_init },
8424 };
8425 /* Set mic1 as input and unmute the mixer */
8426 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8427         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8428         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8429         { } /* end */
8430 };
8431 /* Set mic1 as output and mute mixer */
8432 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8433         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8434         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8435         { } /* end */
8436 };
8437
8438 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8439         { 2, alc861_uniwill_m31_ch2_init },
8440         { 4, alc861_uniwill_m31_ch4_init },
8441 };
8442
8443 /* Set mic1 and line-in as input and unmute the mixer */
8444 static struct hda_verb alc861_asus_ch2_init[] = {
8445         /* set pin widget 1Ah (line in) for input */
8446         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8447         /* set pin widget 18h (mic1/2) for input, for mic also enable
8448          * the vref
8449          */
8450         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8451
8452         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8453 #if 0
8454         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8455         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8456 #endif
8457         { } /* end */
8458 };
8459 /* Set mic1 nad line-in as output and mute mixer */
8460 static struct hda_verb alc861_asus_ch6_init[] = {
8461         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8462         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8463         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8464         /* set pin widget 18h (mic1) for output (CLFE)*/
8465         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8466         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8467         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8468         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8469
8470         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8471 #if 0
8472         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8473         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8474 #endif
8475         { } /* end */
8476 };
8477
8478 static struct hda_channel_mode alc861_asus_modes[2] = {
8479         { 2, alc861_asus_ch2_init },
8480         { 6, alc861_asus_ch6_init },
8481 };
8482
8483 /* patch-ALC861 */
8484
8485 static struct snd_kcontrol_new alc861_base_mixer[] = {
8486         /* output mixer control */
8487         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8488         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8489         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8490         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8491         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8492
8493         /*Input mixer control */
8494         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8495            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8496         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8497         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8498         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8499         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8500         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8501         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8502         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8503         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8504
8505         /* Capture mixer control */
8506         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8507         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8508         {
8509                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8510                 .name = "Capture Source",
8511                 .count = 1,
8512                 .info = alc_mux_enum_info,
8513                 .get = alc_mux_enum_get,
8514                 .put = alc_mux_enum_put,
8515         },
8516         { } /* end */
8517 };
8518
8519 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8520         /* output mixer control */
8521         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8522         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8523         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8524         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8525         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8526
8527         /* Input mixer control */
8528         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8529            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8530         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8531         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8532         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8533         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8534         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8535         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8536         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8537         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8538
8539         /* Capture mixer control */
8540         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8541         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8542         {
8543                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8544                 .name = "Capture Source",
8545                 .count = 1,
8546                 .info = alc_mux_enum_info,
8547                 .get = alc_mux_enum_get,
8548                 .put = alc_mux_enum_put,
8549         },
8550         {
8551                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8552                 .name = "Channel Mode",
8553                 .info = alc_ch_mode_info,
8554                 .get = alc_ch_mode_get,
8555                 .put = alc_ch_mode_put,
8556                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
8557         },
8558         { } /* end */
8559 };
8560
8561 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8562         /* output mixer control */
8563         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8564         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8565         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8566         
8567         /*Capture mixer control */
8568         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8569         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8570         {
8571                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8572                 .name = "Capture Source",
8573                 .count = 1,
8574                 .info = alc_mux_enum_info,
8575                 .get = alc_mux_enum_get,
8576                 .put = alc_mux_enum_put,
8577         },
8578
8579         { } /* end */
8580 };
8581
8582 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8583         /* output mixer control */
8584         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8585         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8586         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8587         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8588         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8589
8590         /* Input mixer control */
8591         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8592            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8593         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8594         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8595         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8596         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8597         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8598         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8599         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8600         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8601
8602         /* Capture mixer control */
8603         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8604         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8605         {
8606                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8607                 .name = "Capture Source",
8608                 .count = 1,
8609                 .info = alc_mux_enum_info,
8610                 .get = alc_mux_enum_get,
8611                 .put = alc_mux_enum_put,
8612         },
8613         {
8614                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8615                 .name = "Channel Mode",
8616                 .info = alc_ch_mode_info,
8617                 .get = alc_ch_mode_get,
8618                 .put = alc_ch_mode_put,
8619                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8620         },
8621         { } /* end */
8622 };
8623
8624 static struct snd_kcontrol_new alc861_asus_mixer[] = {
8625         /* output mixer control */
8626         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8627         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8628         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8629         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8630         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8631
8632         /* Input mixer control */
8633         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8634         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8635         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8636         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8637         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8638         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8639         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8640         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8641         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8642         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
8643
8644         /* Capture mixer control */
8645         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8646         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8647         {
8648                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8649                 .name = "Capture Source",
8650                 .count = 1,
8651                 .info = alc_mux_enum_info,
8652                 .get = alc_mux_enum_get,
8653                 .put = alc_mux_enum_put,
8654         },
8655         {
8656                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8657                 .name = "Channel Mode",
8658                 .info = alc_ch_mode_info,
8659                 .get = alc_ch_mode_get,
8660                 .put = alc_ch_mode_put,
8661                 .private_value = ARRAY_SIZE(alc861_asus_modes),
8662         },
8663         { }
8664 };
8665
8666 /* additional mixer */
8667 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
8668         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8669         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8670         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
8671         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
8672         { }
8673 };
8674
8675 /*
8676  * generic initialization of ADC, input mixers and output mixers
8677  */
8678 static struct hda_verb alc861_base_init_verbs[] = {
8679         /*
8680          * Unmute ADC0 and set the default input to mic-in
8681          */
8682         /* port-A for surround (rear panel) */
8683         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8684         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
8685         /* port-B for mic-in (rear panel) with vref */
8686         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8687         /* port-C for line-in (rear panel) */
8688         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8689         /* port-D for Front */
8690         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8691         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8692         /* port-E for HP out (front panel) */
8693         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8694         /* route front PCM to HP */
8695         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8696         /* port-F for mic-in (front panel) with vref */
8697         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8698         /* port-G for CLFE (rear panel) */
8699         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8700         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8701         /* port-H for side (rear panel) */
8702         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8703         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
8704         /* CD-in */
8705         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8706         /* route front mic to ADC1*/
8707         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8708         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8709         
8710         /* Unmute DAC0~3 & spdif out*/
8711         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8712         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8713         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8714         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8715         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8716         
8717         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8718         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8719         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8720         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8721         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8722         
8723         /* Unmute Stereo Mixer 15 */
8724         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8725         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8726         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8727         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8728
8729         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8730         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8731         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8732         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8733         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8734         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8735         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8736         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8737         /* hp used DAC 3 (Front) */
8738         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8739         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8740
8741         { }
8742 };
8743
8744 static struct hda_verb alc861_threestack_init_verbs[] = {
8745         /*
8746          * Unmute ADC0 and set the default input to mic-in
8747          */
8748         /* port-A for surround (rear panel) */
8749         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8750         /* port-B for mic-in (rear panel) with vref */
8751         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8752         /* port-C for line-in (rear panel) */
8753         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8754         /* port-D for Front */
8755         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8756         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8757         /* port-E for HP out (front panel) */
8758         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8759         /* route front PCM to HP */
8760         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8761         /* port-F for mic-in (front panel) with vref */
8762         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8763         /* port-G for CLFE (rear panel) */
8764         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8765         /* port-H for side (rear panel) */
8766         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8767         /* CD-in */
8768         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8769         /* route front mic to ADC1*/
8770         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8771         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8772         /* Unmute DAC0~3 & spdif out*/
8773         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8774         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8775         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8776         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8777         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8778         
8779         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8780         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8781         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8782         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8783         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8784         
8785         /* Unmute Stereo Mixer 15 */
8786         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8787         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8788         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8789         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8790
8791         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8792         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8793         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8794         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8795         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8796         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8797         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8798         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8799         /* hp used DAC 3 (Front) */
8800         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8801         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8802         { }
8803 };
8804
8805 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
8806         /*
8807          * Unmute ADC0 and set the default input to mic-in
8808          */
8809         /* port-A for surround (rear panel) */
8810         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8811         /* port-B for mic-in (rear panel) with vref */
8812         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8813         /* port-C for line-in (rear panel) */
8814         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8815         /* port-D for Front */
8816         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8817         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8818         /* port-E for HP out (front panel) */
8819         /* this has to be set to VREF80 */
8820         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8821         /* route front PCM to HP */
8822         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8823         /* port-F for mic-in (front panel) with vref */
8824         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8825         /* port-G for CLFE (rear panel) */
8826         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8827         /* port-H for side (rear panel) */
8828         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8829         /* CD-in */
8830         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8831         /* route front mic to ADC1*/
8832         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8833         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8834         /* Unmute DAC0~3 & spdif out*/
8835         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8836         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8837         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8838         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8839         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8840         
8841         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8842         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8843         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8844         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8845         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8846         
8847         /* Unmute Stereo Mixer 15 */
8848         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8849         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8850         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8851         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8852
8853         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8854         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8855         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8856         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8857         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8858         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8859         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8860         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8861         /* hp used DAC 3 (Front) */
8862         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8863         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8864         { }
8865 };
8866
8867 static struct hda_verb alc861_asus_init_verbs[] = {
8868         /*
8869          * Unmute ADC0 and set the default input to mic-in
8870          */
8871         /* port-A for surround (rear panel)
8872          * according to codec#0 this is the HP jack
8873          */
8874         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
8875         /* route front PCM to HP */
8876         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
8877         /* port-B for mic-in (rear panel) with vref */
8878         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8879         /* port-C for line-in (rear panel) */
8880         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8881         /* port-D for Front */
8882         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8883         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8884         /* port-E for HP out (front panel) */
8885         /* this has to be set to VREF80 */
8886         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8887         /* route front PCM to HP */
8888         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8889         /* port-F for mic-in (front panel) with vref */
8890         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8891         /* port-G for CLFE (rear panel) */
8892         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8893         /* port-H for side (rear panel) */
8894         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8895         /* CD-in */
8896         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8897         /* route front mic to ADC1*/
8898         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8899         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8900         /* Unmute DAC0~3 & spdif out*/
8901         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8902         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8903         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8904         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8905         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8906         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8907         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8908         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8909         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8910         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8911         
8912         /* Unmute Stereo Mixer 15 */
8913         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8914         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8915         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8916         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8917
8918         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8919         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8920         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8921         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8922         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8923         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8924         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8925         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8926         /* hp used DAC 3 (Front) */
8927         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8928         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8929         { }
8930 };
8931
8932 /* additional init verbs for ASUS laptops */
8933 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
8934         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
8935         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
8936         { }
8937 };
8938
8939 /*
8940  * generic initialization of ADC, input mixers and output mixers
8941  */
8942 static struct hda_verb alc861_auto_init_verbs[] = {
8943         /*
8944          * Unmute ADC0 and set the default input to mic-in
8945          */
8946         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
8947         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8948         
8949         /* Unmute DAC0~3 & spdif out*/
8950         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8951         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8952         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8953         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8954         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8955         
8956         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8957         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8958         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8959         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8960         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8961         
8962         /* Unmute Stereo Mixer 15 */
8963         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8964         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8965         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8966         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
8967
8968         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8969         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8970         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8971         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8972         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8973         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8974         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8975         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8976
8977         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8978         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8979         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8980         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8981         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8982         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8983         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8984         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8985
8986         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
8987
8988         { }
8989 };
8990
8991 static struct hda_verb alc861_toshiba_init_verbs[] = {
8992         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8993
8994         { }
8995 };
8996
8997 /* toggle speaker-output according to the hp-jack state */
8998 static void alc861_toshiba_automute(struct hda_codec *codec)
8999 {
9000         unsigned int present;
9001
9002         present = snd_hda_codec_read(codec, 0x0f, 0,
9003                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9004         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
9005                                  0x80, present ? 0x80 : 0);
9006         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
9007                                  0x80, present ? 0x80 : 0);
9008         snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
9009                                  0x80, present ? 0 : 0x80);
9010         snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
9011                                  0x80, present ? 0 : 0x80);
9012 }
9013
9014 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9015                                        unsigned int res)
9016 {
9017         if ((res >> 26) == ALC880_HP_EVENT)
9018                 alc861_toshiba_automute(codec);
9019 }
9020
9021 /* pcm configuration: identiacal with ALC880 */
9022 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
9023 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
9024 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
9025 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
9026
9027
9028 #define ALC861_DIGOUT_NID       0x07
9029
9030 static struct hda_channel_mode alc861_8ch_modes[1] = {
9031         { 8, NULL }
9032 };
9033
9034 static hda_nid_t alc861_dac_nids[4] = {
9035         /* front, surround, clfe, side */
9036         0x03, 0x06, 0x05, 0x04
9037 };
9038
9039 static hda_nid_t alc660_dac_nids[3] = {
9040         /* front, clfe, surround */
9041         0x03, 0x05, 0x06
9042 };
9043
9044 static hda_nid_t alc861_adc_nids[1] = {
9045         /* ADC0-2 */
9046         0x08,
9047 };
9048
9049 static struct hda_input_mux alc861_capture_source = {
9050         .num_items = 5,
9051         .items = {
9052                 { "Mic", 0x0 },
9053                 { "Front Mic", 0x3 },
9054                 { "Line", 0x1 },
9055                 { "CD", 0x4 },
9056                 { "Mixer", 0x5 },
9057         },
9058 };
9059
9060 /* fill in the dac_nids table from the parsed pin configuration */
9061 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9062                                      const struct auto_pin_cfg *cfg)
9063 {
9064         int i;
9065         hda_nid_t nid;
9066
9067         spec->multiout.dac_nids = spec->private_dac_nids;
9068         for (i = 0; i < cfg->line_outs; i++) {
9069                 nid = cfg->line_out_pins[i];
9070                 if (nid) {
9071                         if (i >= ARRAY_SIZE(alc861_dac_nids))
9072                                 continue;
9073                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9074                 }
9075         }
9076         spec->multiout.num_dacs = cfg->line_outs;
9077         return 0;
9078 }
9079
9080 /* add playback controls from the parsed DAC table */
9081 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9082                                              const struct auto_pin_cfg *cfg)
9083 {
9084         char name[32];
9085         static const char *chname[4] = {
9086                 "Front", "Surround", NULL /*CLFE*/, "Side"
9087         };
9088         hda_nid_t nid;
9089         int i, idx, err;
9090
9091         for (i = 0; i < cfg->line_outs; i++) {
9092                 nid = spec->multiout.dac_nids[i];
9093                 if (!nid)
9094                         continue;
9095                 if (nid == 0x05) {
9096                         /* Center/LFE */
9097                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9098                                           "Center Playback Switch",
9099                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9100                                                               HDA_OUTPUT));
9101                         if (err < 0)
9102                                 return err;
9103                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9104                                           "LFE Playback Switch",
9105                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9106                                                               HDA_OUTPUT));
9107                         if (err < 0)
9108                                 return err;
9109                 } else {
9110                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9111                              idx++)
9112                                 if (nid == alc861_dac_nids[idx])
9113                                         break;
9114                         sprintf(name, "%s Playback Switch", chname[idx]);
9115                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9116                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9117                                                               HDA_OUTPUT));
9118                         if (err < 0)
9119                                 return err;
9120                 }
9121         }
9122         return 0;
9123 }
9124
9125 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9126 {
9127         int err;
9128         hda_nid_t nid;
9129
9130         if (!pin)
9131                 return 0;
9132
9133         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9134                 nid = 0x03;
9135                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9136                                   "Headphone Playback Switch",
9137                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9138                 if (err < 0)
9139                         return err;
9140                 spec->multiout.hp_nid = nid;
9141         }
9142         return 0;
9143 }
9144
9145 /* create playback/capture controls for input pins */
9146 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9147                                                 const struct auto_pin_cfg *cfg)
9148 {
9149         struct hda_input_mux *imux = &spec->private_imux;
9150         int i, err, idx, idx1;
9151
9152         for (i = 0; i < AUTO_PIN_LAST; i++) {
9153                 switch (cfg->input_pins[i]) {
9154                 case 0x0c:
9155                         idx1 = 1;
9156                         idx = 2;        /* Line In */
9157                         break;
9158                 case 0x0f:
9159                         idx1 = 2;
9160                         idx = 2;        /* Line In */
9161                         break;
9162                 case 0x0d:
9163                         idx1 = 0;
9164                         idx = 1;        /* Mic In */
9165                         break;
9166                 case 0x10:
9167                         idx1 = 3;
9168                         idx = 1;        /* Mic In */
9169                         break;
9170                 case 0x11:
9171                         idx1 = 4;
9172                         idx = 0;        /* CD */
9173                         break;
9174                 default:
9175                         continue;
9176                 }
9177
9178                 err = new_analog_input(spec, cfg->input_pins[i],
9179                                        auto_pin_cfg_labels[i], idx, 0x15);
9180                 if (err < 0)
9181                         return err;
9182
9183                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9184                 imux->items[imux->num_items].index = idx1;
9185                 imux->num_items++;
9186         }
9187         return 0;
9188 }
9189
9190 static struct snd_kcontrol_new alc861_capture_mixer[] = {
9191         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9192         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9193
9194         {
9195                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9196                 /* The multiple "Capture Source" controls confuse alsamixer
9197                  * So call somewhat different..
9198                  *FIXME: the controls appear in the "playback" view!
9199                  */
9200                 /* .name = "Capture Source", */
9201                 .name = "Input Source",
9202                 .count = 1,
9203                 .info = alc_mux_enum_info,
9204                 .get = alc_mux_enum_get,
9205                 .put = alc_mux_enum_put,
9206         },
9207         { } /* end */
9208 };
9209
9210 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9211                                               hda_nid_t nid,
9212                                               int pin_type, int dac_idx)
9213 {
9214         /* set as output */
9215
9216         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9217                             pin_type);
9218         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9219                             AMP_OUT_UNMUTE);
9220
9221 }
9222
9223 static void alc861_auto_init_multi_out(struct hda_codec *codec)
9224 {
9225         struct alc_spec *spec = codec->spec;
9226         int i;
9227
9228         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9229         for (i = 0; i < spec->autocfg.line_outs; i++) {
9230                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9231                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9232                 if (nid)
9233                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9234                                                           spec->multiout.dac_nids[i]);
9235         }
9236 }
9237
9238 static void alc861_auto_init_hp_out(struct hda_codec *codec)
9239 {
9240         struct alc_spec *spec = codec->spec;
9241         hda_nid_t pin;
9242
9243         pin = spec->autocfg.hp_pins[0];
9244         if (pin) /* connect to front */
9245                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9246                                                   spec->multiout.dac_nids[0]);
9247 }
9248
9249 static void alc861_auto_init_analog_input(struct hda_codec *codec)
9250 {
9251         struct alc_spec *spec = codec->spec;
9252         int i;
9253
9254         for (i = 0; i < AUTO_PIN_LAST; i++) {
9255                 hda_nid_t nid = spec->autocfg.input_pins[i];
9256                 if (nid >= 0x0c && nid <= 0x11) {
9257                         snd_hda_codec_write(codec, nid, 0,
9258                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
9259                                             i <= AUTO_PIN_FRONT_MIC ?
9260                                             PIN_VREF80 : PIN_IN);
9261                 }
9262         }
9263 }
9264
9265 /* parse the BIOS configuration and set up the alc_spec */
9266 /* return 1 if successful, 0 if the proper config is not found,
9267  * or a negative error code
9268  */
9269 static int alc861_parse_auto_config(struct hda_codec *codec)
9270 {
9271         struct alc_spec *spec = codec->spec;
9272         int err;
9273         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9274
9275         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9276                                            alc861_ignore);
9277         if (err < 0)
9278                 return err;
9279         if (!spec->autocfg.line_outs)
9280                 return 0; /* can't find valid BIOS pin config */
9281
9282         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9283         if (err < 0)
9284                 return err;
9285         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9286         if (err < 0)
9287                 return err;
9288         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9289         if (err < 0)
9290                 return err;
9291         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9292         if (err < 0)
9293                 return err;
9294
9295         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9296
9297         if (spec->autocfg.dig_out_pin)
9298                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9299
9300         if (spec->kctl_alloc)
9301                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9302
9303         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9304
9305         spec->num_mux_defs = 1;
9306         spec->input_mux = &spec->private_imux;
9307
9308         spec->adc_nids = alc861_adc_nids;
9309         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9310         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9311         spec->num_mixers++;
9312
9313         return 1;
9314 }
9315
9316 /* additional initialization for auto-configuration model */
9317 static void alc861_auto_init(struct hda_codec *codec)
9318 {
9319         alc861_auto_init_multi_out(codec);
9320         alc861_auto_init_hp_out(codec);
9321         alc861_auto_init_analog_input(codec);
9322 }
9323
9324
9325 /*
9326  * configuration and preset
9327  */
9328 static const char *alc861_models[ALC861_MODEL_LAST] = {
9329         [ALC861_3ST]            = "3stack",
9330         [ALC660_3ST]            = "3stack-660",
9331         [ALC861_3ST_DIG]        = "3stack-dig",
9332         [ALC861_6ST_DIG]        = "6stack-dig",
9333         [ALC861_UNIWILL_M31]    = "uniwill-m31",
9334         [ALC861_TOSHIBA]        = "toshiba",
9335         [ALC861_ASUS]           = "asus",
9336         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
9337         [ALC861_AUTO]           = "auto",
9338 };
9339
9340 static struct snd_pci_quirk alc861_cfg_tbl[] = {
9341         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9342         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9343         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9344         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9345         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9346         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9347         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9348         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9349         SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
9350         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9351         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9352         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9353         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9354         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9355         {}
9356 };
9357
9358 static struct alc_config_preset alc861_presets[] = {
9359         [ALC861_3ST] = {
9360                 .mixers = { alc861_3ST_mixer },
9361                 .init_verbs = { alc861_threestack_init_verbs },
9362                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9363                 .dac_nids = alc861_dac_nids,
9364                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9365                 .channel_mode = alc861_threestack_modes,
9366                 .need_dac_fix = 1,
9367                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9368                 .adc_nids = alc861_adc_nids,
9369                 .input_mux = &alc861_capture_source,
9370         },
9371         [ALC861_3ST_DIG] = {
9372                 .mixers = { alc861_base_mixer },
9373                 .init_verbs = { alc861_threestack_init_verbs },
9374                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9375                 .dac_nids = alc861_dac_nids,
9376                 .dig_out_nid = ALC861_DIGOUT_NID,
9377                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9378                 .channel_mode = alc861_threestack_modes,
9379                 .need_dac_fix = 1,
9380                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9381                 .adc_nids = alc861_adc_nids,
9382                 .input_mux = &alc861_capture_source,
9383         },
9384         [ALC861_6ST_DIG] = {
9385                 .mixers = { alc861_base_mixer },
9386                 .init_verbs = { alc861_base_init_verbs },
9387                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9388                 .dac_nids = alc861_dac_nids,
9389                 .dig_out_nid = ALC861_DIGOUT_NID,
9390                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9391                 .channel_mode = alc861_8ch_modes,
9392                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9393                 .adc_nids = alc861_adc_nids,
9394                 .input_mux = &alc861_capture_source,
9395         },
9396         [ALC660_3ST] = {
9397                 .mixers = { alc861_3ST_mixer },
9398                 .init_verbs = { alc861_threestack_init_verbs },
9399                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
9400                 .dac_nids = alc660_dac_nids,
9401                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9402                 .channel_mode = alc861_threestack_modes,
9403                 .need_dac_fix = 1,
9404                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9405                 .adc_nids = alc861_adc_nids,
9406                 .input_mux = &alc861_capture_source,
9407         },
9408         [ALC861_UNIWILL_M31] = {
9409                 .mixers = { alc861_uniwill_m31_mixer },
9410                 .init_verbs = { alc861_uniwill_m31_init_verbs },
9411                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9412                 .dac_nids = alc861_dac_nids,
9413                 .dig_out_nid = ALC861_DIGOUT_NID,
9414                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9415                 .channel_mode = alc861_uniwill_m31_modes,
9416                 .need_dac_fix = 1,
9417                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9418                 .adc_nids = alc861_adc_nids,
9419                 .input_mux = &alc861_capture_source,
9420         },
9421         [ALC861_TOSHIBA] = {
9422                 .mixers = { alc861_toshiba_mixer },
9423                 .init_verbs = { alc861_base_init_verbs,
9424                                 alc861_toshiba_init_verbs },
9425                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9426                 .dac_nids = alc861_dac_nids,
9427                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9428                 .channel_mode = alc883_3ST_2ch_modes,
9429                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9430                 .adc_nids = alc861_adc_nids,
9431                 .input_mux = &alc861_capture_source,
9432                 .unsol_event = alc861_toshiba_unsol_event,
9433                 .init_hook = alc861_toshiba_automute,
9434         },
9435         [ALC861_ASUS] = {
9436                 .mixers = { alc861_asus_mixer },
9437                 .init_verbs = { alc861_asus_init_verbs },
9438                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9439                 .dac_nids = alc861_dac_nids,
9440                 .dig_out_nid = ALC861_DIGOUT_NID,
9441                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9442                 .channel_mode = alc861_asus_modes,
9443                 .need_dac_fix = 1,
9444                 .hp_nid = 0x06,
9445                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9446                 .adc_nids = alc861_adc_nids,
9447                 .input_mux = &alc861_capture_source,
9448         },
9449         [ALC861_ASUS_LAPTOP] = {
9450                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9451                 .init_verbs = { alc861_asus_init_verbs,
9452                                 alc861_asus_laptop_init_verbs },
9453                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9454                 .dac_nids = alc861_dac_nids,
9455                 .dig_out_nid = ALC861_DIGOUT_NID,
9456                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9457                 .channel_mode = alc883_3ST_2ch_modes,
9458                 .need_dac_fix = 1,
9459                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9460                 .adc_nids = alc861_adc_nids,
9461                 .input_mux = &alc861_capture_source,
9462         },
9463 };
9464
9465
9466 static int patch_alc861(struct hda_codec *codec)
9467 {
9468         struct alc_spec *spec;
9469         int board_config;
9470         int err;
9471
9472         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9473         if (spec == NULL)
9474                 return -ENOMEM;
9475
9476         codec->spec = spec;
9477
9478         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9479                                                   alc861_models,
9480                                                   alc861_cfg_tbl);
9481
9482         if (board_config < 0) {
9483                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9484                        "trying auto-probe from BIOS...\n");
9485                 board_config = ALC861_AUTO;
9486         }
9487
9488         if (board_config == ALC861_AUTO) {
9489                 /* automatic parse from the BIOS config */
9490                 err = alc861_parse_auto_config(codec);
9491                 if (err < 0) {
9492                         alc_free(codec);
9493                         return err;
9494                 } else if (!err) {
9495                         printk(KERN_INFO
9496                                "hda_codec: Cannot set up configuration "
9497                                "from BIOS.  Using base mode...\n");
9498                    board_config = ALC861_3ST_DIG;
9499                 }
9500         }
9501
9502         if (board_config != ALC861_AUTO)
9503                 setup_preset(spec, &alc861_presets[board_config]);
9504
9505         spec->stream_name_analog = "ALC861 Analog";
9506         spec->stream_analog_playback = &alc861_pcm_analog_playback;
9507         spec->stream_analog_capture = &alc861_pcm_analog_capture;
9508
9509         spec->stream_name_digital = "ALC861 Digital";
9510         spec->stream_digital_playback = &alc861_pcm_digital_playback;
9511         spec->stream_digital_capture = &alc861_pcm_digital_capture;
9512
9513         codec->patch_ops = alc_patch_ops;
9514         if (board_config == ALC861_AUTO)
9515                 spec->init_hook = alc861_auto_init;
9516                 
9517         return 0;
9518 }
9519
9520 /*
9521  * ALC861-VD support
9522  *
9523  * Based on ALC882
9524  *
9525  * In addition, an independent DAC
9526  */
9527 #define ALC861VD_DIGOUT_NID     0x06
9528
9529 static hda_nid_t alc861vd_dac_nids[4] = {
9530         /* front, surr, clfe, side surr */
9531         0x02, 0x03, 0x04, 0x05
9532 };
9533
9534 /* dac_nids for ALC660vd are in a different order - according to
9535  * Realtek's driver.
9536  * This should probably tesult in a different mixer for 6stack models
9537  * of ALC660vd codecs, but for now there is only 3stack mixer
9538  * - and it is the same as in 861vd.
9539  * adc_nids in ALC660vd are (is) the same as in 861vd
9540  */
9541 static hda_nid_t alc660vd_dac_nids[3] = {
9542         /* front, rear, clfe, rear_surr */
9543         0x02, 0x04, 0x03
9544 };
9545
9546 static hda_nid_t alc861vd_adc_nids[1] = {
9547         /* ADC0 */
9548         0x09,
9549 };
9550
9551 /* input MUX */
9552 /* FIXME: should be a matrix-type input source selection */
9553 static struct hda_input_mux alc861vd_capture_source = {
9554         .num_items = 4,
9555         .items = {
9556                 { "Mic", 0x0 },
9557                 { "Front Mic", 0x1 },
9558                 { "Line", 0x2 },
9559                 { "CD", 0x4 },
9560         },
9561 };
9562
9563 static struct hda_input_mux alc861vd_dallas_capture_source = {
9564         .num_items = 3,
9565         .items = {
9566                 { "Front Mic", 0x0 },
9567                 { "ATAPI Mic", 0x1 },
9568                 { "Line In", 0x5 },
9569         },
9570 };
9571
9572 #define alc861vd_mux_enum_info alc_mux_enum_info
9573 #define alc861vd_mux_enum_get alc_mux_enum_get
9574
9575 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9576                                 struct snd_ctl_elem_value *ucontrol)
9577 {
9578         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9579         struct alc_spec *spec = codec->spec;
9580         const struct hda_input_mux *imux = spec->input_mux;
9581         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9582         static hda_nid_t capture_mixers[1] = { 0x22 };
9583         hda_nid_t nid = capture_mixers[adc_idx];
9584         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9585         unsigned int i, idx;
9586
9587         idx = ucontrol->value.enumerated.item[0];
9588         if (idx >= imux->num_items)
9589                 idx = imux->num_items - 1;
9590         if (*cur_val == idx && !codec->in_resume)
9591                 return 0;
9592         for (i = 0; i < imux->num_items; i++) {
9593                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
9594                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9595                                     v | (imux->items[i].index << 8));
9596         }
9597         *cur_val = idx;
9598         return 1;
9599 }
9600
9601 /*
9602  * 2ch mode
9603  */
9604 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9605         { 2, NULL }
9606 };
9607
9608 /*
9609  * 6ch mode
9610  */
9611 static struct hda_verb alc861vd_6stack_ch6_init[] = {
9612         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9613         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9614         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9615         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9616         { } /* end */
9617 };
9618
9619 /*
9620  * 8ch mode
9621  */
9622 static struct hda_verb alc861vd_6stack_ch8_init[] = {
9623         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9624         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9625         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9626         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9627         { } /* end */
9628 };
9629
9630 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
9631         { 6, alc861vd_6stack_ch6_init },
9632         { 8, alc861vd_6stack_ch8_init },
9633 };
9634
9635 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
9636         {
9637                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9638                 .name = "Channel Mode",
9639                 .info = alc_ch_mode_info,
9640                 .get = alc_ch_mode_get,
9641                 .put = alc_ch_mode_put,
9642         },
9643         { } /* end */
9644 };
9645
9646 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
9647         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9648         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9649
9650         {
9651                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9652                 /* The multiple "Capture Source" controls confuse alsamixer
9653                  * So call somewhat different..
9654                  *FIXME: the controls appear in the "playback" view!
9655                  */
9656                 /* .name = "Capture Source", */
9657                 .name = "Input Source",
9658                 .count = 1,
9659                 .info = alc861vd_mux_enum_info,
9660                 .get = alc861vd_mux_enum_get,
9661                 .put = alc861vd_mux_enum_put,
9662         },
9663         { } /* end */
9664 };
9665
9666 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9667  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9668  */
9669 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
9670         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9671         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9672
9673         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9674         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9675
9676         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
9677                                 HDA_OUTPUT),
9678         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
9679                                 HDA_OUTPUT),
9680         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9681         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9682
9683         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
9684         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9685
9686         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9687
9688         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9689         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9690         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9691
9692         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9693         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9694         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9695
9696         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9697         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9698
9699         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9700         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9701
9702         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9703         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9704
9705         { } /* end */
9706 };
9707
9708 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
9709         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9710         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9711
9712         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9713
9714         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9715         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9716         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9717
9718         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9719         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9720         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9721
9722         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9723         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9724
9725         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9726         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9727
9728         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9729         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9730
9731         { } /* end */
9732 };
9733
9734 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
9735         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9736         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
9737         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9738
9739         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9740
9741         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9742         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9743         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9744
9745         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9746         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9747         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9748
9749         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9750         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9751
9752         { } /* end */
9753 };
9754
9755 /* Pin assignment: Front=0x14, HP = 0x15,
9756  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
9757  */
9758 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
9759         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9760         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9761         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9762         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
9763         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9764         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9765         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9766         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9767         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
9768         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
9769         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9770         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9771         {
9772                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9773                 /* .name = "Capture Source", */
9774                 .name = "Input Source",
9775                 .count = 1,
9776                 .info = alc882_mux_enum_info,
9777                 .get = alc882_mux_enum_get,
9778                 .put = alc882_mux_enum_put,
9779         },
9780         { } /* end */
9781 };
9782
9783 /*
9784  * generic initialization of ADC, input mixers and output mixers
9785  */
9786 static struct hda_verb alc861vd_volume_init_verbs[] = {
9787         /*
9788          * Unmute ADC0 and set the default input to mic-in
9789          */
9790         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9791         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9792
9793         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
9794          * the analog-loopback mixer widget
9795          */
9796         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9797         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9798         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9799         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9800         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9801         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9802
9803         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
9804         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9805         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9806         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9807         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9808
9809         /*
9810          * Set up output mixers (0x02 - 0x05)
9811          */
9812         /* set vol=0 to output mixers */
9813         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9814         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9815         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9816         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9817
9818         /* set up input amps for analog loopback */
9819         /* Amp Indices: DAC = 0, mixer = 1 */
9820         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9821         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9822         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9823         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9824         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9825         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9826         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9827         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9828
9829         { }
9830 };
9831
9832 /*
9833  * 3-stack pin configuration:
9834  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
9835  */
9836 static struct hda_verb alc861vd_3stack_init_verbs[] = {
9837         /*
9838          * Set pin mode and muting
9839          */
9840         /* set front pin widgets 0x14 for output */
9841         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9842         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9843         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9844
9845         /* Mic (rear) pin: input vref at 80% */
9846         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9847         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9848         /* Front Mic pin: input vref at 80% */
9849         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9850         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9851         /* Line In pin: input */
9852         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9853         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9854         /* Line-2 In: Headphone output (output 0 - 0x0c) */
9855         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9856         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9857         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9858         /* CD pin widget for input */
9859         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9860
9861         { }
9862 };
9863
9864 /*
9865  * 6-stack pin configuration:
9866  */
9867 static struct hda_verb alc861vd_6stack_init_verbs[] = {
9868         /*
9869          * Set pin mode and muting
9870          */
9871         /* set front pin widgets 0x14 for output */
9872         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9873         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9874         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9875
9876         /* Rear Pin: output 1 (0x0d) */
9877         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9878         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9879         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9880         /* CLFE Pin: output 2 (0x0e) */
9881         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9882         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9883         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
9884         /* Side Pin: output 3 (0x0f) */
9885         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9886         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9887         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9888
9889         /* Mic (rear) pin: input vref at 80% */
9890         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9891         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9892         /* Front Mic pin: input vref at 80% */
9893         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9894         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9895         /* Line In pin: input */
9896         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9897         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9898         /* Line-2 In: Headphone output (output 0 - 0x0c) */
9899         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9900         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9901         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9902         /* CD pin widget for input */
9903         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9904
9905         { }
9906 };
9907
9908 static struct hda_verb alc861vd_eapd_verbs[] = {
9909         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9910         { }
9911 };
9912
9913 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
9914         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9915         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9916         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9917         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9918         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
9919         {}
9920 };
9921
9922 /* toggle speaker-output according to the hp-jack state */
9923 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
9924 {
9925         unsigned int present;
9926         unsigned char bits;
9927
9928         present = snd_hda_codec_read(codec, 0x1b, 0,
9929                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9930         bits = present ? 0x80 : 0;
9931         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9932                                  0x80, bits);
9933         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9934                                  0x80, bits);
9935 }
9936
9937 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
9938 {
9939         unsigned int present;
9940         unsigned char bits;
9941
9942         present = snd_hda_codec_read(codec, 0x18, 0,
9943                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9944         bits = present ? 0x80 : 0;
9945         snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
9946                                  0x80, bits);
9947         snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
9948                                  0x80, bits);
9949 }
9950
9951 static void alc861vd_lenovo_automute(struct hda_codec *codec)
9952 {
9953         alc861vd_lenovo_hp_automute(codec);
9954         alc861vd_lenovo_mic_automute(codec);
9955 }
9956
9957 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
9958                                         unsigned int res)
9959 {
9960         switch (res >> 26) {
9961         case ALC880_HP_EVENT:
9962                 alc861vd_lenovo_hp_automute(codec);
9963                 break;
9964         case ALC880_MIC_EVENT:
9965                 alc861vd_lenovo_mic_automute(codec);
9966                 break;
9967         }
9968 }
9969
9970 static struct hda_verb alc861vd_dallas_verbs[] = {
9971         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9972         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9973         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9974         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9975
9976         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9977         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9978         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9979         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9980         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9981         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9982         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9983         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9984         
9985         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9986         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9987         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9988         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9989         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9990         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9991         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9992         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9993
9994         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
9995         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9996         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
9997         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9998         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9999         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10000         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10001         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10002
10003         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10004         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10005         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10006         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10007
10008         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10009         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
10010         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10011
10012         { } /* end */
10013 };
10014
10015 /* toggle speaker-output according to the hp-jack state */
10016 static void alc861vd_dallas_automute(struct hda_codec *codec)
10017 {
10018         unsigned int present;
10019
10020         present = snd_hda_codec_read(codec, 0x15, 0,
10021                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10022         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10023                                  0x80, present ? 0x80 : 0);
10024         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10025                                  0x80, present ? 0x80 : 0);
10026 }
10027
10028 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10029 {
10030         if ((res >> 26) == ALC880_HP_EVENT)
10031                 alc861vd_dallas_automute(codec);
10032 }
10033
10034 /* pcm configuration: identiacal with ALC880 */
10035 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
10036 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
10037 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
10038 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
10039
10040 /*
10041  * configuration and preset
10042  */
10043 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10044         [ALC660VD_3ST]          = "3stack-660",
10045         [ALC660VD_3ST_DIG]= "3stack-660-digout",
10046         [ALC861VD_3ST]          = "3stack",
10047         [ALC861VD_3ST_DIG]      = "3stack-digout",
10048         [ALC861VD_6ST_DIG]      = "6stack-digout",
10049         [ALC861VD_LENOVO]       = "lenovo",
10050         [ALC861VD_DALLAS]       = "dallas",
10051         [ALC861VD_AUTO]         = "auto",
10052 };
10053
10054 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10055         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10056         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10057         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10058         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10059         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10060
10061         SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10062         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10063         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10064         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10065         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10066         {}
10067 };
10068
10069 static struct alc_config_preset alc861vd_presets[] = {
10070         [ALC660VD_3ST] = {
10071                 .mixers = { alc861vd_3st_mixer },
10072                 .init_verbs = { alc861vd_volume_init_verbs,
10073                                  alc861vd_3stack_init_verbs },
10074                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10075                 .dac_nids = alc660vd_dac_nids,
10076                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10077                 .adc_nids = alc861vd_adc_nids,
10078                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10079                 .channel_mode = alc861vd_3stack_2ch_modes,
10080                 .input_mux = &alc861vd_capture_source,
10081         },
10082         [ALC660VD_3ST_DIG] = {
10083                 .mixers = { alc861vd_3st_mixer },
10084                 .init_verbs = { alc861vd_volume_init_verbs,
10085                                  alc861vd_3stack_init_verbs },
10086                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10087                 .dac_nids = alc660vd_dac_nids,
10088                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10089                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10090                 .adc_nids = alc861vd_adc_nids,
10091                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10092                 .channel_mode = alc861vd_3stack_2ch_modes,
10093                 .input_mux = &alc861vd_capture_source,
10094         },
10095         [ALC861VD_3ST] = {
10096                 .mixers = { alc861vd_3st_mixer },
10097                 .init_verbs = { alc861vd_volume_init_verbs,
10098                                  alc861vd_3stack_init_verbs },
10099                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10100                 .dac_nids = alc861vd_dac_nids,
10101                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10102                 .channel_mode = alc861vd_3stack_2ch_modes,
10103                 .input_mux = &alc861vd_capture_source,
10104         },
10105         [ALC861VD_3ST_DIG] = {
10106                 .mixers = { alc861vd_3st_mixer },
10107                 .init_verbs = { alc861vd_volume_init_verbs,
10108                                  alc861vd_3stack_init_verbs },
10109                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10110                 .dac_nids = alc861vd_dac_nids,
10111                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10112                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10113                 .channel_mode = alc861vd_3stack_2ch_modes,
10114                 .input_mux = &alc861vd_capture_source,
10115         },
10116         [ALC861VD_6ST_DIG] = {
10117                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10118                 .init_verbs = { alc861vd_volume_init_verbs,
10119                                 alc861vd_6stack_init_verbs },
10120                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10121                 .dac_nids = alc861vd_dac_nids,
10122                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10123                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10124                 .channel_mode = alc861vd_6stack_modes,
10125                 .input_mux = &alc861vd_capture_source,
10126         },
10127         [ALC861VD_LENOVO] = {
10128                 .mixers = { alc861vd_lenovo_mixer },
10129                 .init_verbs = { alc861vd_volume_init_verbs,
10130                                 alc861vd_3stack_init_verbs,
10131                                 alc861vd_eapd_verbs,
10132                                 alc861vd_lenovo_unsol_verbs },
10133                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10134                 .dac_nids = alc660vd_dac_nids,
10135                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10136                 .adc_nids = alc861vd_adc_nids,
10137                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10138                 .channel_mode = alc861vd_3stack_2ch_modes,
10139                 .input_mux = &alc861vd_capture_source,
10140                 .unsol_event = alc861vd_lenovo_unsol_event,
10141                 .init_hook = alc861vd_lenovo_automute,
10142         },
10143         [ALC861VD_DALLAS] = {
10144                 .mixers = { alc861vd_dallas_mixer },
10145                 .init_verbs = { alc861vd_dallas_verbs },
10146                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10147                 .dac_nids = alc861vd_dac_nids,
10148                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10149                 .adc_nids = alc861vd_adc_nids,
10150                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10151                 .channel_mode = alc861vd_3stack_2ch_modes,
10152                 .input_mux = &alc861vd_dallas_capture_source,
10153                 .unsol_event = alc861vd_dallas_unsol_event,
10154                 .init_hook = alc861vd_dallas_automute,
10155         },      
10156 };
10157
10158 /*
10159  * BIOS auto configuration
10160  */
10161 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10162                                 hda_nid_t nid, int pin_type, int dac_idx)
10163 {
10164         /* set as output */
10165         snd_hda_codec_write(codec, nid, 0,
10166                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10167         snd_hda_codec_write(codec, nid, 0,
10168                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10169 }
10170
10171 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10172 {
10173         struct alc_spec *spec = codec->spec;
10174         int i;
10175
10176         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10177         for (i = 0; i <= HDA_SIDE; i++) {
10178                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10179                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10180                 if (nid)
10181                         alc861vd_auto_set_output_and_unmute(codec, nid,
10182                                                             pin_type, i);
10183         }
10184 }
10185
10186
10187 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10188 {
10189         struct alc_spec *spec = codec->spec;
10190         hda_nid_t pin;
10191
10192         pin = spec->autocfg.hp_pins[0];
10193         if (pin) /* connect to front and  use dac 0 */
10194                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10195 }
10196
10197 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
10198 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
10199
10200 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10201 {
10202         struct alc_spec *spec = codec->spec;
10203         int i;
10204
10205         for (i = 0; i < AUTO_PIN_LAST; i++) {
10206                 hda_nid_t nid = spec->autocfg.input_pins[i];
10207                 if (alc861vd_is_input_pin(nid)) {
10208                         snd_hda_codec_write(codec, nid, 0,
10209                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
10210                                         i <= AUTO_PIN_FRONT_MIC ?
10211                                                         PIN_VREF80 : PIN_IN);
10212                         if (nid != ALC861VD_PIN_CD_NID)
10213                                 snd_hda_codec_write(codec, nid, 0,
10214                                                 AC_VERB_SET_AMP_GAIN_MUTE,
10215                                                 AMP_OUT_MUTE);
10216                 }
10217         }
10218 }
10219
10220 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
10221 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
10222
10223 /* add playback controls from the parsed DAC table */
10224 /* Based on ALC880 version. But ALC861VD has separate,
10225  * different NIDs for mute/unmute switch and volume control */
10226 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10227                                              const struct auto_pin_cfg *cfg)
10228 {
10229         char name[32];
10230         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10231         hda_nid_t nid_v, nid_s;
10232         int i, err;
10233
10234         for (i = 0; i < cfg->line_outs; i++) {
10235                 if (!spec->multiout.dac_nids[i])
10236                         continue;
10237                 nid_v = alc861vd_idx_to_mixer_vol(
10238                                 alc880_dac_to_idx(
10239                                         spec->multiout.dac_nids[i]));
10240                 nid_s = alc861vd_idx_to_mixer_switch(
10241                                 alc880_dac_to_idx(
10242                                         spec->multiout.dac_nids[i]));
10243
10244                 if (i == 2) {
10245                         /* Center/LFE */
10246                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10247                                           "Center Playback Volume",
10248                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10249                                                               HDA_OUTPUT));
10250                         if (err < 0)
10251                                 return err;
10252                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10253                                           "LFE Playback Volume",
10254                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10255                                                               HDA_OUTPUT));
10256                         if (err < 0)
10257                                 return err;
10258                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10259                                           "Center Playback Switch",
10260                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10261                                                               HDA_INPUT));
10262                         if (err < 0)
10263                                 return err;
10264                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10265                                           "LFE Playback Switch",
10266                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10267                                                               HDA_INPUT));
10268                         if (err < 0)
10269                                 return err;
10270                 } else {
10271                         sprintf(name, "%s Playback Volume", chname[i]);
10272                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10273                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10274                                                               HDA_OUTPUT));
10275                         if (err < 0)
10276                                 return err;
10277                         sprintf(name, "%s Playback Switch", chname[i]);
10278                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10279                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10280                                                               HDA_INPUT));
10281                         if (err < 0)
10282                                 return err;
10283                 }
10284         }
10285         return 0;
10286 }
10287
10288 /* add playback controls for speaker and HP outputs */
10289 /* Based on ALC880 version. But ALC861VD has separate,
10290  * different NIDs for mute/unmute switch and volume control */
10291 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10292                                         hda_nid_t pin, const char *pfx)
10293 {
10294         hda_nid_t nid_v, nid_s;
10295         int err;
10296         char name[32];
10297
10298         if (!pin)
10299                 return 0;
10300
10301         if (alc880_is_fixed_pin(pin)) {
10302                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10303                 /* specify the DAC as the extra output */
10304                 if (!spec->multiout.hp_nid)
10305                         spec->multiout.hp_nid = nid_v;
10306                 else
10307                         spec->multiout.extra_out_nid[0] = nid_v;
10308                 /* control HP volume/switch on the output mixer amp */
10309                 nid_v = alc861vd_idx_to_mixer_vol(
10310                                 alc880_fixed_pin_idx(pin));
10311                 nid_s = alc861vd_idx_to_mixer_switch(
10312                                 alc880_fixed_pin_idx(pin));
10313
10314                 sprintf(name, "%s Playback Volume", pfx);
10315                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10316                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10317                 if (err < 0)
10318                         return err;
10319                 sprintf(name, "%s Playback Switch", pfx);
10320                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10321                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10322                 if (err < 0)
10323                         return err;
10324         } else if (alc880_is_multi_pin(pin)) {
10325                 /* set manual connection */
10326                 /* we have only a switch on HP-out PIN */
10327                 sprintf(name, "%s Playback Switch", pfx);
10328                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10329                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10330                 if (err < 0)
10331                         return err;
10332         }
10333         return 0;
10334 }
10335
10336 /* parse the BIOS configuration and set up the alc_spec
10337  * return 1 if successful, 0 if the proper config is not found,
10338  * or a negative error code
10339  * Based on ALC880 version - had to change it to override
10340  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10341 static int alc861vd_parse_auto_config(struct hda_codec *codec)
10342 {
10343         struct alc_spec *spec = codec->spec;
10344         int err;
10345         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10346
10347         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10348                                            alc861vd_ignore);
10349         if (err < 0)
10350                 return err;
10351         if (!spec->autocfg.line_outs)
10352                 return 0; /* can't find valid BIOS pin config */
10353
10354         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10355         if (err < 0)
10356                 return err;
10357         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10358         if (err < 0)
10359                 return err;
10360         err = alc861vd_auto_create_extra_out(spec,
10361                                              spec->autocfg.speaker_pins[0],
10362                                              "Speaker");
10363         if (err < 0)
10364                 return err;
10365         err = alc861vd_auto_create_extra_out(spec,
10366                                              spec->autocfg.hp_pins[0],
10367                                              "Headphone");
10368         if (err < 0)
10369                 return err;
10370         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10371         if (err < 0)
10372                 return err;
10373
10374         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10375
10376         if (spec->autocfg.dig_out_pin)
10377                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10378
10379         if (spec->kctl_alloc)
10380                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10381
10382         spec->init_verbs[spec->num_init_verbs++]
10383                 = alc861vd_volume_init_verbs;
10384
10385         spec->num_mux_defs = 1;
10386         spec->input_mux = &spec->private_imux;
10387
10388         return 1;
10389 }
10390
10391 /* additional initialization for auto-configuration model */
10392 static void alc861vd_auto_init(struct hda_codec *codec)
10393 {
10394         alc861vd_auto_init_multi_out(codec);
10395         alc861vd_auto_init_hp_out(codec);
10396         alc861vd_auto_init_analog_input(codec);
10397 }
10398
10399 static int patch_alc861vd(struct hda_codec *codec)
10400 {
10401         struct alc_spec *spec;
10402         int err, board_config;
10403
10404         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10405         if (spec == NULL)
10406                 return -ENOMEM;
10407
10408         codec->spec = spec;
10409
10410         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10411                                                   alc861vd_models,
10412                                                   alc861vd_cfg_tbl);
10413
10414         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10415                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10416                         "ALC861VD, trying auto-probe from BIOS...\n");
10417                 board_config = ALC861VD_AUTO;
10418         }
10419
10420         if (board_config == ALC861VD_AUTO) {
10421                 /* automatic parse from the BIOS config */
10422                 err = alc861vd_parse_auto_config(codec);
10423                 if (err < 0) {
10424                         alc_free(codec);
10425                         return err;
10426                 } else if (!err) {
10427                         printk(KERN_INFO
10428                                "hda_codec: Cannot set up configuration "
10429                                "from BIOS.  Using base mode...\n");
10430                         board_config = ALC861VD_3ST;
10431                 }
10432         }
10433
10434         if (board_config != ALC861VD_AUTO)
10435                 setup_preset(spec, &alc861vd_presets[board_config]);
10436
10437         spec->stream_name_analog = "ALC861VD Analog";
10438         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10439         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10440
10441         spec->stream_name_digital = "ALC861VD Digital";
10442         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10443         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10444
10445         spec->adc_nids = alc861vd_adc_nids;
10446         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10447
10448         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10449         spec->num_mixers++;
10450
10451         codec->patch_ops = alc_patch_ops;
10452
10453         if (board_config == ALC861VD_AUTO)
10454                 spec->init_hook = alc861vd_auto_init;
10455
10456         return 0;
10457 }
10458
10459 /*
10460  * ALC662 support
10461  *
10462  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10463  * configuration.  Each pin widget can choose any input DACs and a mixer.
10464  * Each ADC is connected from a mixer of all inputs.  This makes possible
10465  * 6-channel independent captures.
10466  *
10467  * In addition, an independent DAC for the multi-playback (not used in this
10468  * driver yet).
10469  */
10470 #define ALC662_DIGOUT_NID       0x06
10471 #define ALC662_DIGIN_NID        0x0a
10472
10473 static hda_nid_t alc662_dac_nids[4] = {
10474         /* front, rear, clfe, rear_surr */
10475         0x02, 0x03, 0x04
10476 };
10477
10478 static hda_nid_t alc662_adc_nids[1] = {
10479         /* ADC1-2 */
10480         0x09,
10481 };
10482 /* input MUX */
10483 /* FIXME: should be a matrix-type input source selection */
10484
10485 static struct hda_input_mux alc662_capture_source = {
10486         .num_items = 4,
10487         .items = {
10488                 { "Mic", 0x0 },
10489                 { "Front Mic", 0x1 },
10490                 { "Line", 0x2 },
10491                 { "CD", 0x4 },
10492         },
10493 };
10494
10495 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10496         .num_items = 2,
10497         .items = {
10498                 { "Mic", 0x1 },
10499                 { "Line", 0x2 },
10500         },
10501 };
10502 #define alc662_mux_enum_info alc_mux_enum_info
10503 #define alc662_mux_enum_get alc_mux_enum_get
10504
10505 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10506                                struct snd_ctl_elem_value *ucontrol)
10507 {
10508         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10509         struct alc_spec *spec = codec->spec;
10510         const struct hda_input_mux *imux = spec->input_mux;
10511         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10512         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
10513         hda_nid_t nid = capture_mixers[adc_idx];
10514         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10515         unsigned int i, idx;
10516
10517         idx = ucontrol->value.enumerated.item[0];
10518         if (idx >= imux->num_items)
10519                 idx = imux->num_items - 1;
10520         if (*cur_val == idx && !codec->in_resume)
10521                 return 0;
10522         for (i = 0; i < imux->num_items; i++) {
10523                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
10524                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10525                                     v | (imux->items[i].index << 8));
10526         }
10527         *cur_val = idx;
10528         return 1;
10529 }
10530 /*
10531  * 2ch mode
10532  */
10533 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10534         { 2, NULL }
10535 };
10536
10537 /*
10538  * 2ch mode
10539  */
10540 static struct hda_verb alc662_3ST_ch2_init[] = {
10541         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10542         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10543         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10544         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10545         { } /* end */
10546 };
10547
10548 /*
10549  * 6ch mode
10550  */
10551 static struct hda_verb alc662_3ST_ch6_init[] = {
10552         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10553         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10554         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10555         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10556         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10557         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10558         { } /* end */
10559 };
10560
10561 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10562         { 2, alc662_3ST_ch2_init },
10563         { 6, alc662_3ST_ch6_init },
10564 };
10565
10566 /*
10567  * 2ch mode
10568  */
10569 static struct hda_verb alc662_sixstack_ch6_init[] = {
10570         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10571         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10572         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10573         { } /* end */
10574 };
10575
10576 /*
10577  * 6ch mode
10578  */
10579 static struct hda_verb alc662_sixstack_ch8_init[] = {
10580         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10581         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10582         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10583         { } /* end */
10584 };
10585
10586 static struct hda_channel_mode alc662_5stack_modes[2] = {
10587         { 2, alc662_sixstack_ch6_init },
10588         { 6, alc662_sixstack_ch8_init },
10589 };
10590
10591 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10592  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10593  */
10594
10595 static struct snd_kcontrol_new alc662_base_mixer[] = {
10596         /* output mixer control */
10597         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10598         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
10599         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10600         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10601         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10602         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10603         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10604         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10605         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10606
10607         /*Input mixer control */
10608         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
10609         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
10610         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
10611         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
10612         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
10613         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
10614         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
10615         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
10616
10617         /* Capture mixer control */
10618         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10619         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10620         {
10621                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10622                 .name = "Capture Source",
10623                 .count = 1,
10624                 .info = alc_mux_enum_info,
10625                 .get = alc_mux_enum_get,
10626                 .put = alc_mux_enum_put,
10627         },
10628         { } /* end */
10629 };
10630
10631 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
10632         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10633         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10634         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10635         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10636         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10637         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10638         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10639         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10640         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10641         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10642         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10643         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10644         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10645         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10646         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10647         {
10648                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10649                 /* .name = "Capture Source", */
10650                 .name = "Input Source",
10651                 .count = 1,
10652                 .info = alc662_mux_enum_info,
10653                 .get = alc662_mux_enum_get,
10654                 .put = alc662_mux_enum_put,
10655         },
10656         { } /* end */
10657 };
10658
10659 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
10660         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10661         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10662         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10663         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
10664         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10665         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10666         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10667         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10668         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10669         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10670         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10671         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10672         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10673         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10674         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10675         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10676         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10677         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10678         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10679         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10680         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10681         {
10682                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10683                 /* .name = "Capture Source", */
10684                 .name = "Input Source",
10685                 .count = 1,
10686                 .info = alc662_mux_enum_info,
10687                 .get = alc662_mux_enum_get,
10688                 .put = alc662_mux_enum_put,
10689         },
10690         { } /* end */
10691 };
10692
10693 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
10694         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10695         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10696         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10697         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
10698         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10699         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10700         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10701         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10702         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10703         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10704         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10705         {
10706                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10707                 /* .name = "Capture Source", */
10708                 .name = "Input Source",
10709                 .count = 1,
10710                 .info = alc662_mux_enum_info,
10711                 .get = alc662_mux_enum_get,
10712                 .put = alc662_mux_enum_put,
10713         },
10714         { } /* end */
10715 };
10716
10717 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
10718         {
10719                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10720                 .name = "Channel Mode",
10721                 .info = alc_ch_mode_info,
10722                 .get = alc_ch_mode_get,
10723                 .put = alc_ch_mode_put,
10724         },
10725         { } /* end */
10726 };
10727
10728 static struct hda_verb alc662_init_verbs[] = {
10729         /* ADC: mute amp left and right */
10730         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10731         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10732         /* Front mixer: unmute input/output amp left and right (volume = 0) */
10733
10734         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10735         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10736         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10737         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10738         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10739
10740         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10741         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10742         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10743         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10744         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10745         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10746
10747         /* Front Pin: output 0 (0x0c) */
10748         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10749         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10750
10751         /* Rear Pin: output 1 (0x0d) */
10752         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10753         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10754
10755         /* CLFE Pin: output 2 (0x0e) */
10756         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10757         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10758
10759         /* Mic (rear) pin: input vref at 80% */
10760         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10761         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10762         /* Front Mic pin: input vref at 80% */
10763         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10764         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10765         /* Line In pin: input */
10766         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10767         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10768         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10769         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10770         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10771         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10772         /* CD pin widget for input */
10773         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10774
10775         /* FIXME: use matrix-type input source selection */
10776         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10777         /* Input mixer */
10778         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10779         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10780         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10781         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10782         { }
10783 };
10784
10785 static struct hda_verb alc662_sue_init_verbs[] = {
10786         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
10787         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
10788         {}
10789 };
10790
10791 /*
10792  * generic initialization of ADC, input mixers and output mixers
10793  */
10794 static struct hda_verb alc662_auto_init_verbs[] = {
10795         /*
10796          * Unmute ADC and set the default input to mic-in
10797          */
10798         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10799         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10800
10801         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10802          * mixer widget
10803          * Note: PASD motherboards uses the Line In 2 as the input for front
10804          * panel mic (mic 2)
10805          */
10806         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10807         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10808         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10809         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10810         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10811         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10812
10813         /*
10814          * Set up output mixers (0x0c - 0x0f)
10815          */
10816         /* set vol=0 to output mixers */
10817         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10818         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10819         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10820
10821         /* set up input amps for analog loopback */
10822         /* Amp Indices: DAC = 0, mixer = 1 */
10823         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10824         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10825         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10826         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10827         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10828         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10829
10830
10831         /* FIXME: use matrix-type input source selection */
10832         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10833         /* Input mixer */
10834         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10835         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10836         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10837         /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
10838         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10839
10840         { }
10841 };
10842
10843 /* capture mixer elements */
10844 static struct snd_kcontrol_new alc662_capture_mixer[] = {
10845         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10846         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10847         {
10848                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10849                 /* The multiple "Capture Source" controls confuse alsamixer
10850                  * So call somewhat different..
10851                  * FIXME: the controls appear in the "playback" view!
10852                  */
10853                 /* .name = "Capture Source", */
10854                 .name = "Input Source",
10855                 .count = 1,
10856                 .info = alc882_mux_enum_info,
10857                 .get = alc882_mux_enum_get,
10858                 .put = alc882_mux_enum_put,
10859         },
10860         { } /* end */
10861 };
10862
10863 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
10864 {
10865         unsigned int present;
10866         unsigned char bits;
10867
10868         present = snd_hda_codec_read(codec, 0x14, 0,
10869                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10870         bits = present ? 0x80 : 0;
10871         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
10872                                  0x80, bits);
10873         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
10874                                  0x80, bits);
10875 }
10876
10877 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
10878 {
10879         unsigned int present;
10880         unsigned char bits;
10881
10882         present = snd_hda_codec_read(codec, 0x1b, 0,
10883                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10884         bits = present ? 0x80 : 0;
10885         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
10886                                  0x80, bits);
10887         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
10888                                  0x80, bits);
10889         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10890                                  0x80, bits);
10891         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10892                                  0x80, bits);
10893 }
10894
10895 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
10896                                            unsigned int res)
10897 {
10898         if ((res >> 26) == ALC880_HP_EVENT)
10899                 alc662_lenovo_101e_all_automute(codec);
10900         if ((res >> 26) == ALC880_FRONT_EVENT)
10901                 alc662_lenovo_101e_ispeaker_automute(codec);
10902 }
10903
10904
10905 /* pcm configuration: identiacal with ALC880 */
10906 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
10907 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
10908 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
10909 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
10910
10911 /*
10912  * configuration and preset
10913  */
10914 static const char *alc662_models[ALC662_MODEL_LAST] = {
10915         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
10916         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
10917         [ALC662_3ST_6ch]        = "3stack-6ch",
10918         [ALC662_5ST_DIG]        = "6stack-dig",
10919         [ALC662_LENOVO_101E]    = "lenovo-101e",
10920         [ALC662_AUTO]           = "auto",
10921 };
10922
10923 static struct snd_pci_quirk alc662_cfg_tbl[] = {
10924         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
10925         {}
10926 };
10927
10928 static struct alc_config_preset alc662_presets[] = {
10929         [ALC662_3ST_2ch_DIG] = {
10930                 .mixers = { alc662_3ST_2ch_mixer },
10931                 .init_verbs = { alc662_init_verbs },
10932                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
10933                 .dac_nids = alc662_dac_nids,
10934                 .dig_out_nid = ALC662_DIGOUT_NID,
10935                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10936                 .adc_nids = alc662_adc_nids,
10937                 .dig_in_nid = ALC662_DIGIN_NID,
10938                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
10939                 .channel_mode = alc662_3ST_2ch_modes,
10940                 .input_mux = &alc662_capture_source,
10941         },
10942         [ALC662_3ST_6ch_DIG] = {
10943                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
10944                 .init_verbs = { alc662_init_verbs },
10945                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
10946                 .dac_nids = alc662_dac_nids,
10947                 .dig_out_nid = ALC662_DIGOUT_NID,
10948                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10949                 .adc_nids = alc662_adc_nids,
10950                 .dig_in_nid = ALC662_DIGIN_NID,
10951                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
10952                 .channel_mode = alc662_3ST_6ch_modes,
10953                 .need_dac_fix = 1,
10954                 .input_mux = &alc662_capture_source,
10955         },
10956         [ALC662_3ST_6ch] = {
10957                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
10958                 .init_verbs = { alc662_init_verbs },
10959                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
10960                 .dac_nids = alc662_dac_nids,
10961                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10962                 .adc_nids = alc662_adc_nids,
10963                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
10964                 .channel_mode = alc662_3ST_6ch_modes,
10965                 .need_dac_fix = 1,
10966                 .input_mux = &alc662_capture_source,
10967         },
10968         [ALC662_5ST_DIG] = {
10969                 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
10970                 .init_verbs = { alc662_init_verbs },
10971                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
10972                 .dac_nids = alc662_dac_nids,
10973                 .dig_out_nid = ALC662_DIGOUT_NID,
10974                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10975                 .adc_nids = alc662_adc_nids,
10976                 .dig_in_nid = ALC662_DIGIN_NID,
10977                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
10978                 .channel_mode = alc662_5stack_modes,
10979                 .input_mux = &alc662_capture_source,
10980         },
10981         [ALC662_LENOVO_101E] = {
10982                 .mixers = { alc662_lenovo_101e_mixer },
10983                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
10984                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
10985                 .dac_nids = alc662_dac_nids,
10986                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10987                 .adc_nids = alc662_adc_nids,
10988                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
10989                 .channel_mode = alc662_3ST_2ch_modes,
10990                 .input_mux = &alc662_lenovo_101e_capture_source,
10991                 .unsol_event = alc662_lenovo_101e_unsol_event,
10992                 .init_hook = alc662_lenovo_101e_all_automute,
10993         },
10994
10995 };
10996
10997
10998 /*
10999  * BIOS auto configuration
11000  */
11001
11002 /* add playback controls from the parsed DAC table */
11003 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11004                                              const struct auto_pin_cfg *cfg)
11005 {
11006         char name[32];
11007         static const char *chname[4] = {
11008                 "Front", "Surround", NULL /*CLFE*/, "Side"
11009         };
11010         hda_nid_t nid;
11011         int i, err;
11012
11013         for (i = 0; i < cfg->line_outs; i++) {
11014                 if (!spec->multiout.dac_nids[i])
11015                         continue;
11016                 nid = alc880_idx_to_dac(i);
11017                 if (i == 2) {
11018                         /* Center/LFE */
11019                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11020                                           "Center Playback Volume",
11021                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11022                                                               HDA_OUTPUT));
11023                         if (err < 0)
11024                                 return err;
11025                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11026                                           "LFE Playback Volume",
11027                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11028                                                               HDA_OUTPUT));
11029                         if (err < 0)
11030                                 return err;
11031                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11032                                           "Center Playback Switch",
11033                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11034                                                               HDA_INPUT));
11035                         if (err < 0)
11036                                 return err;
11037                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11038                                           "LFE Playback Switch",
11039                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11040                                                               HDA_INPUT));
11041                         if (err < 0)
11042                                 return err;
11043                 } else {
11044                         sprintf(name, "%s Playback Volume", chname[i]);
11045                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11046                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11047                                                               HDA_OUTPUT));
11048                         if (err < 0)
11049                                 return err;
11050                         sprintf(name, "%s Playback Switch", chname[i]);
11051                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11052                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11053                                                               HDA_INPUT));
11054                         if (err < 0)
11055                                 return err;
11056                 }
11057         }
11058         return 0;
11059 }
11060
11061 /* add playback controls for speaker and HP outputs */
11062 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11063                                         const char *pfx)
11064 {
11065         hda_nid_t nid;
11066         int err;
11067         char name[32];
11068
11069         if (!pin)
11070                 return 0;
11071
11072         if (alc880_is_fixed_pin(pin)) {
11073                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11074                 /* printk("DAC nid=%x\n",nid); */
11075                 /* specify the DAC as the extra output */
11076                 if (!spec->multiout.hp_nid)
11077                         spec->multiout.hp_nid = nid;
11078                 else
11079                         spec->multiout.extra_out_nid[0] = nid;
11080                 /* control HP volume/switch on the output mixer amp */
11081                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11082                 sprintf(name, "%s Playback Volume", pfx);
11083                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11084                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11085                 if (err < 0)
11086                         return err;
11087                 sprintf(name, "%s Playback Switch", pfx);
11088                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11089                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11090                 if (err < 0)
11091                         return err;
11092         } else if (alc880_is_multi_pin(pin)) {
11093                 /* set manual connection */
11094                 /* we have only a switch on HP-out PIN */
11095                 sprintf(name, "%s Playback Switch", pfx);
11096                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11097                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11098                 if (err < 0)
11099                         return err;
11100         }
11101         return 0;
11102 }
11103
11104 /* create playback/capture controls for input pins */
11105 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11106                                                 const struct auto_pin_cfg *cfg)
11107 {
11108         struct hda_input_mux *imux = &spec->private_imux;
11109         int i, err, idx;
11110
11111         for (i = 0; i < AUTO_PIN_LAST; i++) {
11112                 if (alc880_is_input_pin(cfg->input_pins[i])) {
11113                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
11114                         err = new_analog_input(spec, cfg->input_pins[i],
11115                                                auto_pin_cfg_labels[i],
11116                                                idx, 0x0b);
11117                         if (err < 0)
11118                                 return err;
11119                         imux->items[imux->num_items].label =
11120                                 auto_pin_cfg_labels[i];
11121                         imux->items[imux->num_items].index =
11122                                 alc880_input_pin_idx(cfg->input_pins[i]);
11123                         imux->num_items++;
11124                 }
11125         }
11126         return 0;
11127 }
11128
11129 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11130                                               hda_nid_t nid, int pin_type,
11131                                               int dac_idx)
11132 {
11133         /* set as output */
11134         snd_hda_codec_write(codec, nid, 0,
11135                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11136         snd_hda_codec_write(codec, nid, 0,
11137                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11138         /* need the manual connection? */
11139         if (alc880_is_multi_pin(nid)) {
11140                 struct alc_spec *spec = codec->spec;
11141                 int idx = alc880_multi_pin_idx(nid);
11142                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11143                                     AC_VERB_SET_CONNECT_SEL,
11144                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11145         }
11146 }
11147
11148 static void alc662_auto_init_multi_out(struct hda_codec *codec)
11149 {
11150         struct alc_spec *spec = codec->spec;
11151         int i;
11152
11153         for (i = 0; i <= HDA_SIDE; i++) {
11154                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11155                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11156                 if (nid)
11157                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11158                                                           i);
11159         }
11160 }
11161
11162 static void alc662_auto_init_hp_out(struct hda_codec *codec)
11163 {
11164         struct alc_spec *spec = codec->spec;
11165         hda_nid_t pin;
11166
11167         pin = spec->autocfg.hp_pins[0];
11168         if (pin) /* connect to front */
11169                 /* use dac 0 */
11170                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11171 }
11172
11173 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
11174 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
11175
11176 static void alc662_auto_init_analog_input(struct hda_codec *codec)
11177 {
11178         struct alc_spec *spec = codec->spec;
11179         int i;
11180
11181         for (i = 0; i < AUTO_PIN_LAST; i++) {
11182                 hda_nid_t nid = spec->autocfg.input_pins[i];
11183                 if (alc662_is_input_pin(nid)) {
11184                         snd_hda_codec_write(codec, nid, 0,
11185                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
11186                                             (i <= AUTO_PIN_FRONT_MIC ?
11187                                              PIN_VREF80 : PIN_IN));
11188                         if (nid != ALC662_PIN_CD_NID)
11189                                 snd_hda_codec_write(codec, nid, 0,
11190                                                     AC_VERB_SET_AMP_GAIN_MUTE,
11191                                                     AMP_OUT_MUTE);
11192                 }
11193         }
11194 }
11195
11196 static int alc662_parse_auto_config(struct hda_codec *codec)
11197 {
11198         struct alc_spec *spec = codec->spec;
11199         int err;
11200         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11201
11202         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11203                                            alc662_ignore);
11204         if (err < 0)
11205                 return err;
11206         if (!spec->autocfg.line_outs)
11207                 return 0; /* can't find valid BIOS pin config */
11208
11209         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11210         if (err < 0)
11211                 return err;
11212         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11213         if (err < 0)
11214                 return err;
11215         err = alc662_auto_create_extra_out(spec,
11216                                            spec->autocfg.speaker_pins[0],
11217                                            "Speaker");
11218         if (err < 0)
11219                 return err;
11220         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11221                                            "Headphone");
11222         if (err < 0)
11223                 return err;
11224         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11225         if (err < 0)
11226                 return err;
11227
11228         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11229
11230         if (spec->autocfg.dig_out_pin)
11231                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11232
11233         if (spec->kctl_alloc)
11234                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11235
11236         spec->num_mux_defs = 1;
11237         spec->input_mux = &spec->private_imux;
11238         
11239         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11240         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11241         spec->num_mixers++;
11242         return 1;
11243 }
11244
11245 /* additional initialization for auto-configuration model */
11246 static void alc662_auto_init(struct hda_codec *codec)
11247 {
11248         alc662_auto_init_multi_out(codec);
11249         alc662_auto_init_hp_out(codec);
11250         alc662_auto_init_analog_input(codec);
11251 }
11252
11253 static int patch_alc662(struct hda_codec *codec)
11254 {
11255         struct alc_spec *spec;
11256         int err, board_config;
11257
11258         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11259         if (!spec)
11260                 return -ENOMEM;
11261
11262         codec->spec = spec;
11263
11264         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11265                                                   alc662_models,
11266                                                   alc662_cfg_tbl);
11267         if (board_config < 0) {
11268                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11269                        "trying auto-probe from BIOS...\n");
11270                 board_config = ALC662_AUTO;
11271         }
11272
11273         if (board_config == ALC662_AUTO) {
11274                 /* automatic parse from the BIOS config */
11275                 err = alc662_parse_auto_config(codec);
11276                 if (err < 0) {
11277                         alc_free(codec);
11278                         return err;
11279                 } else if (!err) {
11280                         printk(KERN_INFO
11281                                "hda_codec: Cannot set up configuration "
11282                                "from BIOS.  Using base mode...\n");
11283                         board_config = ALC662_3ST_2ch_DIG;
11284                 }
11285         }
11286
11287         if (board_config != ALC662_AUTO)
11288                 setup_preset(spec, &alc662_presets[board_config]);
11289
11290         spec->stream_name_analog = "ALC662 Analog";
11291         spec->stream_analog_playback = &alc662_pcm_analog_playback;
11292         spec->stream_analog_capture = &alc662_pcm_analog_capture;
11293
11294         spec->stream_name_digital = "ALC662 Digital";
11295         spec->stream_digital_playback = &alc662_pcm_digital_playback;
11296         spec->stream_digital_capture = &alc662_pcm_digital_capture;
11297
11298         if (!spec->adc_nids && spec->input_mux) {
11299                 spec->adc_nids = alc662_adc_nids;
11300                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11301         }
11302
11303         codec->patch_ops = alc_patch_ops;
11304         if (board_config == ALC662_AUTO)
11305                 spec->init_hook = alc662_auto_init;
11306
11307         return 0;
11308 }
11309
11310 /*
11311  * patch entries
11312  */
11313 struct hda_codec_preset snd_hda_preset_realtek[] = {
11314         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11315         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11316         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11317         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11318           .patch = patch_alc861 },
11319         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11320         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11321         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11322         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11323           .patch = patch_alc883 },
11324         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11325           .patch = patch_alc662 },
11326         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11327         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11328         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11329         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11330         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11331         {} /* terminator */
11332 };