[ALSA] hda-codec - Add HP Lucknow 5.1 support
[pandora-kernel.git] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_BENQ_ED8,
96         ALC262_SONY_ASSAMD,
97         ALC262_BENQ_T31,
98         ALC262_AUTO,
99         ALC262_MODEL_LAST /* last tag */
100 };
101
102 /* ALC268 models */
103 enum {
104         ALC268_3ST,
105         ALC268_AUTO,
106         ALC268_MODEL_LAST /* last tag */
107 };
108
109 /* ALC861 models */
110 enum {
111         ALC861_3ST,
112         ALC660_3ST,
113         ALC861_3ST_DIG,
114         ALC861_6ST_DIG,
115         ALC861_UNIWILL_M31,
116         ALC861_TOSHIBA,
117         ALC861_ASUS,
118         ALC861_ASUS_LAPTOP,
119         ALC861_AUTO,
120         ALC861_MODEL_LAST,
121 };
122
123 /* ALC861-VD models */
124 enum {
125         ALC660VD_3ST,
126         ALC660VD_3ST_DIG,
127         ALC861VD_3ST,
128         ALC861VD_3ST_DIG,
129         ALC861VD_6ST_DIG,
130         ALC861VD_LENOVO,
131         ALC861VD_DALLAS,
132         ALC861VD_AUTO,
133         ALC861VD_MODEL_LAST,
134 };
135
136 /* ALC662 models */
137 enum {
138         ALC662_3ST_2ch_DIG,
139         ALC662_3ST_6ch_DIG,
140         ALC662_3ST_6ch,
141         ALC662_5ST_DIG,
142         ALC662_LENOVO_101E,
143         ALC662_AUTO,
144         ALC662_MODEL_LAST,
145 };
146
147 /* ALC882 models */
148 enum {
149         ALC882_3ST_DIG,
150         ALC882_6ST_DIG,
151         ALC882_ARIMA,
152         ALC882_W2JC,
153         ALC882_TARGA,
154         ALC882_ASUS_A7J,
155         ALC885_MACPRO,
156         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         ALC888_HP_NETTLE,
176         ALC888_HP_LUCKNOW,
177         ALC883_AUTO,
178         ALC883_MODEL_LAST,
179 };
180
181 /* for GPIO Poll */
182 #define GPIO_MASK       0x03
183
184 struct alc_spec {
185         /* codec parameterization */
186         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
187         unsigned int num_mixers;
188
189         const struct hda_verb *init_verbs[5];   /* initialization verbs
190                                                  * don't forget NULL
191                                                  * termination!
192                                                  */
193         unsigned int num_init_verbs;
194
195         char *stream_name_analog;       /* analog PCM stream */
196         struct hda_pcm_stream *stream_analog_playback;
197         struct hda_pcm_stream *stream_analog_capture;
198
199         char *stream_name_digital;      /* digital PCM stream */
200         struct hda_pcm_stream *stream_digital_playback;
201         struct hda_pcm_stream *stream_digital_capture;
202
203         /* playback */
204         struct hda_multi_out multiout;  /* playback set-up
205                                          * max_channels, dacs must be set
206                                          * dig_out_nid and hp_nid are optional
207                                          */
208
209         /* capture */
210         unsigned int num_adc_nids;
211         hda_nid_t *adc_nids;
212         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
213
214         /* capture source */
215         unsigned int num_mux_defs;
216         const struct hda_input_mux *input_mux;
217         unsigned int cur_mux[3];
218
219         /* channel model */
220         const struct hda_channel_mode *channel_mode;
221         int num_channel_mode;
222         int need_dac_fix;
223
224         /* PCM information */
225         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
226
227         /* dynamic controls, init_verbs and input_mux */
228         struct auto_pin_cfg autocfg;
229         unsigned int num_kctl_alloc, num_kctl_used;
230         struct snd_kcontrol_new *kctl_alloc;
231         struct hda_input_mux private_imux;
232         hda_nid_t private_dac_nids[5];
233
234         /* hooks */
235         void (*init_hook)(struct hda_codec *codec);
236         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
237
238         /* for pin sensing */
239         unsigned int sense_updated: 1;
240         unsigned int jack_present: 1;
241 };
242
243 /*
244  * configuration template - to be copied to the spec instance
245  */
246 struct alc_config_preset {
247         struct snd_kcontrol_new *mixers[5]; /* should be identical size
248                                              * with spec
249                                              */
250         const struct hda_verb *init_verbs[5];
251         unsigned int num_dacs;
252         hda_nid_t *dac_nids;
253         hda_nid_t dig_out_nid;          /* optional */
254         hda_nid_t hp_nid;               /* optional */
255         unsigned int num_adc_nids;
256         hda_nid_t *adc_nids;
257         hda_nid_t dig_in_nid;
258         unsigned int num_channel_mode;
259         const struct hda_channel_mode *channel_mode;
260         int need_dac_fix;
261         unsigned int num_mux_defs;
262         const struct hda_input_mux *input_mux;
263         void (*unsol_event)(struct hda_codec *, unsigned int);
264         void (*init_hook)(struct hda_codec *);
265 };
266
267
268 /*
269  * input MUX handling
270  */
271 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
272                              struct snd_ctl_elem_info *uinfo)
273 {
274         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
275         struct alc_spec *spec = codec->spec;
276         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
277         if (mux_idx >= spec->num_mux_defs)
278                 mux_idx = 0;
279         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
280 }
281
282 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
283                             struct snd_ctl_elem_value *ucontrol)
284 {
285         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
286         struct alc_spec *spec = codec->spec;
287         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
288
289         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
290         return 0;
291 }
292
293 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
294                             struct snd_ctl_elem_value *ucontrol)
295 {
296         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297         struct alc_spec *spec = codec->spec;
298         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
299         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
300         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
301                                      spec->adc_nids[adc_idx],
302                                      &spec->cur_mux[adc_idx]);
303 }
304
305
306 /*
307  * channel mode setting
308  */
309 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
310                             struct snd_ctl_elem_info *uinfo)
311 {
312         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
313         struct alc_spec *spec = codec->spec;
314         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
315                                     spec->num_channel_mode);
316 }
317
318 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
319                            struct snd_ctl_elem_value *ucontrol)
320 {
321         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
322         struct alc_spec *spec = codec->spec;
323         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
324                                    spec->num_channel_mode,
325                                    spec->multiout.max_channels);
326 }
327
328 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
329                            struct snd_ctl_elem_value *ucontrol)
330 {
331         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
332         struct alc_spec *spec = codec->spec;
333         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
334                                       spec->num_channel_mode,
335                                       &spec->multiout.max_channels);
336         if (err >= 0 && spec->need_dac_fix)
337                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
338         return err;
339 }
340
341 /*
342  * Control the mode of pin widget settings via the mixer.  "pc" is used
343  * instead of "%" to avoid consequences of accidently treating the % as 
344  * being part of a format specifier.  Maximum allowed length of a value is
345  * 63 characters plus NULL terminator.
346  *
347  * Note: some retasking pin complexes seem to ignore requests for input
348  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
349  * are requested.  Therefore order this list so that this behaviour will not
350  * cause problems when mixer clients move through the enum sequentially.
351  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
352  * March 2006.
353  */
354 static char *alc_pin_mode_names[] = {
355         "Mic 50pc bias", "Mic 80pc bias",
356         "Line in", "Line out", "Headphone out",
357 };
358 static unsigned char alc_pin_mode_values[] = {
359         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
360 };
361 /* The control can present all 5 options, or it can limit the options based
362  * in the pin being assumed to be exclusively an input or an output pin.  In
363  * addition, "input" pins may or may not process the mic bias option
364  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
365  * accept requests for bias as of chip versions up to March 2006) and/or
366  * wiring in the computer.
367  */
368 #define ALC_PIN_DIR_IN              0x00
369 #define ALC_PIN_DIR_OUT             0x01
370 #define ALC_PIN_DIR_INOUT           0x02
371 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
372 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
373
374 /* Info about the pin modes supported by the different pin direction modes. 
375  * For each direction the minimum and maximum values are given.
376  */
377 static signed char alc_pin_mode_dir_info[5][2] = {
378         { 0, 2 },    /* ALC_PIN_DIR_IN */
379         { 3, 4 },    /* ALC_PIN_DIR_OUT */
380         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
381         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
382         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
383 };
384 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
385 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
386 #define alc_pin_mode_n_items(_dir) \
387         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
388
389 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
390                              struct snd_ctl_elem_info *uinfo)
391 {
392         unsigned int item_num = uinfo->value.enumerated.item;
393         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
394
395         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
396         uinfo->count = 1;
397         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
398
399         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
400                 item_num = alc_pin_mode_min(dir);
401         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
402         return 0;
403 }
404
405 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
406                             struct snd_ctl_elem_value *ucontrol)
407 {
408         unsigned int i;
409         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
410         hda_nid_t nid = kcontrol->private_value & 0xffff;
411         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
412         long *valp = ucontrol->value.integer.value;
413         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
414                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
415                                                  0x00);
416
417         /* Find enumerated value for current pinctl setting */
418         i = alc_pin_mode_min(dir);
419         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
420                 i++;
421         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
422         return 0;
423 }
424
425 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
426                             struct snd_ctl_elem_value *ucontrol)
427 {
428         signed int change;
429         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
430         hda_nid_t nid = kcontrol->private_value & 0xffff;
431         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
432         long val = *ucontrol->value.integer.value;
433         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
434                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
435                                                  0x00);
436
437         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
438                 val = alc_pin_mode_min(dir);
439
440         change = pinctl != alc_pin_mode_values[val];
441         if (change) {
442                 /* Set pin mode to that requested */
443                 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
444                                     alc_pin_mode_values[val]);
445
446                 /* Also enable the retasking pin's input/output as required 
447                  * for the requested pin mode.  Enum values of 2 or less are
448                  * input modes.
449                  *
450                  * Dynamically switching the input/output buffers probably
451                  * reduces noise slightly (particularly on input) so we'll
452                  * do it.  However, having both input and output buffers
453                  * enabled simultaneously doesn't seem to be problematic if
454                  * this turns out to be necessary in the future.
455                  */
456                 if (val <= 2) {
457                         snd_hda_codec_write(codec, nid, 0,
458                                             AC_VERB_SET_AMP_GAIN_MUTE,
459                                             AMP_OUT_MUTE);
460                         snd_hda_codec_write(codec, nid, 0,
461                                             AC_VERB_SET_AMP_GAIN_MUTE,
462                                             AMP_IN_UNMUTE(0));
463                 } else {
464                         snd_hda_codec_write(codec, nid, 0,
465                                             AC_VERB_SET_AMP_GAIN_MUTE,
466                                             AMP_IN_MUTE(0));
467                         snd_hda_codec_write(codec, nid, 0,
468                                             AC_VERB_SET_AMP_GAIN_MUTE,
469                                             AMP_OUT_UNMUTE);
470                 }
471         }
472         return change;
473 }
474
475 #define ALC_PIN_MODE(xname, nid, dir) \
476         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
477           .info = alc_pin_mode_info, \
478           .get = alc_pin_mode_get, \
479           .put = alc_pin_mode_put, \
480           .private_value = nid | (dir<<16) }
481
482 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
483  * together using a mask with more than one bit set.  This control is
484  * currently used only by the ALC260 test model.  At this stage they are not
485  * needed for any "production" models.
486  */
487 #ifdef CONFIG_SND_DEBUG
488 static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
489                               struct snd_ctl_elem_info *uinfo)
490 {
491         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
492         uinfo->count = 1;
493         uinfo->value.integer.min = 0;
494         uinfo->value.integer.max = 1;
495         return 0;
496 }
497
498 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
499                              struct snd_ctl_elem_value *ucontrol)
500 {
501         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
502         hda_nid_t nid = kcontrol->private_value & 0xffff;
503         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
504         long *valp = ucontrol->value.integer.value;
505         unsigned int val = snd_hda_codec_read(codec, nid, 0,
506                                               AC_VERB_GET_GPIO_DATA, 0x00);
507
508         *valp = (val & mask) != 0;
509         return 0;
510 }
511 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
512                              struct snd_ctl_elem_value *ucontrol)
513 {
514         signed int change;
515         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
516         hda_nid_t nid = kcontrol->private_value & 0xffff;
517         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
518         long val = *ucontrol->value.integer.value;
519         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
520                                                     AC_VERB_GET_GPIO_DATA,
521                                                     0x00);
522
523         /* Set/unset the masked GPIO bit(s) as needed */
524         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
525         if (val == 0)
526                 gpio_data &= ~mask;
527         else
528                 gpio_data |= mask;
529         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
530
531         return change;
532 }
533 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
534         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
535           .info = alc_gpio_data_info, \
536           .get = alc_gpio_data_get, \
537           .put = alc_gpio_data_put, \
538           .private_value = nid | (mask<<16) }
539 #endif   /* CONFIG_SND_DEBUG */
540
541 /* A switch control to allow the enabling of the digital IO pins on the
542  * ALC260.  This is incredibly simplistic; the intention of this control is
543  * to provide something in the test model allowing digital outputs to be
544  * identified if present.  If models are found which can utilise these
545  * outputs a more complete mixer control can be devised for those models if
546  * necessary.
547  */
548 #ifdef CONFIG_SND_DEBUG
549 static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
550                                struct snd_ctl_elem_info *uinfo)
551 {
552         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
553         uinfo->count = 1;
554         uinfo->value.integer.min = 0;
555         uinfo->value.integer.max = 1;
556         return 0;
557 }
558
559 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
560                               struct snd_ctl_elem_value *ucontrol)
561 {
562         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
563         hda_nid_t nid = kcontrol->private_value & 0xffff;
564         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
565         long *valp = ucontrol->value.integer.value;
566         unsigned int val = snd_hda_codec_read(codec, nid, 0,
567                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
568
569         *valp = (val & mask) != 0;
570         return 0;
571 }
572 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
573                               struct snd_ctl_elem_value *ucontrol)
574 {
575         signed int change;
576         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
577         hda_nid_t nid = kcontrol->private_value & 0xffff;
578         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
579         long val = *ucontrol->value.integer.value;
580         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
581                                                     AC_VERB_GET_DIGI_CONVERT,
582                                                     0x00);
583
584         /* Set/unset the masked control bit(s) as needed */
585         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
586         if (val==0)
587                 ctrl_data &= ~mask;
588         else
589                 ctrl_data |= mask;
590         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
591                             ctrl_data);
592
593         return change;
594 }
595 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
596         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
597           .info = alc_spdif_ctrl_info, \
598           .get = alc_spdif_ctrl_get, \
599           .put = alc_spdif_ctrl_put, \
600           .private_value = nid | (mask<<16) }
601 #endif   /* CONFIG_SND_DEBUG */
602
603 /*
604  * set up from the preset table
605  */
606 static void setup_preset(struct alc_spec *spec,
607                          const struct alc_config_preset *preset)
608 {
609         int i;
610
611         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
612                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
613         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
614              i++)
615                 spec->init_verbs[spec->num_init_verbs++] =
616                         preset->init_verbs[i];
617         
618         spec->channel_mode = preset->channel_mode;
619         spec->num_channel_mode = preset->num_channel_mode;
620         spec->need_dac_fix = preset->need_dac_fix;
621
622         spec->multiout.max_channels = spec->channel_mode[0].channels;
623
624         spec->multiout.num_dacs = preset->num_dacs;
625         spec->multiout.dac_nids = preset->dac_nids;
626         spec->multiout.dig_out_nid = preset->dig_out_nid;
627         spec->multiout.hp_nid = preset->hp_nid;
628         
629         spec->num_mux_defs = preset->num_mux_defs;
630         if (!spec->num_mux_defs)
631                 spec->num_mux_defs = 1;
632         spec->input_mux = preset->input_mux;
633
634         spec->num_adc_nids = preset->num_adc_nids;
635         spec->adc_nids = preset->adc_nids;
636         spec->dig_in_nid = preset->dig_in_nid;
637
638         spec->unsol_event = preset->unsol_event;
639         spec->init_hook = preset->init_hook;
640 }
641
642 /* Enable GPIO mask and set output */
643 static struct hda_verb alc_gpio1_init_verbs[] = {
644         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
645         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
646         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
647         { }
648 };
649
650 static struct hda_verb alc_gpio2_init_verbs[] = {
651         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
652         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
653         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
654         { }
655 };
656
657 static struct hda_verb alc_gpio3_init_verbs[] = {
658         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
659         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
660         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
661         { }
662 };
663
664 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
665  *      31 ~ 16 :       Manufacture ID
666  *      15 ~ 8  :       SKU ID
667  *      7  ~ 0  :       Assembly ID
668  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
669  */
670 static void alc_subsystem_id(struct hda_codec *codec,
671                              unsigned int porta, unsigned int porte,
672                              unsigned int portd)
673 {
674         unsigned int ass, tmp;
675
676         ass = codec->subsystem_id;
677         if (!(ass & 1))
678                 return;
679
680         /* Override */
681         tmp = (ass & 0x38) >> 3;        /* external Amp control */
682         switch (tmp) {
683         case 1:
684                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
685                 break;
686         case 3:
687                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
688                 break;
689         case 7:
690                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
691                 break;
692         case 5:
693                 switch (codec->vendor_id) {
694                 case 0x10ec0862:
695                 case 0x10ec0660:
696                 case 0x10ec0662:        
697                 case 0x10ec0267:
698                 case 0x10ec0268:
699                         snd_hda_codec_write(codec, 0x14, 0,
700                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
701                         snd_hda_codec_write(codec, 0x15, 0,
702                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
703                         return;
704                 }
705         case 6:
706                 if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
707                         hda_nid_t port = 0;
708                         tmp = (ass & 0x1800) >> 11;
709                         switch (tmp) {
710                         case 0: port = porta; break;
711                         case 1: port = porte; break;
712                         case 2: port = portd; break;
713                         }
714                         if (port)
715                                 snd_hda_codec_write(codec, port, 0,
716                                                     AC_VERB_SET_EAPD_BTLENABLE,
717                                                     2);
718                 }
719                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
720                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
721                                     (tmp == 5 ? 0x3040 : 0x3050));
722                 break;
723         }
724 }
725
726 /*
727  * ALC880 3-stack model
728  *
729  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
730  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
731  *                 F-Mic = 0x1b, HP = 0x19
732  */
733
734 static hda_nid_t alc880_dac_nids[4] = {
735         /* front, rear, clfe, rear_surr */
736         0x02, 0x05, 0x04, 0x03
737 };
738
739 static hda_nid_t alc880_adc_nids[3] = {
740         /* ADC0-2 */
741         0x07, 0x08, 0x09,
742 };
743
744 /* The datasheet says the node 0x07 is connected from inputs,
745  * but it shows zero connection in the real implementation on some devices.
746  * Note: this is a 915GAV bug, fixed on 915GLV
747  */
748 static hda_nid_t alc880_adc_nids_alt[2] = {
749         /* ADC1-2 */
750         0x08, 0x09,
751 };
752
753 #define ALC880_DIGOUT_NID       0x06
754 #define ALC880_DIGIN_NID        0x0a
755
756 static struct hda_input_mux alc880_capture_source = {
757         .num_items = 4,
758         .items = {
759                 { "Mic", 0x0 },
760                 { "Front Mic", 0x3 },
761                 { "Line", 0x2 },
762                 { "CD", 0x4 },
763         },
764 };
765
766 /* channel source setting (2/6 channel selection for 3-stack) */
767 /* 2ch mode */
768 static struct hda_verb alc880_threestack_ch2_init[] = {
769         /* set line-in to input, mute it */
770         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
771         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
772         /* set mic-in to input vref 80%, mute it */
773         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
774         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
775         { } /* end */
776 };
777
778 /* 6ch mode */
779 static struct hda_verb alc880_threestack_ch6_init[] = {
780         /* set line-in to output, unmute it */
781         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
782         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
783         /* set mic-in to output, unmute it */
784         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
785         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
786         { } /* end */
787 };
788
789 static struct hda_channel_mode alc880_threestack_modes[2] = {
790         { 2, alc880_threestack_ch2_init },
791         { 6, alc880_threestack_ch6_init },
792 };
793
794 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
795         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
796         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
797         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
798         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
799         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
800         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
801         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
802         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
803         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
804         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
805         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
806         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
807         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
808         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
809         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
810         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
811         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
812         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
813         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
814         {
815                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
816                 .name = "Channel Mode",
817                 .info = alc_ch_mode_info,
818                 .get = alc_ch_mode_get,
819                 .put = alc_ch_mode_put,
820         },
821         { } /* end */
822 };
823
824 /* capture mixer elements */
825 static struct snd_kcontrol_new alc880_capture_mixer[] = {
826         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
827         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
828         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
829         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
830         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
831         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
832         {
833                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
834                 /* The multiple "Capture Source" controls confuse alsamixer
835                  * So call somewhat different..
836                  * FIXME: the controls appear in the "playback" view!
837                  */
838                 /* .name = "Capture Source", */
839                 .name = "Input Source",
840                 .count = 3,
841                 .info = alc_mux_enum_info,
842                 .get = alc_mux_enum_get,
843                 .put = alc_mux_enum_put,
844         },
845         { } /* end */
846 };
847
848 /* capture mixer elements (in case NID 0x07 not available) */
849 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
850         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
851         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
852         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
853         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
854         {
855                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
856                 /* The multiple "Capture Source" controls confuse alsamixer
857                  * So call somewhat different..
858                  * FIXME: the controls appear in the "playback" view!
859                  */
860                 /* .name = "Capture Source", */
861                 .name = "Input Source",
862                 .count = 2,
863                 .info = alc_mux_enum_info,
864                 .get = alc_mux_enum_get,
865                 .put = alc_mux_enum_put,
866         },
867         { } /* end */
868 };
869
870
871
872 /*
873  * ALC880 5-stack model
874  *
875  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
876  *      Side = 0x02 (0xd)
877  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
878  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
879  */
880
881 /* additional mixers to alc880_three_stack_mixer */
882 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
883         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
884         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
885         { } /* end */
886 };
887
888 /* channel source setting (6/8 channel selection for 5-stack) */
889 /* 6ch mode */
890 static struct hda_verb alc880_fivestack_ch6_init[] = {
891         /* set line-in to input, mute it */
892         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
893         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
894         { } /* end */
895 };
896
897 /* 8ch mode */
898 static struct hda_verb alc880_fivestack_ch8_init[] = {
899         /* set line-in to output, unmute it */
900         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
901         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
902         { } /* end */
903 };
904
905 static struct hda_channel_mode alc880_fivestack_modes[2] = {
906         { 6, alc880_fivestack_ch6_init },
907         { 8, alc880_fivestack_ch8_init },
908 };
909
910
911 /*
912  * ALC880 6-stack model
913  *
914  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
915  *      Side = 0x05 (0x0f)
916  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
917  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
918  */
919
920 static hda_nid_t alc880_6st_dac_nids[4] = {
921         /* front, rear, clfe, rear_surr */
922         0x02, 0x03, 0x04, 0x05
923 };
924
925 static struct hda_input_mux alc880_6stack_capture_source = {
926         .num_items = 4,
927         .items = {
928                 { "Mic", 0x0 },
929                 { "Front Mic", 0x1 },
930                 { "Line", 0x2 },
931                 { "CD", 0x4 },
932         },
933 };
934
935 /* fixed 8-channels */
936 static struct hda_channel_mode alc880_sixstack_modes[1] = {
937         { 8, NULL },
938 };
939
940 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
941         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
942         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
943         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
944         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
945         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
946         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
947         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
948         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
949         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
950         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
951         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
952         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
953         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
954         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
955         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
956         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
957         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
958         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
959         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
960         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
961         {
962                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
963                 .name = "Channel Mode",
964                 .info = alc_ch_mode_info,
965                 .get = alc_ch_mode_get,
966                 .put = alc_ch_mode_put,
967         },
968         { } /* end */
969 };
970
971
972 /*
973  * ALC880 W810 model
974  *
975  * W810 has rear IO for:
976  * Front (DAC 02)
977  * Surround (DAC 03)
978  * Center/LFE (DAC 04)
979  * Digital out (06)
980  *
981  * The system also has a pair of internal speakers, and a headphone jack.
982  * These are both connected to Line2 on the codec, hence to DAC 02.
983  * 
984  * There is a variable resistor to control the speaker or headphone
985  * volume. This is a hardware-only device without a software API.
986  *
987  * Plugging headphones in will disable the internal speakers. This is
988  * implemented in hardware, not via the driver using jack sense. In
989  * a similar fashion, plugging into the rear socket marked "front" will
990  * disable both the speakers and headphones.
991  *
992  * For input, there's a microphone jack, and an "audio in" jack.
993  * These may not do anything useful with this driver yet, because I
994  * haven't setup any initialization verbs for these yet...
995  */
996
997 static hda_nid_t alc880_w810_dac_nids[3] = {
998         /* front, rear/surround, clfe */
999         0x02, 0x03, 0x04
1000 };
1001
1002 /* fixed 6 channels */
1003 static struct hda_channel_mode alc880_w810_modes[1] = {
1004         { 6, NULL }
1005 };
1006
1007 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1008 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1009         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1010         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1011         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1012         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1013         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1014         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1015         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1016         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1017         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1018         { } /* end */
1019 };
1020
1021
1022 /*
1023  * Z710V model
1024  *
1025  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1026  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1027  *                 Line = 0x1a
1028  */
1029
1030 static hda_nid_t alc880_z71v_dac_nids[1] = {
1031         0x02
1032 };
1033 #define ALC880_Z71V_HP_DAC      0x03
1034
1035 /* fixed 2 channels */
1036 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1037         { 2, NULL }
1038 };
1039
1040 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1041         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1042         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1043         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1044         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1045         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1046         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1047         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1048         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1049         { } /* end */
1050 };
1051
1052
1053 /* FIXME! */
1054 /*
1055  * ALC880 F1734 model
1056  *
1057  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1058  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1059  */
1060
1061 static hda_nid_t alc880_f1734_dac_nids[1] = {
1062         0x03
1063 };
1064 #define ALC880_F1734_HP_DAC     0x02
1065
1066 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1067         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1068         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1069         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1070         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1071         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1072         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1073         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1074         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1075         { } /* end */
1076 };
1077
1078
1079 /* FIXME! */
1080 /*
1081  * ALC880 ASUS model
1082  *
1083  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1084  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1085  *  Mic = 0x18, Line = 0x1a
1086  */
1087
1088 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1089 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1090
1091 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1092         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1093         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1094         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1095         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1096         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1097         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1098         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1099         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1100         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1101         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1102         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1103         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1104         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1105         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1106         {
1107                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1108                 .name = "Channel Mode",
1109                 .info = alc_ch_mode_info,
1110                 .get = alc_ch_mode_get,
1111                 .put = alc_ch_mode_put,
1112         },
1113         { } /* end */
1114 };
1115
1116 /* FIXME! */
1117 /*
1118  * ALC880 ASUS W1V model
1119  *
1120  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1121  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1122  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1123  */
1124
1125 /* additional mixers to alc880_asus_mixer */
1126 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1127         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1128         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1129         { } /* end */
1130 };
1131
1132 /* additional mixers to alc880_asus_mixer */
1133 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1134         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1135         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1136         { } /* end */
1137 };
1138
1139 /* TCL S700 */
1140 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1141         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1142         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1143         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1144         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1145         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1146         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1147         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1148         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1149         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1150         {
1151                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1152                 /* The multiple "Capture Source" controls confuse alsamixer
1153                  * So call somewhat different..
1154                  * FIXME: the controls appear in the "playback" view!
1155                  */
1156                 /* .name = "Capture Source", */
1157                 .name = "Input Source",
1158                 .count = 1,
1159                 .info = alc_mux_enum_info,
1160                 .get = alc_mux_enum_get,
1161                 .put = alc_mux_enum_put,
1162         },
1163         { } /* end */
1164 };
1165
1166 /* Uniwill */
1167 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1168         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1169         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1170         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1171         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1172         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1173         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1174         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1175         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1176         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1177         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1178         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1179         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1180         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1181         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1182         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1183         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1184         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1185         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1186         {
1187                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1188                 .name = "Channel Mode",
1189                 .info = alc_ch_mode_info,
1190                 .get = alc_ch_mode_get,
1191                 .put = alc_ch_mode_put,
1192         },
1193         { } /* end */
1194 };
1195
1196 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1197         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1198         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1199         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1200         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1201         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1202         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1203         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1204         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1205         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1206         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1207         { } /* end */
1208 };
1209
1210 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1211         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1212         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1213         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1214         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1215         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1216         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1217         { } /* end */
1218 };
1219
1220 /*
1221  * build control elements
1222  */
1223 static int alc_build_controls(struct hda_codec *codec)
1224 {
1225         struct alc_spec *spec = codec->spec;
1226         int err;
1227         int i;
1228
1229         for (i = 0; i < spec->num_mixers; i++) {
1230                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1231                 if (err < 0)
1232                         return err;
1233         }
1234
1235         if (spec->multiout.dig_out_nid) {
1236                 err = snd_hda_create_spdif_out_ctls(codec,
1237                                                     spec->multiout.dig_out_nid);
1238                 if (err < 0)
1239                         return err;
1240         }
1241         if (spec->dig_in_nid) {
1242                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1243                 if (err < 0)
1244                         return err;
1245         }
1246         return 0;
1247 }
1248
1249
1250 /*
1251  * initialize the codec volumes, etc
1252  */
1253
1254 /*
1255  * generic initialization of ADC, input mixers and output mixers
1256  */
1257 static struct hda_verb alc880_volume_init_verbs[] = {
1258         /*
1259          * Unmute ADC0-2 and set the default input to mic-in
1260          */
1261         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1262         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1263         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1264         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1265         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1266         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1267
1268         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1269          * mixer widget
1270          * Note: PASD motherboards uses the Line In 2 as the input for front
1271          * panel mic (mic 2)
1272          */
1273         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1274         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1275         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1276         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1277         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1278         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1279
1280         /*
1281          * Set up output mixers (0x0c - 0x0f)
1282          */
1283         /* set vol=0 to output mixers */
1284         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1285         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1286         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1287         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1288         /* set up input amps for analog loopback */
1289         /* Amp Indices: DAC = 0, mixer = 1 */
1290         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1291         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1292         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1293         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1294         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1295         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1296         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1297         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1298
1299         { }
1300 };
1301
1302 /*
1303  * 3-stack pin configuration:
1304  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1305  */
1306 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1307         /*
1308          * preset connection lists of input pins
1309          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1310          */
1311         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1312         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1313         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1314
1315         /*
1316          * Set pin mode and muting
1317          */
1318         /* set front pin widgets 0x14 for output */
1319         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1320         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1321         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1322         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1323         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1324         /* Mic2 (as headphone out) for HP output */
1325         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1326         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1327         /* Line In pin widget for input */
1328         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1329         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1330         /* Line2 (as front mic) pin widget for input and vref at 80% */
1331         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1332         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1333         /* CD pin widget for input */
1334         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1335
1336         { }
1337 };
1338
1339 /*
1340  * 5-stack pin configuration:
1341  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1342  * line-in/side = 0x1a, f-mic = 0x1b
1343  */
1344 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1345         /*
1346          * preset connection lists of input pins
1347          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1348          */
1349         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1350         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1351
1352         /*
1353          * Set pin mode and muting
1354          */
1355         /* set pin widgets 0x14-0x17 for output */
1356         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1357         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1358         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1359         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1360         /* unmute pins for output (no gain on this amp) */
1361         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1363         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1364         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1365
1366         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1367         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1368         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1369         /* Mic2 (as headphone out) for HP output */
1370         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1371         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1372         /* Line In pin widget for input */
1373         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1374         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1375         /* Line2 (as front mic) pin widget for input and vref at 80% */
1376         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1377         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1378         /* CD pin widget for input */
1379         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1380
1381         { }
1382 };
1383
1384 /*
1385  * W810 pin configuration:
1386  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1387  */
1388 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1389         /* hphone/speaker input selector: front DAC */
1390         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1391
1392         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1393         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1394         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1395         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1396         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1397         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1398
1399         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1400         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1401
1402         { }
1403 };
1404
1405 /*
1406  * Z71V pin configuration:
1407  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1408  */
1409 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1410         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1411         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1412         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1413         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1414
1415         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1416         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1417         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1418         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1419
1420         { }
1421 };
1422
1423 /*
1424  * 6-stack pin configuration:
1425  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1426  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1427  */
1428 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1429         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1430
1431         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1432         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1433         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1434         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1435         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1436         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1437         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1438         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1439
1440         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1441         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1442         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1443         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1444         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1445         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1446         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1447         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1448         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1449         
1450         { }
1451 };
1452
1453 /*
1454  * Uniwill pin configuration:
1455  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1456  * line = 0x1a
1457  */
1458 static struct hda_verb alc880_uniwill_init_verbs[] = {
1459         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1460
1461         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1462         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1464         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1466         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1468         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1469         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1470         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1471         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1472         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1473         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1474         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1475
1476         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1477         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1478         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1479         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1480         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1481         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1482         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1483         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1484         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1485
1486         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1487         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1488
1489         { }
1490 };
1491
1492 /*
1493 * Uniwill P53
1494 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1495  */
1496 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1497         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1498
1499         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1500         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1501         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1502         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1503         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1504         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1505         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1506         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1507         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1508         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1509         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1510         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1511
1512         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1513         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1514         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1515         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1516         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1517         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1518
1519         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1520         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1521
1522         { }
1523 };
1524
1525 static struct hda_verb alc880_beep_init_verbs[] = {
1526         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1527         { }
1528 };
1529
1530 /* toggle speaker-output according to the hp-jack state */
1531 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1532 {
1533         unsigned int present;
1534         unsigned char bits;
1535
1536         present = snd_hda_codec_read(codec, 0x14, 0,
1537                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1538         bits = present ? 0x80 : 0;
1539         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1540                                  0x80, bits);
1541         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1542                                  0x80, bits);
1543         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1544                                  0x80, bits);
1545         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1546                                  0x80, bits);
1547 }
1548
1549 /* auto-toggle front mic */
1550 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1551 {
1552         unsigned int present;
1553         unsigned char bits;
1554
1555         present = snd_hda_codec_read(codec, 0x18, 0,
1556                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1557         bits = present ? 0x80 : 0;
1558         snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
1559                                  0x80, bits);
1560         snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
1561                                  0x80, bits);
1562 }
1563
1564 static void alc880_uniwill_automute(struct hda_codec *codec)
1565 {
1566         alc880_uniwill_hp_automute(codec);
1567         alc880_uniwill_mic_automute(codec);
1568 }
1569
1570 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1571                                        unsigned int res)
1572 {
1573         /* Looks like the unsol event is incompatible with the standard
1574          * definition.  4bit tag is placed at 28 bit!
1575          */
1576         switch (res >> 28) {
1577         case ALC880_HP_EVENT:
1578                 alc880_uniwill_hp_automute(codec);
1579                 break;
1580         case ALC880_MIC_EVENT:
1581                 alc880_uniwill_mic_automute(codec);
1582                 break;
1583         }
1584 }
1585
1586 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1587 {
1588         unsigned int present;
1589         unsigned char bits;
1590
1591         present = snd_hda_codec_read(codec, 0x14, 0,
1592                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1593         bits = present ? 0x80 : 0;
1594         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1595                                  0x80, bits);
1596         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1597                                  0x80, bits);
1598 }
1599
1600 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1601 {
1602         unsigned int present;
1603         
1604         present = snd_hda_codec_read(codec, 0x21, 0,
1605                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1606
1607         snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1608                                  0x7f, present);
1609         snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1610                                  0x7f,  present);
1611
1612         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1613                                  0x7f,  present);
1614         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1615                                  0x7f, present);
1616
1617 }
1618 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1619                                            unsigned int res)
1620 {
1621         /* Looks like the unsol event is incompatible with the standard
1622          * definition.  4bit tag is placed at 28 bit!
1623          */
1624         if ((res >> 28) == ALC880_HP_EVENT)
1625                 alc880_uniwill_p53_hp_automute(codec);
1626         if ((res >> 28) == ALC880_DCVOL_EVENT)
1627                 alc880_uniwill_p53_dcvol_automute(codec);
1628 }
1629
1630 /* FIXME! */
1631 /*
1632  * F1734 pin configuration:
1633  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1634  */
1635 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1636         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1637         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1638         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1639         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1640
1641         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1642         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1643         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1644         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1645
1646         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1647         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1648         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1649         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1650         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1651         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1652         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1653         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1654         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1655
1656         { }
1657 };
1658
1659 /* FIXME! */
1660 /*
1661  * ASUS pin configuration:
1662  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1663  */
1664 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1665         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1666         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1667         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1668         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1669
1670         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1671         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1672         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1673         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1674         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1675         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1676         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1677         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1678
1679         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1680         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1681         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1682         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1683         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1684         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1685         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1686         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1687         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1688         
1689         { }
1690 };
1691
1692 /* Enable GPIO mask and set output */
1693 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1694 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1695
1696 /* Clevo m520g init */
1697 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1698         /* headphone output */
1699         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1700         /* line-out */
1701         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1702         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1703         /* Line-in */
1704         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1705         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706         /* CD */
1707         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1708         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1709         /* Mic1 (rear panel) */
1710         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1711         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1712         /* Mic2 (front panel) */
1713         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1714         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1715         /* headphone */
1716         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1717         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1718         /* change to EAPD mode */
1719         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1720         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1721
1722         { }
1723 };
1724
1725 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1726         /* change to EAPD mode */
1727         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1728         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1729
1730         /* Headphone output */
1731         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1732         /* Front output*/
1733         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1734         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1735
1736         /* Line In pin widget for input */
1737         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1738         /* CD pin widget for input */
1739         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1740         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1741         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1742
1743         /* change to EAPD mode */
1744         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1745         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1746
1747         { }
1748 };
1749
1750 /*
1751  * LG m1 express dual
1752  *
1753  * Pin assignment:
1754  *   Rear Line-In/Out (blue): 0x14
1755  *   Build-in Mic-In: 0x15
1756  *   Speaker-out: 0x17
1757  *   HP-Out (green): 0x1b
1758  *   Mic-In/Out (red): 0x19
1759  *   SPDIF-Out: 0x1e
1760  */
1761
1762 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1763 static hda_nid_t alc880_lg_dac_nids[3] = {
1764         0x05, 0x02, 0x03
1765 };
1766
1767 /* seems analog CD is not working */
1768 static struct hda_input_mux alc880_lg_capture_source = {
1769         .num_items = 3,
1770         .items = {
1771                 { "Mic", 0x1 },
1772                 { "Line", 0x5 },
1773                 { "Internal Mic", 0x6 },
1774         },
1775 };
1776
1777 /* 2,4,6 channel modes */
1778 static struct hda_verb alc880_lg_ch2_init[] = {
1779         /* set line-in and mic-in to input */
1780         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1781         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1782         { }
1783 };
1784
1785 static struct hda_verb alc880_lg_ch4_init[] = {
1786         /* set line-in to out and mic-in to input */
1787         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1788         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1789         { }
1790 };
1791
1792 static struct hda_verb alc880_lg_ch6_init[] = {
1793         /* set line-in and mic-in to output */
1794         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1795         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1796         { }
1797 };
1798
1799 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1800         { 2, alc880_lg_ch2_init },
1801         { 4, alc880_lg_ch4_init },
1802         { 6, alc880_lg_ch6_init },
1803 };
1804
1805 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1806         /* FIXME: it's not really "master" but front channels */
1807         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1808         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1809         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1810         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1811         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1812         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1813         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1814         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1815         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1816         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1817         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1818         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1819         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1820         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1821         {
1822                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1823                 .name = "Channel Mode",
1824                 .info = alc_ch_mode_info,
1825                 .get = alc_ch_mode_get,
1826                 .put = alc_ch_mode_put,
1827         },
1828         { } /* end */
1829 };
1830
1831 static struct hda_verb alc880_lg_init_verbs[] = {
1832         /* set capture source to mic-in */
1833         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1834         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1835         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1836         /* mute all amp mixer inputs */
1837         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1838         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1839         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1840         /* line-in to input */
1841         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1842         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1843         /* built-in mic */
1844         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1845         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1846         /* speaker-out */
1847         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1848         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1849         /* mic-in to input */
1850         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1851         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1852         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1853         /* HP-out */
1854         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1855         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1856         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1857         /* jack sense */
1858         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1859         { }
1860 };
1861
1862 /* toggle speaker-output according to the hp-jack state */
1863 static void alc880_lg_automute(struct hda_codec *codec)
1864 {
1865         unsigned int present;
1866         unsigned char bits;
1867
1868         present = snd_hda_codec_read(codec, 0x1b, 0,
1869                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1870         bits = present ? 0x80 : 0;
1871         snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1872                                  0x80, bits);
1873         snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1874                                  0x80, bits);
1875 }
1876
1877 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1878 {
1879         /* Looks like the unsol event is incompatible with the standard
1880          * definition.  4bit tag is placed at 28 bit!
1881          */
1882         if ((res >> 28) == 0x01)
1883                 alc880_lg_automute(codec);
1884 }
1885
1886 /*
1887  * LG LW20
1888  *
1889  * Pin assignment:
1890  *   Speaker-out: 0x14
1891  *   Mic-In: 0x18
1892  *   Built-in Mic-In: 0x19 (?)
1893  *   HP-Out: 0x1b
1894  *   SPDIF-Out: 0x1e
1895  */
1896
1897 /* seems analog CD is not working */
1898 static struct hda_input_mux alc880_lg_lw_capture_source = {
1899         .num_items = 2,
1900         .items = {
1901                 { "Mic", 0x0 },
1902                 { "Internal Mic", 0x1 },
1903         },
1904 };
1905
1906 #define alc880_lg_lw_modes alc880_threestack_modes
1907
1908 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1909         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1910         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1911         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1912         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1913         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1914         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1915         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1916         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1917         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1918         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1919         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1920         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1921         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1922         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1923         {
1924                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1925                 .name = "Channel Mode",
1926                 .info = alc_ch_mode_info,
1927                 .get = alc_ch_mode_get,
1928                 .put = alc_ch_mode_put,
1929         },
1930         { } /* end */
1931 };
1932
1933 static struct hda_verb alc880_lg_lw_init_verbs[] = {
1934         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1935         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1936         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1937
1938         /* set capture source to mic-in */
1939         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1940         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1941         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1942         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1943         /* speaker-out */
1944         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1945         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1946         /* HP-out */
1947         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1948         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1949         /* mic-in to input */
1950         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1951         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1952         /* built-in mic */
1953         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1954         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1955         /* jack sense */
1956         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1957         { }
1958 };
1959
1960 /* toggle speaker-output according to the hp-jack state */
1961 static void alc880_lg_lw_automute(struct hda_codec *codec)
1962 {
1963         unsigned int present;
1964         unsigned char bits;
1965
1966         present = snd_hda_codec_read(codec, 0x1b, 0,
1967                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1968         bits = present ? 0x80 : 0;
1969         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1970                                  0x80, bits);
1971         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1972                                  0x80, bits);
1973 }
1974
1975 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1976 {
1977         /* Looks like the unsol event is incompatible with the standard
1978          * definition.  4bit tag is placed at 28 bit!
1979          */
1980         if ((res >> 28) == 0x01)
1981                 alc880_lg_lw_automute(codec);
1982 }
1983
1984 /*
1985  * Common callbacks
1986  */
1987
1988 static int alc_init(struct hda_codec *codec)
1989 {
1990         struct alc_spec *spec = codec->spec;
1991         unsigned int i;
1992
1993         for (i = 0; i < spec->num_init_verbs; i++)
1994                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1995
1996         if (spec->init_hook)
1997                 spec->init_hook(codec);
1998
1999         return 0;
2000 }
2001
2002 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2003 {
2004         struct alc_spec *spec = codec->spec;
2005
2006         if (spec->unsol_event)
2007                 spec->unsol_event(codec, res);
2008 }
2009
2010 #ifdef CONFIG_PM
2011 /*
2012  * resume
2013  */
2014 static int alc_resume(struct hda_codec *codec)
2015 {
2016         struct alc_spec *spec = codec->spec;
2017         int i;
2018
2019         alc_init(codec);
2020         for (i = 0; i < spec->num_mixers; i++)
2021                 snd_hda_resume_ctls(codec, spec->mixers[i]);
2022         if (spec->multiout.dig_out_nid)
2023                 snd_hda_resume_spdif_out(codec);
2024         if (spec->dig_in_nid)
2025                 snd_hda_resume_spdif_in(codec);
2026
2027         return 0;
2028 }
2029 #endif
2030
2031 /*
2032  * Analog playback callbacks
2033  */
2034 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2035                                     struct hda_codec *codec,
2036                                     struct snd_pcm_substream *substream)
2037 {
2038         struct alc_spec *spec = codec->spec;
2039         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2040 }
2041
2042 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2043                                        struct hda_codec *codec,
2044                                        unsigned int stream_tag,
2045                                        unsigned int format,
2046                                        struct snd_pcm_substream *substream)
2047 {
2048         struct alc_spec *spec = codec->spec;
2049         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2050                                                 stream_tag, format, substream);
2051 }
2052
2053 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2054                                        struct hda_codec *codec,
2055                                        struct snd_pcm_substream *substream)
2056 {
2057         struct alc_spec *spec = codec->spec;
2058         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2059 }
2060
2061 /*
2062  * Digital out
2063  */
2064 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2065                                         struct hda_codec *codec,
2066                                         struct snd_pcm_substream *substream)
2067 {
2068         struct alc_spec *spec = codec->spec;
2069         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2070 }
2071
2072 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2073                                            struct hda_codec *codec,
2074                                            unsigned int stream_tag,
2075                                            unsigned int format,
2076                                            struct snd_pcm_substream *substream)
2077 {
2078         struct alc_spec *spec = codec->spec;
2079         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2080                                              stream_tag, format, substream);
2081 }
2082
2083 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2084                                          struct hda_codec *codec,
2085                                          struct snd_pcm_substream *substream)
2086 {
2087         struct alc_spec *spec = codec->spec;
2088         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2089 }
2090
2091 /*
2092  * Analog capture
2093  */
2094 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2095                                       struct hda_codec *codec,
2096                                       unsigned int stream_tag,
2097                                       unsigned int format,
2098                                       struct snd_pcm_substream *substream)
2099 {
2100         struct alc_spec *spec = codec->spec;
2101
2102         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2103                                    stream_tag, 0, format);
2104         return 0;
2105 }
2106
2107 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2108                                       struct hda_codec *codec,
2109                                       struct snd_pcm_substream *substream)
2110 {
2111         struct alc_spec *spec = codec->spec;
2112
2113         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2114                                    0, 0, 0);
2115         return 0;
2116 }
2117
2118
2119 /*
2120  */
2121 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2122         .substreams = 1,
2123         .channels_min = 2,
2124         .channels_max = 8,
2125         /* NID is set in alc_build_pcms */
2126         .ops = {
2127                 .open = alc880_playback_pcm_open,
2128                 .prepare = alc880_playback_pcm_prepare,
2129                 .cleanup = alc880_playback_pcm_cleanup
2130         },
2131 };
2132
2133 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2134         .substreams = 2,
2135         .channels_min = 2,
2136         .channels_max = 2,
2137         /* NID is set in alc_build_pcms */
2138         .ops = {
2139                 .prepare = alc880_capture_pcm_prepare,
2140                 .cleanup = alc880_capture_pcm_cleanup
2141         },
2142 };
2143
2144 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2145         .substreams = 1,
2146         .channels_min = 2,
2147         .channels_max = 2,
2148         /* NID is set in alc_build_pcms */
2149         .ops = {
2150                 .open = alc880_dig_playback_pcm_open,
2151                 .close = alc880_dig_playback_pcm_close,
2152                 .prepare = alc880_dig_playback_pcm_prepare
2153         },
2154 };
2155
2156 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2157         .substreams = 1,
2158         .channels_min = 2,
2159         .channels_max = 2,
2160         /* NID is set in alc_build_pcms */
2161 };
2162
2163 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2164 static struct hda_pcm_stream alc_pcm_null_playback = {
2165         .substreams = 0,
2166         .channels_min = 0,
2167         .channels_max = 0,
2168 };
2169
2170 static int alc_build_pcms(struct hda_codec *codec)
2171 {
2172         struct alc_spec *spec = codec->spec;
2173         struct hda_pcm *info = spec->pcm_rec;
2174         int i;
2175
2176         codec->num_pcms = 1;
2177         codec->pcm_info = info;
2178
2179         info->name = spec->stream_name_analog;
2180         if (spec->stream_analog_playback) {
2181                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2182                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2183                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2184         }
2185         if (spec->stream_analog_capture) {
2186                 snd_assert(spec->adc_nids, return -EINVAL);
2187                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2188                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2189         }
2190
2191         if (spec->channel_mode) {
2192                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2193                 for (i = 0; i < spec->num_channel_mode; i++) {
2194                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2195                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2196                         }
2197                 }
2198         }
2199
2200         /* SPDIF for stream index #1 */
2201         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2202                 codec->num_pcms = 2;
2203                 info = spec->pcm_rec + 1;
2204                 info->name = spec->stream_name_digital;
2205                 if (spec->multiout.dig_out_nid &&
2206                     spec->stream_digital_playback) {
2207                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2208                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2209                 }
2210                 if (spec->dig_in_nid &&
2211                     spec->stream_digital_capture) {
2212                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2213                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2214                 }
2215         }
2216
2217         /* If the use of more than one ADC is requested for the current
2218          * model, configure a second analog capture-only PCM.
2219          */
2220         /* Additional Analaog capture for index #2 */
2221         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2222             spec->adc_nids) {
2223                 codec->num_pcms = 3;
2224                 info = spec->pcm_rec + 2;
2225                 info->name = spec->stream_name_analog;
2226                 /* No playback stream for second PCM */
2227                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2228                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2229                 if (spec->stream_analog_capture) {
2230                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2231                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2232                 }
2233         }
2234
2235         return 0;
2236 }
2237
2238 static void alc_free(struct hda_codec *codec)
2239 {
2240         struct alc_spec *spec = codec->spec;
2241         unsigned int i;
2242
2243         if (!spec)
2244                 return;
2245
2246         if (spec->kctl_alloc) {
2247                 for (i = 0; i < spec->num_kctl_used; i++)
2248                         kfree(spec->kctl_alloc[i].name);
2249                 kfree(spec->kctl_alloc);
2250         }
2251         kfree(spec);
2252 }
2253
2254 /*
2255  */
2256 static struct hda_codec_ops alc_patch_ops = {
2257         .build_controls = alc_build_controls,
2258         .build_pcms = alc_build_pcms,
2259         .init = alc_init,
2260         .free = alc_free,
2261         .unsol_event = alc_unsol_event,
2262 #ifdef CONFIG_PM
2263         .resume = alc_resume,
2264 #endif
2265 };
2266
2267
2268 /*
2269  * Test configuration for debugging
2270  *
2271  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2272  * enum controls.
2273  */
2274 #ifdef CONFIG_SND_DEBUG
2275 static hda_nid_t alc880_test_dac_nids[4] = {
2276         0x02, 0x03, 0x04, 0x05
2277 };
2278
2279 static struct hda_input_mux alc880_test_capture_source = {
2280         .num_items = 7,
2281         .items = {
2282                 { "In-1", 0x0 },
2283                 { "In-2", 0x1 },
2284                 { "In-3", 0x2 },
2285                 { "In-4", 0x3 },
2286                 { "CD", 0x4 },
2287                 { "Front", 0x5 },
2288                 { "Surround", 0x6 },
2289         },
2290 };
2291
2292 static struct hda_channel_mode alc880_test_modes[4] = {
2293         { 2, NULL },
2294         { 4, NULL },
2295         { 6, NULL },
2296         { 8, NULL },
2297 };
2298
2299 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2300                                  struct snd_ctl_elem_info *uinfo)
2301 {
2302         static char *texts[] = {
2303                 "N/A", "Line Out", "HP Out",
2304                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2305         };
2306         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2307         uinfo->count = 1;
2308         uinfo->value.enumerated.items = 8;
2309         if (uinfo->value.enumerated.item >= 8)
2310                 uinfo->value.enumerated.item = 7;
2311         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2312         return 0;
2313 }
2314
2315 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2316                                 struct snd_ctl_elem_value *ucontrol)
2317 {
2318         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2319         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2320         unsigned int pin_ctl, item = 0;
2321
2322         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2323                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2324         if (pin_ctl & AC_PINCTL_OUT_EN) {
2325                 if (pin_ctl & AC_PINCTL_HP_EN)
2326                         item = 2;
2327                 else
2328                         item = 1;
2329         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2330                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2331                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2332                 case AC_PINCTL_VREF_50:  item = 4; break;
2333                 case AC_PINCTL_VREF_GRD: item = 5; break;
2334                 case AC_PINCTL_VREF_80:  item = 6; break;
2335                 case AC_PINCTL_VREF_100: item = 7; break;
2336                 }
2337         }
2338         ucontrol->value.enumerated.item[0] = item;
2339         return 0;
2340 }
2341
2342 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2343                                 struct snd_ctl_elem_value *ucontrol)
2344 {
2345         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2346         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2347         static unsigned int ctls[] = {
2348                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2349                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2350                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2351                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2352                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2353                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2354         };
2355         unsigned int old_ctl, new_ctl;
2356
2357         old_ctl = snd_hda_codec_read(codec, nid, 0,
2358                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2359         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2360         if (old_ctl != new_ctl) {
2361                 snd_hda_codec_write(codec, nid, 0,
2362                                     AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2363                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2364                                     (ucontrol->value.enumerated.item[0] >= 3 ?
2365                                      0xb080 : 0xb000));
2366                 return 1;
2367         }
2368         return 0;
2369 }
2370
2371 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2372                                  struct snd_ctl_elem_info *uinfo)
2373 {
2374         static char *texts[] = {
2375                 "Front", "Surround", "CLFE", "Side"
2376         };
2377         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2378         uinfo->count = 1;
2379         uinfo->value.enumerated.items = 4;
2380         if (uinfo->value.enumerated.item >= 4)
2381                 uinfo->value.enumerated.item = 3;
2382         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2383         return 0;
2384 }
2385
2386 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2387                                 struct snd_ctl_elem_value *ucontrol)
2388 {
2389         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2390         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2391         unsigned int sel;
2392
2393         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2394         ucontrol->value.enumerated.item[0] = sel & 3;
2395         return 0;
2396 }
2397
2398 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2399                                 struct snd_ctl_elem_value *ucontrol)
2400 {
2401         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2402         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2403         unsigned int sel;
2404
2405         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2406         if (ucontrol->value.enumerated.item[0] != sel) {
2407                 sel = ucontrol->value.enumerated.item[0] & 3;
2408                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2409                 return 1;
2410         }
2411         return 0;
2412 }
2413
2414 #define PIN_CTL_TEST(xname,nid) {                       \
2415                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2416                         .name = xname,                 \
2417                         .info = alc_test_pin_ctl_info, \
2418                         .get = alc_test_pin_ctl_get,   \
2419                         .put = alc_test_pin_ctl_put,   \
2420                         .private_value = nid           \
2421                         }
2422
2423 #define PIN_SRC_TEST(xname,nid) {                       \
2424                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2425                         .name = xname,                 \
2426                         .info = alc_test_pin_src_info, \
2427                         .get = alc_test_pin_src_get,   \
2428                         .put = alc_test_pin_src_put,   \
2429                         .private_value = nid           \
2430                         }
2431
2432 static struct snd_kcontrol_new alc880_test_mixer[] = {
2433         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2434         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2435         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2436         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2437         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2438         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2439         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2440         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2441         PIN_CTL_TEST("Front Pin Mode", 0x14),
2442         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2443         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2444         PIN_CTL_TEST("Side Pin Mode", 0x17),
2445         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2446         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2447         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2448         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2449         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2450         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2451         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2452         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2453         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2454         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2455         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2456         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2457         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2458         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2459         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2460         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2461         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2462         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2463         {
2464                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2465                 .name = "Channel Mode",
2466                 .info = alc_ch_mode_info,
2467                 .get = alc_ch_mode_get,
2468                 .put = alc_ch_mode_put,
2469         },
2470         { } /* end */
2471 };
2472
2473 static struct hda_verb alc880_test_init_verbs[] = {
2474         /* Unmute inputs of 0x0c - 0x0f */
2475         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2476         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2477         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2478         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2479         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2480         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2481         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2482         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2483         /* Vol output for 0x0c-0x0f */
2484         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2485         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2486         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2487         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2488         /* Set output pins 0x14-0x17 */
2489         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2490         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2491         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2492         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2493         /* Unmute output pins 0x14-0x17 */
2494         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2495         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2496         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2497         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2498         /* Set input pins 0x18-0x1c */
2499         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2500         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2501         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2502         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2503         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2504         /* Mute input pins 0x18-0x1b */
2505         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2506         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2507         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2508         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2509         /* ADC set up */
2510         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2511         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2512         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2513         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2514         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2515         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2516         /* Analog input/passthru */
2517         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2518         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2519         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2520         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2521         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2522         { }
2523 };
2524 #endif
2525
2526 /*
2527  */
2528
2529 static const char *alc880_models[ALC880_MODEL_LAST] = {
2530         [ALC880_3ST]            = "3stack",
2531         [ALC880_TCL_S700]       = "tcl",
2532         [ALC880_3ST_DIG]        = "3stack-digout",
2533         [ALC880_CLEVO]          = "clevo",
2534         [ALC880_5ST]            = "5stack",
2535         [ALC880_5ST_DIG]        = "5stack-digout",
2536         [ALC880_W810]           = "w810",
2537         [ALC880_Z71V]           = "z71v",
2538         [ALC880_6ST]            = "6stack",
2539         [ALC880_6ST_DIG]        = "6stack-digout",
2540         [ALC880_ASUS]           = "asus",
2541         [ALC880_ASUS_W1V]       = "asus-w1v",
2542         [ALC880_ASUS_DIG]       = "asus-dig",
2543         [ALC880_ASUS_DIG2]      = "asus-dig2",
2544         [ALC880_UNIWILL_DIG]    = "uniwill",
2545         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2546         [ALC880_FUJITSU]        = "fujitsu",
2547         [ALC880_F1734]          = "F1734",
2548         [ALC880_LG]             = "lg",
2549         [ALC880_LG_LW]          = "lg-lw",
2550 #ifdef CONFIG_SND_DEBUG
2551         [ALC880_TEST]           = "test",
2552 #endif
2553         [ALC880_AUTO]           = "auto",
2554 };
2555
2556 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2557         /* Broken BIOS configuration */
2558         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2559         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2560
2561         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2562         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2563         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2564         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2565         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2566         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2567         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2568         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2569         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2570
2571         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2572         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2573
2574         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2575         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2576         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2577         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2578         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2579         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2580         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2581         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2582         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2583         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2584         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2585         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2586         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2587         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2588         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2589
2590         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2591         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2592         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2593         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2594         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2595         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2596         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2597         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2598         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2599         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2600         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2601         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2602         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2603         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2604         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2605         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2606         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2607         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2608
2609         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2610         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2611         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2612         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2613
2614         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2615         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2616         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2617         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2618
2619         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2620         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2621         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2622         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2623
2624         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2625         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2626         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2627         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2628         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2629         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2630         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2631         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2632         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2633         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2634         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2635
2636         {}
2637 };
2638
2639 /*
2640  * ALC880 codec presets
2641  */
2642 static struct alc_config_preset alc880_presets[] = {
2643         [ALC880_3ST] = {
2644                 .mixers = { alc880_three_stack_mixer },
2645                 .init_verbs = { alc880_volume_init_verbs,
2646                                 alc880_pin_3stack_init_verbs },
2647                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2648                 .dac_nids = alc880_dac_nids,
2649                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2650                 .channel_mode = alc880_threestack_modes,
2651                 .need_dac_fix = 1,
2652                 .input_mux = &alc880_capture_source,
2653         },
2654         [ALC880_3ST_DIG] = {
2655                 .mixers = { alc880_three_stack_mixer },
2656                 .init_verbs = { alc880_volume_init_verbs,
2657                                 alc880_pin_3stack_init_verbs },
2658                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2659                 .dac_nids = alc880_dac_nids,
2660                 .dig_out_nid = ALC880_DIGOUT_NID,
2661                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2662                 .channel_mode = alc880_threestack_modes,
2663                 .need_dac_fix = 1,
2664                 .input_mux = &alc880_capture_source,
2665         },
2666         [ALC880_TCL_S700] = {
2667                 .mixers = { alc880_tcl_s700_mixer },
2668                 .init_verbs = { alc880_volume_init_verbs,
2669                                 alc880_pin_tcl_S700_init_verbs,
2670                                 alc880_gpio2_init_verbs },
2671                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2672                 .dac_nids = alc880_dac_nids,
2673                 .hp_nid = 0x03,
2674                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2675                 .channel_mode = alc880_2_jack_modes,
2676                 .input_mux = &alc880_capture_source,
2677         },
2678         [ALC880_5ST] = {
2679                 .mixers = { alc880_three_stack_mixer,
2680                             alc880_five_stack_mixer},
2681                 .init_verbs = { alc880_volume_init_verbs,
2682                                 alc880_pin_5stack_init_verbs },
2683                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2684                 .dac_nids = alc880_dac_nids,
2685                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2686                 .channel_mode = alc880_fivestack_modes,
2687                 .input_mux = &alc880_capture_source,
2688         },
2689         [ALC880_5ST_DIG] = {
2690                 .mixers = { alc880_three_stack_mixer,
2691                             alc880_five_stack_mixer },
2692                 .init_verbs = { alc880_volume_init_verbs,
2693                                 alc880_pin_5stack_init_verbs },
2694                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2695                 .dac_nids = alc880_dac_nids,
2696                 .dig_out_nid = ALC880_DIGOUT_NID,
2697                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2698                 .channel_mode = alc880_fivestack_modes,
2699                 .input_mux = &alc880_capture_source,
2700         },
2701         [ALC880_6ST] = {
2702                 .mixers = { alc880_six_stack_mixer },
2703                 .init_verbs = { alc880_volume_init_verbs,
2704                                 alc880_pin_6stack_init_verbs },
2705                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2706                 .dac_nids = alc880_6st_dac_nids,
2707                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2708                 .channel_mode = alc880_sixstack_modes,
2709                 .input_mux = &alc880_6stack_capture_source,
2710         },
2711         [ALC880_6ST_DIG] = {
2712                 .mixers = { alc880_six_stack_mixer },
2713                 .init_verbs = { alc880_volume_init_verbs,
2714                                 alc880_pin_6stack_init_verbs },
2715                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2716                 .dac_nids = alc880_6st_dac_nids,
2717                 .dig_out_nid = ALC880_DIGOUT_NID,
2718                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2719                 .channel_mode = alc880_sixstack_modes,
2720                 .input_mux = &alc880_6stack_capture_source,
2721         },
2722         [ALC880_W810] = {
2723                 .mixers = { alc880_w810_base_mixer },
2724                 .init_verbs = { alc880_volume_init_verbs,
2725                                 alc880_pin_w810_init_verbs,
2726                                 alc880_gpio2_init_verbs },
2727                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2728                 .dac_nids = alc880_w810_dac_nids,
2729                 .dig_out_nid = ALC880_DIGOUT_NID,
2730                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2731                 .channel_mode = alc880_w810_modes,
2732                 .input_mux = &alc880_capture_source,
2733         },
2734         [ALC880_Z71V] = {
2735                 .mixers = { alc880_z71v_mixer },
2736                 .init_verbs = { alc880_volume_init_verbs,
2737                                 alc880_pin_z71v_init_verbs },
2738                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2739                 .dac_nids = alc880_z71v_dac_nids,
2740                 .dig_out_nid = ALC880_DIGOUT_NID,
2741                 .hp_nid = 0x03,
2742                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2743                 .channel_mode = alc880_2_jack_modes,
2744                 .input_mux = &alc880_capture_source,
2745         },
2746         [ALC880_F1734] = {
2747                 .mixers = { alc880_f1734_mixer },
2748                 .init_verbs = { alc880_volume_init_verbs,
2749                                 alc880_pin_f1734_init_verbs },
2750                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2751                 .dac_nids = alc880_f1734_dac_nids,
2752                 .hp_nid = 0x02,
2753                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2754                 .channel_mode = alc880_2_jack_modes,
2755                 .input_mux = &alc880_capture_source,
2756         },
2757         [ALC880_ASUS] = {
2758                 .mixers = { alc880_asus_mixer },
2759                 .init_verbs = { alc880_volume_init_verbs,
2760                                 alc880_pin_asus_init_verbs,
2761                                 alc880_gpio1_init_verbs },
2762                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2763                 .dac_nids = alc880_asus_dac_nids,
2764                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2765                 .channel_mode = alc880_asus_modes,
2766                 .need_dac_fix = 1,
2767                 .input_mux = &alc880_capture_source,
2768         },
2769         [ALC880_ASUS_DIG] = {
2770                 .mixers = { alc880_asus_mixer },
2771                 .init_verbs = { alc880_volume_init_verbs,
2772                                 alc880_pin_asus_init_verbs,
2773                                 alc880_gpio1_init_verbs },
2774                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2775                 .dac_nids = alc880_asus_dac_nids,
2776                 .dig_out_nid = ALC880_DIGOUT_NID,
2777                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2778                 .channel_mode = alc880_asus_modes,
2779                 .need_dac_fix = 1,
2780                 .input_mux = &alc880_capture_source,
2781         },
2782         [ALC880_ASUS_DIG2] = {
2783                 .mixers = { alc880_asus_mixer },
2784                 .init_verbs = { alc880_volume_init_verbs,
2785                                 alc880_pin_asus_init_verbs,
2786                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2787                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2788                 .dac_nids = alc880_asus_dac_nids,
2789                 .dig_out_nid = ALC880_DIGOUT_NID,
2790                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2791                 .channel_mode = alc880_asus_modes,
2792                 .need_dac_fix = 1,
2793                 .input_mux = &alc880_capture_source,
2794         },
2795         [ALC880_ASUS_W1V] = {
2796                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2797                 .init_verbs = { alc880_volume_init_verbs,
2798                                 alc880_pin_asus_init_verbs,
2799                                 alc880_gpio1_init_verbs },
2800                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2801                 .dac_nids = alc880_asus_dac_nids,
2802                 .dig_out_nid = ALC880_DIGOUT_NID,
2803                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2804                 .channel_mode = alc880_asus_modes,
2805                 .need_dac_fix = 1,
2806                 .input_mux = &alc880_capture_source,
2807         },
2808         [ALC880_UNIWILL_DIG] = {
2809                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2810                 .init_verbs = { alc880_volume_init_verbs,
2811                                 alc880_pin_asus_init_verbs },
2812                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2813                 .dac_nids = alc880_asus_dac_nids,
2814                 .dig_out_nid = ALC880_DIGOUT_NID,
2815                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2816                 .channel_mode = alc880_asus_modes,
2817                 .need_dac_fix = 1,
2818                 .input_mux = &alc880_capture_source,
2819         },
2820         [ALC880_UNIWILL] = {
2821                 .mixers = { alc880_uniwill_mixer },
2822                 .init_verbs = { alc880_volume_init_verbs,
2823                                 alc880_uniwill_init_verbs },
2824                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2825                 .dac_nids = alc880_asus_dac_nids,
2826                 .dig_out_nid = ALC880_DIGOUT_NID,
2827                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2828                 .channel_mode = alc880_threestack_modes,
2829                 .need_dac_fix = 1,
2830                 .input_mux = &alc880_capture_source,
2831                 .unsol_event = alc880_uniwill_unsol_event,
2832                 .init_hook = alc880_uniwill_automute,
2833         },
2834         [ALC880_UNIWILL_P53] = {
2835                 .mixers = { alc880_uniwill_p53_mixer },
2836                 .init_verbs = { alc880_volume_init_verbs,
2837                                 alc880_uniwill_p53_init_verbs },
2838                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2839                 .dac_nids = alc880_asus_dac_nids,
2840                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2841                 .channel_mode = alc880_threestack_modes,
2842                 .input_mux = &alc880_capture_source,
2843                 .unsol_event = alc880_uniwill_p53_unsol_event,
2844                 .init_hook = alc880_uniwill_p53_hp_automute,
2845         },
2846         [ALC880_FUJITSU] = {
2847                 .mixers = { alc880_fujitsu_mixer,
2848                             alc880_pcbeep_mixer, },
2849                 .init_verbs = { alc880_volume_init_verbs,
2850                                 alc880_uniwill_p53_init_verbs,
2851                                 alc880_beep_init_verbs },
2852                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2853                 .dac_nids = alc880_dac_nids,
2854                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2855                 .channel_mode = alc880_2_jack_modes,
2856                 .input_mux = &alc880_capture_source,
2857                 .unsol_event = alc880_uniwill_p53_unsol_event,
2858                 .init_hook = alc880_uniwill_p53_hp_automute,
2859         },
2860         [ALC880_CLEVO] = {
2861                 .mixers = { alc880_three_stack_mixer },
2862                 .init_verbs = { alc880_volume_init_verbs,
2863                                 alc880_pin_clevo_init_verbs },
2864                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2865                 .dac_nids = alc880_dac_nids,
2866                 .hp_nid = 0x03,
2867                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2868                 .channel_mode = alc880_threestack_modes,
2869                 .need_dac_fix = 1,
2870                 .input_mux = &alc880_capture_source,
2871         },
2872         [ALC880_LG] = {
2873                 .mixers = { alc880_lg_mixer },
2874                 .init_verbs = { alc880_volume_init_verbs,
2875                                 alc880_lg_init_verbs },
2876                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2877                 .dac_nids = alc880_lg_dac_nids,
2878                 .dig_out_nid = ALC880_DIGOUT_NID,
2879                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2880                 .channel_mode = alc880_lg_ch_modes,
2881                 .need_dac_fix = 1,
2882                 .input_mux = &alc880_lg_capture_source,
2883                 .unsol_event = alc880_lg_unsol_event,
2884                 .init_hook = alc880_lg_automute,
2885         },
2886         [ALC880_LG_LW] = {
2887                 .mixers = { alc880_lg_lw_mixer },
2888                 .init_verbs = { alc880_volume_init_verbs,
2889                                 alc880_lg_lw_init_verbs },
2890                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2891                 .dac_nids = alc880_dac_nids,
2892                 .dig_out_nid = ALC880_DIGOUT_NID,
2893                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2894                 .channel_mode = alc880_lg_lw_modes,
2895                 .input_mux = &alc880_lg_lw_capture_source,
2896                 .unsol_event = alc880_lg_lw_unsol_event,
2897                 .init_hook = alc880_lg_lw_automute,
2898         },
2899 #ifdef CONFIG_SND_DEBUG
2900         [ALC880_TEST] = {
2901                 .mixers = { alc880_test_mixer },
2902                 .init_verbs = { alc880_test_init_verbs },
2903                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2904                 .dac_nids = alc880_test_dac_nids,
2905                 .dig_out_nid = ALC880_DIGOUT_NID,
2906                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2907                 .channel_mode = alc880_test_modes,
2908                 .input_mux = &alc880_test_capture_source,
2909         },
2910 #endif
2911 };
2912
2913 /*
2914  * Automatic parse of I/O pins from the BIOS configuration
2915  */
2916
2917 #define NUM_CONTROL_ALLOC       32
2918 #define NUM_VERB_ALLOC          32
2919
2920 enum {
2921         ALC_CTL_WIDGET_VOL,
2922         ALC_CTL_WIDGET_MUTE,
2923         ALC_CTL_BIND_MUTE,
2924 };
2925 static struct snd_kcontrol_new alc880_control_templates[] = {
2926         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2927         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2928         HDA_BIND_MUTE(NULL, 0, 0, 0),
2929 };
2930
2931 /* add dynamic controls */
2932 static int add_control(struct alc_spec *spec, int type, const char *name,
2933                        unsigned long val)
2934 {
2935         struct snd_kcontrol_new *knew;
2936
2937         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2938                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2939
2940                 /* array + terminator */
2941                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2942                 if (!knew)
2943                         return -ENOMEM;
2944                 if (spec->kctl_alloc) {
2945                         memcpy(knew, spec->kctl_alloc,
2946                                sizeof(*knew) * spec->num_kctl_alloc);
2947                         kfree(spec->kctl_alloc);
2948                 }
2949                 spec->kctl_alloc = knew;
2950                 spec->num_kctl_alloc = num;
2951         }
2952
2953         knew = &spec->kctl_alloc[spec->num_kctl_used];
2954         *knew = alc880_control_templates[type];
2955         knew->name = kstrdup(name, GFP_KERNEL);
2956         if (!knew->name)
2957                 return -ENOMEM;
2958         knew->private_value = val;
2959         spec->num_kctl_used++;
2960         return 0;
2961 }
2962
2963 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
2964 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
2965 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
2966 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
2967 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
2968 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
2969 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
2970 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
2971 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
2972 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
2973 #define ALC880_PIN_CD_NID               0x1c
2974
2975 /* fill in the dac_nids table from the parsed pin configuration */
2976 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
2977                                      const struct auto_pin_cfg *cfg)
2978 {
2979         hda_nid_t nid;
2980         int assigned[4];
2981         int i, j;
2982
2983         memset(assigned, 0, sizeof(assigned));
2984         spec->multiout.dac_nids = spec->private_dac_nids;
2985
2986         /* check the pins hardwired to audio widget */
2987         for (i = 0; i < cfg->line_outs; i++) {
2988                 nid = cfg->line_out_pins[i];
2989                 if (alc880_is_fixed_pin(nid)) {
2990                         int idx = alc880_fixed_pin_idx(nid);
2991                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
2992                         assigned[idx] = 1;
2993                 }
2994         }
2995         /* left pins can be connect to any audio widget */
2996         for (i = 0; i < cfg->line_outs; i++) {
2997                 nid = cfg->line_out_pins[i];
2998                 if (alc880_is_fixed_pin(nid))
2999                         continue;
3000                 /* search for an empty channel */
3001                 for (j = 0; j < cfg->line_outs; j++) {
3002                         if (!assigned[j]) {
3003                                 spec->multiout.dac_nids[i] =
3004                                         alc880_idx_to_dac(j);
3005                                 assigned[j] = 1;
3006                                 break;
3007                         }
3008                 }
3009         }
3010         spec->multiout.num_dacs = cfg->line_outs;
3011         return 0;
3012 }
3013
3014 /* add playback controls from the parsed DAC table */
3015 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3016                                              const struct auto_pin_cfg *cfg)
3017 {
3018         char name[32];
3019         static const char *chname[4] = {
3020                 "Front", "Surround", NULL /*CLFE*/, "Side"
3021         };
3022         hda_nid_t nid;
3023         int i, err;
3024
3025         for (i = 0; i < cfg->line_outs; i++) {
3026                 if (!spec->multiout.dac_nids[i])
3027                         continue;
3028                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3029                 if (i == 2) {
3030                         /* Center/LFE */
3031                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3032                                           "Center Playback Volume",
3033                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3034                                                               HDA_OUTPUT));
3035                         if (err < 0)
3036                                 return err;
3037                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3038                                           "LFE Playback Volume",
3039                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3040                                                               HDA_OUTPUT));
3041                         if (err < 0)
3042                                 return err;
3043                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3044                                           "Center Playback Switch",
3045                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3046                                                               HDA_INPUT));
3047                         if (err < 0)
3048                                 return err;
3049                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3050                                           "LFE Playback Switch",
3051                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3052                                                               HDA_INPUT));
3053                         if (err < 0)
3054                                 return err;
3055                 } else {
3056                         sprintf(name, "%s Playback Volume", chname[i]);
3057                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3058                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3059                                                               HDA_OUTPUT));
3060                         if (err < 0)
3061                                 return err;
3062                         sprintf(name, "%s Playback Switch", chname[i]);
3063                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3064                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3065                                                               HDA_INPUT));
3066                         if (err < 0)
3067                                 return err;
3068                 }
3069         }
3070         return 0;
3071 }
3072
3073 /* add playback controls for speaker and HP outputs */
3074 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3075                                         const char *pfx)
3076 {
3077         hda_nid_t nid;
3078         int err;
3079         char name[32];
3080
3081         if (!pin)
3082                 return 0;
3083
3084         if (alc880_is_fixed_pin(pin)) {
3085                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3086                 /* specify the DAC as the extra output */
3087                 if (!spec->multiout.hp_nid)
3088                         spec->multiout.hp_nid = nid;
3089                 else
3090                         spec->multiout.extra_out_nid[0] = nid;
3091                 /* control HP volume/switch on the output mixer amp */
3092                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3093                 sprintf(name, "%s Playback Volume", pfx);
3094                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3095                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3096                 if (err < 0)
3097                         return err;
3098                 sprintf(name, "%s Playback Switch", pfx);
3099                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3100                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3101                 if (err < 0)
3102                         return err;
3103         } else if (alc880_is_multi_pin(pin)) {
3104                 /* set manual connection */
3105                 /* we have only a switch on HP-out PIN */
3106                 sprintf(name, "%s Playback Switch", pfx);
3107                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3108                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3109                 if (err < 0)
3110                         return err;
3111         }
3112         return 0;
3113 }
3114
3115 /* create input playback/capture controls for the given pin */
3116 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3117                             const char *ctlname,
3118                             int idx, hda_nid_t mix_nid)
3119 {
3120         char name[32];
3121         int err;
3122
3123         sprintf(name, "%s Playback Volume", ctlname);
3124         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3125                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3126         if (err < 0)
3127                 return err;
3128         sprintf(name, "%s Playback Switch", ctlname);
3129         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3130                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3131         if (err < 0)
3132                 return err;
3133         return 0;
3134 }
3135
3136 /* create playback/capture controls for input pins */
3137 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3138                                                 const struct auto_pin_cfg *cfg)
3139 {
3140         struct hda_input_mux *imux = &spec->private_imux;
3141         int i, err, idx;
3142
3143         for (i = 0; i < AUTO_PIN_LAST; i++) {
3144                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3145                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3146                         err = new_analog_input(spec, cfg->input_pins[i],
3147                                                auto_pin_cfg_labels[i],
3148                                                idx, 0x0b);
3149                         if (err < 0)
3150                                 return err;
3151                         imux->items[imux->num_items].label =
3152                                 auto_pin_cfg_labels[i];
3153                         imux->items[imux->num_items].index =
3154                                 alc880_input_pin_idx(cfg->input_pins[i]);
3155                         imux->num_items++;
3156                 }
3157         }
3158         return 0;
3159 }
3160
3161 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3162                                               hda_nid_t nid, int pin_type,
3163                                               int dac_idx)
3164 {
3165         /* set as output */
3166         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3167                             pin_type);
3168         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3169                             AMP_OUT_UNMUTE);
3170         /* need the manual connection? */
3171         if (alc880_is_multi_pin(nid)) {
3172                 struct alc_spec *spec = codec->spec;
3173                 int idx = alc880_multi_pin_idx(nid);
3174                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3175                                     AC_VERB_SET_CONNECT_SEL,
3176                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3177         }
3178 }
3179
3180 static int get_pin_type(int line_out_type)
3181 {
3182         if (line_out_type == AUTO_PIN_HP_OUT)
3183                 return PIN_HP;
3184         else
3185                 return PIN_OUT;
3186 }
3187
3188 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3189 {
3190         struct alc_spec *spec = codec->spec;
3191         int i;
3192         
3193         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3194         for (i = 0; i < spec->autocfg.line_outs; i++) {
3195                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3196                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3197                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3198         }
3199 }
3200
3201 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3202 {
3203         struct alc_spec *spec = codec->spec;
3204         hda_nid_t pin;
3205
3206         pin = spec->autocfg.speaker_pins[0];
3207         if (pin) /* connect to front */
3208                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3209         pin = spec->autocfg.hp_pins[0];
3210         if (pin) /* connect to front */
3211                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3212 }
3213
3214 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3215 {
3216         struct alc_spec *spec = codec->spec;
3217         int i;
3218
3219         for (i = 0; i < AUTO_PIN_LAST; i++) {
3220                 hda_nid_t nid = spec->autocfg.input_pins[i];
3221                 if (alc880_is_input_pin(nid)) {
3222                         snd_hda_codec_write(codec, nid, 0,
3223                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3224                                             i <= AUTO_PIN_FRONT_MIC ?
3225                                             PIN_VREF80 : PIN_IN);
3226                         if (nid != ALC880_PIN_CD_NID)
3227                                 snd_hda_codec_write(codec, nid, 0,
3228                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3229                                                     AMP_OUT_MUTE);
3230                 }
3231         }
3232 }
3233
3234 /* parse the BIOS configuration and set up the alc_spec */
3235 /* return 1 if successful, 0 if the proper config is not found,
3236  * or a negative error code
3237  */
3238 static int alc880_parse_auto_config(struct hda_codec *codec)
3239 {
3240         struct alc_spec *spec = codec->spec;
3241         int err;
3242         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3243
3244         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3245                                            alc880_ignore);
3246         if (err < 0)
3247                 return err;
3248         if (!spec->autocfg.line_outs)
3249                 return 0; /* can't find valid BIOS pin config */
3250
3251         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3252         if (err < 0)
3253                 return err;
3254         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3255         if (err < 0)
3256                 return err;
3257         err = alc880_auto_create_extra_out(spec,
3258                                            spec->autocfg.speaker_pins[0],
3259                                            "Speaker");
3260         if (err < 0)
3261                 return err;
3262         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3263                                            "Headphone");
3264         if (err < 0)
3265                 return err;
3266         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3267         if (err < 0)
3268                 return err;
3269
3270         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3271
3272         if (spec->autocfg.dig_out_pin)
3273                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3274         if (spec->autocfg.dig_in_pin)
3275                 spec->dig_in_nid = ALC880_DIGIN_NID;
3276
3277         if (spec->kctl_alloc)
3278                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3279
3280         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3281
3282         spec->num_mux_defs = 1;
3283         spec->input_mux = &spec->private_imux;
3284
3285         return 1;
3286 }
3287
3288 /* additional initialization for auto-configuration model */
3289 static void alc880_auto_init(struct hda_codec *codec)
3290 {
3291         alc880_auto_init_multi_out(codec);
3292         alc880_auto_init_extra_out(codec);
3293         alc880_auto_init_analog_input(codec);
3294 }
3295
3296 /*
3297  * OK, here we have finally the patch for ALC880
3298  */
3299
3300 static int patch_alc880(struct hda_codec *codec)
3301 {
3302         struct alc_spec *spec;
3303         int board_config;
3304         int err;
3305
3306         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3307         if (spec == NULL)
3308                 return -ENOMEM;
3309
3310         codec->spec = spec;
3311
3312         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3313                                                   alc880_models,
3314                                                   alc880_cfg_tbl);
3315         if (board_config < 0) {
3316                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3317                        "trying auto-probe from BIOS...\n");
3318                 board_config = ALC880_AUTO;
3319         }
3320
3321         if (board_config == ALC880_AUTO) {
3322                 /* automatic parse from the BIOS config */
3323                 err = alc880_parse_auto_config(codec);
3324                 if (err < 0) {
3325                         alc_free(codec);
3326                         return err;
3327                 } else if (!err) {
3328                         printk(KERN_INFO
3329                                "hda_codec: Cannot set up configuration "
3330                                "from BIOS.  Using 3-stack mode...\n");
3331                         board_config = ALC880_3ST;
3332                 }
3333         }
3334
3335         if (board_config != ALC880_AUTO)
3336                 setup_preset(spec, &alc880_presets[board_config]);
3337
3338         spec->stream_name_analog = "ALC880 Analog";
3339         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3340         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3341
3342         spec->stream_name_digital = "ALC880 Digital";
3343         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3344         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3345
3346         if (!spec->adc_nids && spec->input_mux) {
3347                 /* check whether NID 0x07 is valid */
3348                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3349                 /* get type */
3350                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3351                 if (wcap != AC_WID_AUD_IN) {
3352                         spec->adc_nids = alc880_adc_nids_alt;
3353                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3354                         spec->mixers[spec->num_mixers] =
3355                                 alc880_capture_alt_mixer;
3356                         spec->num_mixers++;
3357                 } else {
3358                         spec->adc_nids = alc880_adc_nids;
3359                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3360                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3361                         spec->num_mixers++;
3362                 }
3363         }
3364
3365         codec->patch_ops = alc_patch_ops;
3366         if (board_config == ALC880_AUTO)
3367                 spec->init_hook = alc880_auto_init;
3368
3369         return 0;
3370 }
3371
3372
3373 /*
3374  * ALC260 support
3375  */
3376
3377 static hda_nid_t alc260_dac_nids[1] = {
3378         /* front */
3379         0x02,
3380 };
3381
3382 static hda_nid_t alc260_adc_nids[1] = {
3383         /* ADC0 */
3384         0x04,
3385 };
3386
3387 static hda_nid_t alc260_adc_nids_alt[1] = {
3388         /* ADC1 */
3389         0x05,
3390 };
3391
3392 static hda_nid_t alc260_hp_adc_nids[2] = {
3393         /* ADC1, 0 */
3394         0x05, 0x04
3395 };
3396
3397 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3398  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3399  */
3400 static hda_nid_t alc260_dual_adc_nids[2] = {
3401         /* ADC0, ADC1 */
3402         0x04, 0x05
3403 };
3404
3405 #define ALC260_DIGOUT_NID       0x03
3406 #define ALC260_DIGIN_NID        0x06
3407
3408 static struct hda_input_mux alc260_capture_source = {
3409         .num_items = 4,
3410         .items = {
3411                 { "Mic", 0x0 },
3412                 { "Front Mic", 0x1 },
3413                 { "Line", 0x2 },
3414                 { "CD", 0x4 },
3415         },
3416 };
3417
3418 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3419  * headphone jack and the internal CD lines since these are the only pins at
3420  * which audio can appear.  For flexibility, also allow the option of
3421  * recording the mixer output on the second ADC (ADC0 doesn't have a
3422  * connection to the mixer output).
3423  */
3424 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3425         {
3426                 .num_items = 3,
3427                 .items = {
3428                         { "Mic/Line", 0x0 },
3429                         { "CD", 0x4 },
3430                         { "Headphone", 0x2 },
3431                 },
3432         },
3433         {
3434                 .num_items = 4,
3435                 .items = {
3436                         { "Mic/Line", 0x0 },
3437                         { "CD", 0x4 },
3438                         { "Headphone", 0x2 },
3439                         { "Mixer", 0x5 },
3440                 },
3441         },
3442
3443 };
3444
3445 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3446  * the Fujitsu S702x, but jacks are marked differently.
3447  */
3448 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3449         {
3450                 .num_items = 4,
3451                 .items = {
3452                         { "Mic", 0x0 },
3453                         { "Line", 0x2 },
3454                         { "CD", 0x4 },
3455                         { "Headphone", 0x5 },
3456                 },
3457         },
3458         {
3459                 .num_items = 5,
3460                 .items = {
3461                         { "Mic", 0x0 },
3462                         { "Line", 0x2 },
3463                         { "CD", 0x4 },
3464                         { "Headphone", 0x6 },
3465                         { "Mixer", 0x5 },
3466                 },
3467         },
3468 };
3469 /*
3470  * This is just place-holder, so there's something for alc_build_pcms to look
3471  * at when it calculates the maximum number of channels. ALC260 has no mixer
3472  * element which allows changing the channel mode, so the verb list is
3473  * never used.
3474  */
3475 static struct hda_channel_mode alc260_modes[1] = {
3476         { 2, NULL },
3477 };
3478
3479
3480 /* Mixer combinations
3481  *
3482  * basic: base_output + input + pc_beep + capture
3483  * HP: base_output + input + capture_alt
3484  * HP_3013: hp_3013 + input + capture
3485  * fujitsu: fujitsu + capture
3486  * acer: acer + capture
3487  */
3488
3489 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3490         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3491         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3492         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3493         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3494         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3495         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3496         { } /* end */
3497 };
3498
3499 static struct snd_kcontrol_new alc260_input_mixer[] = {
3500         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3501         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3502         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3503         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3504         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3505         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3506         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3507         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3508         { } /* end */
3509 };
3510
3511 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3512         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3513         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3514         { } /* end */
3515 };
3516
3517 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3518         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3519         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3520         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3521         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3522         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3523         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3524         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3525         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3526         { } /* end */
3527 };
3528
3529 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3530  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3531  */
3532 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3533         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3534         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3535         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3536         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3537         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3538         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3539         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3540         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3541         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3542         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3543         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3544         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3545         { } /* end */
3546 };
3547
3548 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3549  * versions of the ALC260 don't act on requests to enable mic bias from NID
3550  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3551  * datasheet doesn't mention this restriction.  At this stage it's not clear
3552  * whether this behaviour is intentional or is a hardware bug in chip
3553  * revisions available in early 2006.  Therefore for now allow the
3554  * "Headphone Jack Mode" control to span all choices, but if it turns out
3555  * that the lack of mic bias for this NID is intentional we could change the
3556  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3557  *
3558  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3559  * don't appear to make the mic bias available from the "line" jack, even
3560  * though the NID used for this jack (0x14) can supply it.  The theory is
3561  * that perhaps Acer have included blocking capacitors between the ALC260
3562  * and the output jack.  If this turns out to be the case for all such
3563  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3564  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3565  *
3566  * The C20x Tablet series have a mono internal speaker which is controlled
3567  * via the chip's Mono sum widget and pin complex, so include the necessary
3568  * controls for such models.  On models without a "mono speaker" the control
3569  * won't do anything.
3570  */
3571 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3572         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3573         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3574         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3575         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3576                               HDA_OUTPUT),
3577         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3578                            HDA_INPUT),
3579         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3580         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3581         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3582         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3583         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3584         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3585         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3586         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3587         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3588         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3589         { } /* end */
3590 };
3591
3592 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3593  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3594  */
3595 static struct snd_kcontrol_new alc260_will_mixer[] = {
3596         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3597         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3598         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3599         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3600         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3601         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3602         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3603         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3604         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3605         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3606         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3607         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3608         { } /* end */
3609 };
3610
3611 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3612  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3613  */
3614 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3615         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3616         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3617         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3618         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3619         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3620         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3621         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3622         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3623         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3624         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3625         { } /* end */
3626 };
3627
3628 /* capture mixer elements */
3629 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3630         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3631         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3632         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3633         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3634         {
3635                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3636                 /* The multiple "Capture Source" controls confuse alsamixer
3637                  * So call somewhat different..
3638                  * FIXME: the controls appear in the "playback" view!
3639                  */
3640                 /* .name = "Capture Source", */
3641                 .name = "Input Source",
3642                 .count = 2,
3643                 .info = alc_mux_enum_info,
3644                 .get = alc_mux_enum_get,
3645                 .put = alc_mux_enum_put,
3646         },
3647         { } /* end */
3648 };
3649
3650 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3651         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3652         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3653         {
3654                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3655                 /* The multiple "Capture Source" controls confuse alsamixer
3656                  * So call somewhat different..
3657                  * FIXME: the controls appear in the "playback" view!
3658                  */
3659                 /* .name = "Capture Source", */
3660                 .name = "Input Source",
3661                 .count = 1,
3662                 .info = alc_mux_enum_info,
3663                 .get = alc_mux_enum_get,
3664                 .put = alc_mux_enum_put,
3665         },
3666         { } /* end */
3667 };
3668
3669 /*
3670  * initialization verbs
3671  */
3672 static struct hda_verb alc260_init_verbs[] = {
3673         /* Line In pin widget for input */
3674         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3675         /* CD pin widget for input */
3676         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3677         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3678         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3679         /* Mic2 (front panel) pin widget for input and vref at 80% */
3680         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3681         /* LINE-2 is used for line-out in rear */
3682         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3683         /* select line-out */
3684         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3685         /* LINE-OUT pin */
3686         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3687         /* enable HP */
3688         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3689         /* enable Mono */
3690         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3691         /* mute capture amp left and right */
3692         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3693         /* set connection select to line in (default select for this ADC) */
3694         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3695         /* mute capture amp left and right */
3696         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3697         /* set connection select to line in (default select for this ADC) */
3698         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3699         /* set vol=0 Line-Out mixer amp left and right */
3700         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3701         /* unmute pin widget amp left and right (no gain on this amp) */
3702         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3703         /* set vol=0 HP mixer amp left and right */
3704         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3705         /* unmute pin widget amp left and right (no gain on this amp) */
3706         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3707         /* set vol=0 Mono mixer amp left and right */
3708         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3709         /* unmute pin widget amp left and right (no gain on this amp) */
3710         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3711         /* unmute LINE-2 out pin */
3712         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3713         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3714          * Line In 2 = 0x03
3715          */
3716         /* mute CD */
3717         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3718         /* mute Line In */
3719         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3720         /* mute Mic */
3721         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3722         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3723         /* mute Front out path */
3724         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3725         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3726         /* mute Headphone out path */
3727         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3728         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3729         /* mute Mono out path */
3730         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3731         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3732         { }
3733 };
3734
3735 #if 0 /* should be identical with alc260_init_verbs? */
3736 static struct hda_verb alc260_hp_init_verbs[] = {
3737         /* Headphone and output */
3738         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3739         /* mono output */
3740         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3741         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3742         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3743         /* Mic2 (front panel) pin widget for input and vref at 80% */
3744         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3745         /* Line In pin widget for input */
3746         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3747         /* Line-2 pin widget for output */
3748         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3749         /* CD pin widget for input */
3750         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3751         /* unmute amp left and right */
3752         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3753         /* set connection select to line in (default select for this ADC) */
3754         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3755         /* unmute Line-Out mixer amp left and right (volume = 0) */
3756         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3757         /* mute pin widget amp left and right (no gain on this amp) */
3758         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3759         /* unmute HP mixer amp left and right (volume = 0) */
3760         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3761         /* mute pin widget amp left and right (no gain on this amp) */
3762         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3763         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3764          * Line In 2 = 0x03
3765          */
3766         /* unmute CD */
3767         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3768         /* unmute Line In */
3769         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3770         /* unmute Mic */
3771         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3772         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3773         /* Unmute Front out path */
3774         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3775         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3776         /* Unmute Headphone out path */
3777         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3778         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3779         /* Unmute Mono out path */
3780         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3781         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3782         { }
3783 };
3784 #endif
3785
3786 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3787         /* Line out and output */
3788         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3789         /* mono output */
3790         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3791         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3792         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3793         /* Mic2 (front panel) pin widget for input and vref at 80% */
3794         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3795         /* Line In pin widget for input */
3796         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3797         /* Headphone pin widget for output */
3798         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3799         /* CD pin widget for input */
3800         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3801         /* unmute amp left and right */
3802         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3803         /* set connection select to line in (default select for this ADC) */
3804         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3805         /* unmute Line-Out mixer amp left and right (volume = 0) */
3806         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3807         /* mute pin widget amp left and right (no gain on this amp) */
3808         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3809         /* unmute HP mixer amp left and right (volume = 0) */
3810         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3811         /* mute pin widget amp left and right (no gain on this amp) */
3812         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3813         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3814          * Line In 2 = 0x03
3815          */
3816         /* unmute CD */
3817         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3818         /* unmute Line In */
3819         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3820         /* unmute Mic */
3821         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3822         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3823         /* Unmute Front out path */
3824         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3825         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3826         /* Unmute Headphone out path */
3827         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3828         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3829         /* Unmute Mono out path */
3830         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3831         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3832         { }
3833 };
3834
3835 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3836  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3837  * audio = 0x16, internal speaker = 0x10.
3838  */
3839 static struct hda_verb alc260_fujitsu_init_verbs[] = {
3840         /* Disable all GPIOs */
3841         {0x01, AC_VERB_SET_GPIO_MASK, 0},
3842         /* Internal speaker is connected to headphone pin */
3843         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3844         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3845         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3846         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3847         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3848         /* Ensure all other unused pins are disabled and muted. */
3849         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3850         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3851         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3852         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3853         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3854         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3855         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3856         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3857
3858         /* Disable digital (SPDIF) pins */
3859         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3860         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3861
3862         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
3863          * when acting as an output.
3864          */
3865         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3866
3867         /* Start with output sum widgets muted and their output gains at min */
3868         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3869         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3870         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3871         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3872         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3873         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3874         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3875         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3876         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3877
3878         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3879         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3880         /* Unmute Line1 pin widget output buffer since it starts as an output.
3881          * If the pin mode is changed by the user the pin mode control will
3882          * take care of enabling the pin's input/output buffers as needed.
3883          * Therefore there's no need to enable the input buffer at this
3884          * stage.
3885          */
3886         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3887         /* Unmute input buffer of pin widget used for Line-in (no equiv 
3888          * mixer ctrl)
3889          */
3890         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3891
3892         /* Mute capture amp left and right */
3893         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3894         /* Set ADC connection select to match default mixer setting - line 
3895          * in (on mic1 pin)
3896          */
3897         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3898
3899         /* Do the same for the second ADC: mute capture input amp and
3900          * set ADC connection to line in (on mic1 pin)
3901          */
3902         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3903         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3904
3905         /* Mute all inputs to mixer widget (even unconnected ones) */
3906         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3907         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3908         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3909         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3910         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3911         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3912         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3913         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3914
3915         { }
3916 };
3917
3918 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3919  * similar laptops (adapted from Fujitsu init verbs).
3920  */
3921 static struct hda_verb alc260_acer_init_verbs[] = {
3922         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3923          * the headphone jack.  Turn this on and rely on the standard mute
3924          * methods whenever the user wants to turn these outputs off.
3925          */
3926         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3927         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3928         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3929         /* Internal speaker/Headphone jack is connected to Line-out pin */
3930         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3931         /* Internal microphone/Mic jack is connected to Mic1 pin */
3932         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3933         /* Line In jack is connected to Line1 pin */
3934         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3935         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3936         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3937         /* Ensure all other unused pins are disabled and muted. */
3938         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3939         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3940         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3941         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3942         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3943         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3944         /* Disable digital (SPDIF) pins */
3945         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3946         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3947
3948         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
3949          * bus when acting as outputs.
3950          */
3951         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3952         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3953
3954         /* Start with output sum widgets muted and their output gains at min */
3955         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3956         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3957         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3958         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3959         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3960         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3961         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3962         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3963         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3964
3965         /* Unmute Line-out pin widget amp left and right
3966          * (no equiv mixer ctrl)
3967          */
3968         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3969         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3970         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3971         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3972          * inputs. If the pin mode is changed by the user the pin mode control
3973          * will take care of enabling the pin's input/output buffers as needed.
3974          * Therefore there's no need to enable the input buffer at this
3975          * stage.
3976          */
3977         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3978         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3979
3980         /* Mute capture amp left and right */
3981         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3982         /* Set ADC connection select to match default mixer setting - mic
3983          * (on mic1 pin)
3984          */
3985         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3986
3987         /* Do similar with the second ADC: mute capture input amp and
3988          * set ADC connection to mic to match ALSA's default state.
3989          */
3990         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3991         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3992
3993         /* Mute all inputs to mixer widget (even unconnected ones) */
3994         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3995         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3996         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3997         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3998         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3999         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4000         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4001         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4002
4003         { }
4004 };
4005
4006 static struct hda_verb alc260_will_verbs[] = {
4007         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4008         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4009         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4010         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4011         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4012         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4013         {}
4014 };
4015
4016 static struct hda_verb alc260_replacer_672v_verbs[] = {
4017         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4018         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4019         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4020
4021         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4022         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4023         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4024
4025         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4026         {}
4027 };
4028
4029 /* toggle speaker-output according to the hp-jack state */
4030 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4031 {
4032         unsigned int present;
4033
4034         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4035         present = snd_hda_codec_read(codec, 0x0f, 0,
4036                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4037         if (present) {
4038                 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
4039                 snd_hda_codec_write(codec, 0x0f, 0,
4040                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4041         } else {
4042                 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4043                 snd_hda_codec_write(codec, 0x0f, 0,
4044                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4045         }
4046 }
4047
4048 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4049                                        unsigned int res)
4050 {
4051         if ((res >> 26) == ALC880_HP_EVENT)
4052                 alc260_replacer_672v_automute(codec);
4053 }
4054
4055 /* Test configuration for debugging, modelled after the ALC880 test
4056  * configuration.
4057  */
4058 #ifdef CONFIG_SND_DEBUG
4059 static hda_nid_t alc260_test_dac_nids[1] = {
4060         0x02,
4061 };
4062 static hda_nid_t alc260_test_adc_nids[2] = {
4063         0x04, 0x05,
4064 };
4065 /* For testing the ALC260, each input MUX needs its own definition since
4066  * the signal assignments are different.  This assumes that the first ADC 
4067  * is NID 0x04.
4068  */
4069 static struct hda_input_mux alc260_test_capture_sources[2] = {
4070         {
4071                 .num_items = 7,
4072                 .items = {
4073                         { "MIC1 pin", 0x0 },
4074                         { "MIC2 pin", 0x1 },
4075                         { "LINE1 pin", 0x2 },
4076                         { "LINE2 pin", 0x3 },
4077                         { "CD pin", 0x4 },
4078                         { "LINE-OUT pin", 0x5 },
4079                         { "HP-OUT pin", 0x6 },
4080                 },
4081         },
4082         {
4083                 .num_items = 8,
4084                 .items = {
4085                         { "MIC1 pin", 0x0 },
4086                         { "MIC2 pin", 0x1 },
4087                         { "LINE1 pin", 0x2 },
4088                         { "LINE2 pin", 0x3 },
4089                         { "CD pin", 0x4 },
4090                         { "Mixer", 0x5 },
4091                         { "LINE-OUT pin", 0x6 },
4092                         { "HP-OUT pin", 0x7 },
4093                 },
4094         },
4095 };
4096 static struct snd_kcontrol_new alc260_test_mixer[] = {
4097         /* Output driver widgets */
4098         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4099         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4100         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4101         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4102         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4103         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4104
4105         /* Modes for retasking pin widgets
4106          * Note: the ALC260 doesn't seem to act on requests to enable mic
4107          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4108          * mention this restriction.  At this stage it's not clear whether
4109          * this behaviour is intentional or is a hardware bug in chip
4110          * revisions available at least up until early 2006.  Therefore for
4111          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4112          * choices, but if it turns out that the lack of mic bias for these
4113          * NIDs is intentional we could change their modes from
4114          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4115          */
4116         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4117         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4118         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4119         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4120         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4121         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4122
4123         /* Loopback mixer controls */
4124         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4125         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4126         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4127         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4128         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4129         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4130         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4131         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4132         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4133         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4134         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4135         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4136         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4137         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4138         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4139         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4140
4141         /* Controls for GPIO pins, assuming they are configured as outputs */
4142         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4143         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4144         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4145         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4146
4147         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4148          * is ambigious as to which NID is which; testing on laptops which
4149          * make this output available should provide clarification. 
4150          */
4151         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4152         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4153
4154         { } /* end */
4155 };
4156 static struct hda_verb alc260_test_init_verbs[] = {
4157         /* Enable all GPIOs as outputs with an initial value of 0 */
4158         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4159         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4160         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4161
4162         /* Enable retasking pins as output, initially without power amp */
4163         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4164         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4165         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4166         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4167         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4168         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4169
4170         /* Disable digital (SPDIF) pins initially, but users can enable
4171          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4172          * payload also sets the generation to 0, output to be in "consumer"
4173          * PCM format, copyright asserted, no pre-emphasis and no validity
4174          * control.
4175          */
4176         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4177         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4178
4179         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4180          * OUT1 sum bus when acting as an output.
4181          */
4182         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4183         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4184         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4185         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4186
4187         /* Start with output sum widgets muted and their output gains at min */
4188         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4189         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4190         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4191         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4192         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4193         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4194         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4195         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4196         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4197
4198         /* Unmute retasking pin widget output buffers since the default
4199          * state appears to be output.  As the pin mode is changed by the
4200          * user the pin mode control will take care of enabling the pin's
4201          * input/output buffers as needed.
4202          */
4203         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4204         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4205         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4206         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4207         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4208         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4209         /* Also unmute the mono-out pin widget */
4210         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4211
4212         /* Mute capture amp left and right */
4213         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4214         /* Set ADC connection select to match default mixer setting (mic1
4215          * pin)
4216          */
4217         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4218
4219         /* Do the same for the second ADC: mute capture input amp and
4220          * set ADC connection to mic1 pin
4221          */
4222         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4223         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4224
4225         /* Mute all inputs to mixer widget (even unconnected ones) */
4226         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4227         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4228         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4229         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4230         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4231         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4232         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4233         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4234
4235         { }
4236 };
4237 #endif
4238
4239 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4240         .substreams = 1,
4241         .channels_min = 2,
4242         .channels_max = 2,
4243 };
4244
4245 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4246         .substreams = 1,
4247         .channels_min = 2,
4248         .channels_max = 2,
4249 };
4250
4251 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4252 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4253
4254 /*
4255  * for BIOS auto-configuration
4256  */
4257
4258 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4259                                         const char *pfx)
4260 {
4261         hda_nid_t nid_vol;
4262         unsigned long vol_val, sw_val;
4263         char name[32];
4264         int err;
4265
4266         if (nid >= 0x0f && nid < 0x11) {
4267                 nid_vol = nid - 0x7;
4268                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4269                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4270         } else if (nid == 0x11) {
4271                 nid_vol = nid - 0x7;
4272                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4273                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4274         } else if (nid >= 0x12 && nid <= 0x15) {
4275                 nid_vol = 0x08;
4276                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4277                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4278         } else
4279                 return 0; /* N/A */
4280         
4281         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4282         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4283         if (err < 0)
4284                 return err;
4285         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4286         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4287         if (err < 0)
4288                 return err;
4289         return 1;
4290 }
4291
4292 /* add playback controls from the parsed DAC table */
4293 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4294                                              const struct auto_pin_cfg *cfg)
4295 {
4296         hda_nid_t nid;
4297         int err;
4298
4299         spec->multiout.num_dacs = 1;
4300         spec->multiout.dac_nids = spec->private_dac_nids;
4301         spec->multiout.dac_nids[0] = 0x02;
4302
4303         nid = cfg->line_out_pins[0];
4304         if (nid) {
4305                 err = alc260_add_playback_controls(spec, nid, "Front");
4306                 if (err < 0)
4307                         return err;
4308         }
4309
4310         nid = cfg->speaker_pins[0];
4311         if (nid) {
4312                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4313                 if (err < 0)
4314                         return err;
4315         }
4316
4317         nid = cfg->hp_pins[0];
4318         if (nid) {
4319                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4320                 if (err < 0)
4321                         return err;
4322         }
4323         return 0;
4324 }
4325
4326 /* create playback/capture controls for input pins */
4327 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4328                                                 const struct auto_pin_cfg *cfg)
4329 {
4330         struct hda_input_mux *imux = &spec->private_imux;
4331         int i, err, idx;
4332
4333         for (i = 0; i < AUTO_PIN_LAST; i++) {
4334                 if (cfg->input_pins[i] >= 0x12) {
4335                         idx = cfg->input_pins[i] - 0x12;
4336                         err = new_analog_input(spec, cfg->input_pins[i],
4337                                                auto_pin_cfg_labels[i], idx,
4338                                                0x07);
4339                         if (err < 0)
4340                                 return err;
4341                         imux->items[imux->num_items].label =
4342                                 auto_pin_cfg_labels[i];
4343                         imux->items[imux->num_items].index = idx;
4344                         imux->num_items++;
4345                 }
4346                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4347                         idx = cfg->input_pins[i] - 0x09;
4348                         err = new_analog_input(spec, cfg->input_pins[i],
4349                                                auto_pin_cfg_labels[i], idx,
4350                                                0x07);
4351                         if (err < 0)
4352                                 return err;
4353                         imux->items[imux->num_items].label =
4354                                 auto_pin_cfg_labels[i];
4355                         imux->items[imux->num_items].index = idx;
4356                         imux->num_items++;
4357                 }
4358         }
4359         return 0;
4360 }
4361
4362 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4363                                               hda_nid_t nid, int pin_type,
4364                                               int sel_idx)
4365 {
4366         /* set as output */
4367         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4368                             pin_type);
4369         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4370                             AMP_OUT_UNMUTE);
4371         /* need the manual connection? */
4372         if (nid >= 0x12) {
4373                 int idx = nid - 0x12;
4374                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4375                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4376         }
4377 }
4378
4379 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4380 {
4381         struct alc_spec *spec = codec->spec;
4382         hda_nid_t nid;
4383
4384         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4385         nid = spec->autocfg.line_out_pins[0];
4386         if (nid) {
4387                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4388                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4389         }
4390         
4391         nid = spec->autocfg.speaker_pins[0];
4392         if (nid)
4393                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4394
4395         nid = spec->autocfg.hp_pins[0];
4396         if (nid)
4397                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4398 }
4399
4400 #define ALC260_PIN_CD_NID               0x16
4401 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4402 {
4403         struct alc_spec *spec = codec->spec;
4404         int i;
4405
4406         for (i = 0; i < AUTO_PIN_LAST; i++) {
4407                 hda_nid_t nid = spec->autocfg.input_pins[i];
4408                 if (nid >= 0x12) {
4409                         snd_hda_codec_write(codec, nid, 0,
4410                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4411                                             i <= AUTO_PIN_FRONT_MIC ?
4412                                             PIN_VREF80 : PIN_IN);
4413                         if (nid != ALC260_PIN_CD_NID)
4414                                 snd_hda_codec_write(codec, nid, 0,
4415                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4416                                                     AMP_OUT_MUTE);
4417                 }
4418         }
4419 }
4420
4421 /*
4422  * generic initialization of ADC, input mixers and output mixers
4423  */
4424 static struct hda_verb alc260_volume_init_verbs[] = {
4425         /*
4426          * Unmute ADC0-1 and set the default input to mic-in
4427          */
4428         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4429         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4430         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4431         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4432         
4433         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4434          * mixer widget
4435          * Note: PASD motherboards uses the Line In 2 as the input for
4436          * front panel mic (mic 2)
4437          */
4438         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4439         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4440         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4441         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4442         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4443         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4444
4445         /*
4446          * Set up output mixers (0x08 - 0x0a)
4447          */
4448         /* set vol=0 to output mixers */
4449         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4450         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4451         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4452         /* set up input amps for analog loopback */
4453         /* Amp Indices: DAC = 0, mixer = 1 */
4454         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4455         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4456         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4457         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4458         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4459         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4460         
4461         { }
4462 };
4463
4464 static int alc260_parse_auto_config(struct hda_codec *codec)
4465 {
4466         struct alc_spec *spec = codec->spec;
4467         unsigned int wcap;
4468         int err;
4469         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4470
4471         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4472                                            alc260_ignore);
4473         if (err < 0)
4474                 return err;
4475         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4476         if (err < 0)
4477                 return err;
4478         if (!spec->kctl_alloc)
4479                 return 0; /* can't find valid BIOS pin config */
4480         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4481         if (err < 0)
4482                 return err;
4483
4484         spec->multiout.max_channels = 2;
4485
4486         if (spec->autocfg.dig_out_pin)
4487                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4488         if (spec->kctl_alloc)
4489                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4490
4491         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4492
4493         spec->num_mux_defs = 1;
4494         spec->input_mux = &spec->private_imux;
4495
4496         /* check whether NID 0x04 is valid */
4497         wcap = get_wcaps(codec, 0x04);
4498         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4499         if (wcap != AC_WID_AUD_IN) {
4500                 spec->adc_nids = alc260_adc_nids_alt;
4501                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4502                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4503         } else {
4504                 spec->adc_nids = alc260_adc_nids;
4505                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4506                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4507         }
4508         spec->num_mixers++;
4509
4510         return 1;
4511 }
4512
4513 /* additional initialization for auto-configuration model */
4514 static void alc260_auto_init(struct hda_codec *codec)
4515 {
4516         alc260_auto_init_multi_out(codec);
4517         alc260_auto_init_analog_input(codec);
4518 }
4519
4520 /*
4521  * ALC260 configurations
4522  */
4523 static const char *alc260_models[ALC260_MODEL_LAST] = {
4524         [ALC260_BASIC]          = "basic",
4525         [ALC260_HP]             = "hp",
4526         [ALC260_HP_3013]        = "hp-3013",
4527         [ALC260_FUJITSU_S702X]  = "fujitsu",
4528         [ALC260_ACER]           = "acer",
4529         [ALC260_WILL]           = "will",
4530         [ALC260_REPLACER_672V]  = "replacer",
4531 #ifdef CONFIG_SND_DEBUG
4532         [ALC260_TEST]           = "test",
4533 #endif
4534         [ALC260_AUTO]           = "auto",
4535 };
4536
4537 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4538         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4539         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4540         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4541         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4542         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4543         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4544         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4545         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4546         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4547         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4548         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4549         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4550         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4551         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4552         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4553         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4554         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4555         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4556         {}
4557 };
4558
4559 static struct alc_config_preset alc260_presets[] = {
4560         [ALC260_BASIC] = {
4561                 .mixers = { alc260_base_output_mixer,
4562                             alc260_input_mixer,
4563                             alc260_pc_beep_mixer,
4564                             alc260_capture_mixer },
4565                 .init_verbs = { alc260_init_verbs },
4566                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4567                 .dac_nids = alc260_dac_nids,
4568                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4569                 .adc_nids = alc260_adc_nids,
4570                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4571                 .channel_mode = alc260_modes,
4572                 .input_mux = &alc260_capture_source,
4573         },
4574         [ALC260_HP] = {
4575                 .mixers = { alc260_base_output_mixer,
4576                             alc260_input_mixer,
4577                             alc260_capture_alt_mixer },
4578                 .init_verbs = { alc260_init_verbs },
4579                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4580                 .dac_nids = alc260_dac_nids,
4581                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4582                 .adc_nids = alc260_hp_adc_nids,
4583                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4584                 .channel_mode = alc260_modes,
4585                 .input_mux = &alc260_capture_source,
4586         },
4587         [ALC260_HP_3013] = {
4588                 .mixers = { alc260_hp_3013_mixer,
4589                             alc260_input_mixer,
4590                             alc260_capture_alt_mixer },
4591                 .init_verbs = { alc260_hp_3013_init_verbs },
4592                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4593                 .dac_nids = alc260_dac_nids,
4594                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4595                 .adc_nids = alc260_hp_adc_nids,
4596                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4597                 .channel_mode = alc260_modes,
4598                 .input_mux = &alc260_capture_source,
4599         },
4600         [ALC260_FUJITSU_S702X] = {
4601                 .mixers = { alc260_fujitsu_mixer,
4602                             alc260_capture_mixer },
4603                 .init_verbs = { alc260_fujitsu_init_verbs },
4604                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4605                 .dac_nids = alc260_dac_nids,
4606                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4607                 .adc_nids = alc260_dual_adc_nids,
4608                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4609                 .channel_mode = alc260_modes,
4610                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4611                 .input_mux = alc260_fujitsu_capture_sources,
4612         },
4613         [ALC260_ACER] = {
4614                 .mixers = { alc260_acer_mixer,
4615                             alc260_capture_mixer },
4616                 .init_verbs = { alc260_acer_init_verbs },
4617                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4618                 .dac_nids = alc260_dac_nids,
4619                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4620                 .adc_nids = alc260_dual_adc_nids,
4621                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4622                 .channel_mode = alc260_modes,
4623                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4624                 .input_mux = alc260_acer_capture_sources,
4625         },
4626         [ALC260_WILL] = {
4627                 .mixers = { alc260_will_mixer,
4628                             alc260_capture_mixer },
4629                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4630                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4631                 .dac_nids = alc260_dac_nids,
4632                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4633                 .adc_nids = alc260_adc_nids,
4634                 .dig_out_nid = ALC260_DIGOUT_NID,
4635                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4636                 .channel_mode = alc260_modes,
4637                 .input_mux = &alc260_capture_source,
4638         },
4639         [ALC260_REPLACER_672V] = {
4640                 .mixers = { alc260_replacer_672v_mixer,
4641                             alc260_capture_mixer },
4642                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4643                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4644                 .dac_nids = alc260_dac_nids,
4645                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4646                 .adc_nids = alc260_adc_nids,
4647                 .dig_out_nid = ALC260_DIGOUT_NID,
4648                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4649                 .channel_mode = alc260_modes,
4650                 .input_mux = &alc260_capture_source,
4651                 .unsol_event = alc260_replacer_672v_unsol_event,
4652                 .init_hook = alc260_replacer_672v_automute,
4653         },
4654 #ifdef CONFIG_SND_DEBUG
4655         [ALC260_TEST] = {
4656                 .mixers = { alc260_test_mixer,
4657                             alc260_capture_mixer },
4658                 .init_verbs = { alc260_test_init_verbs },
4659                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4660                 .dac_nids = alc260_test_dac_nids,
4661                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4662                 .adc_nids = alc260_test_adc_nids,
4663                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4664                 .channel_mode = alc260_modes,
4665                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4666                 .input_mux = alc260_test_capture_sources,
4667         },
4668 #endif
4669 };
4670
4671 static int patch_alc260(struct hda_codec *codec)
4672 {
4673         struct alc_spec *spec;
4674         int err, board_config;
4675
4676         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4677         if (spec == NULL)
4678                 return -ENOMEM;
4679
4680         codec->spec = spec;
4681
4682         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4683                                                   alc260_models,
4684                                                   alc260_cfg_tbl);
4685         if (board_config < 0) {
4686                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4687                            "trying auto-probe from BIOS...\n");
4688                 board_config = ALC260_AUTO;
4689         }
4690
4691         if (board_config == ALC260_AUTO) {
4692                 /* automatic parse from the BIOS config */
4693                 err = alc260_parse_auto_config(codec);
4694                 if (err < 0) {
4695                         alc_free(codec);
4696                         return err;
4697                 } else if (!err) {
4698                         printk(KERN_INFO
4699                                "hda_codec: Cannot set up configuration "
4700                                "from BIOS.  Using base mode...\n");
4701                         board_config = ALC260_BASIC;
4702                 }
4703         }
4704
4705         if (board_config != ALC260_AUTO)
4706                 setup_preset(spec, &alc260_presets[board_config]);
4707
4708         spec->stream_name_analog = "ALC260 Analog";
4709         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4710         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4711
4712         spec->stream_name_digital = "ALC260 Digital";
4713         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4714         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4715
4716         codec->patch_ops = alc_patch_ops;
4717         if (board_config == ALC260_AUTO)
4718                 spec->init_hook = alc260_auto_init;
4719
4720         return 0;
4721 }
4722
4723
4724 /*
4725  * ALC882 support
4726  *
4727  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4728  * configuration.  Each pin widget can choose any input DACs and a mixer.
4729  * Each ADC is connected from a mixer of all inputs.  This makes possible
4730  * 6-channel independent captures.
4731  *
4732  * In addition, an independent DAC for the multi-playback (not used in this
4733  * driver yet).
4734  */
4735 #define ALC882_DIGOUT_NID       0x06
4736 #define ALC882_DIGIN_NID        0x0a
4737
4738 static struct hda_channel_mode alc882_ch_modes[1] = {
4739         { 8, NULL }
4740 };
4741
4742 static hda_nid_t alc882_dac_nids[4] = {
4743         /* front, rear, clfe, rear_surr */
4744         0x02, 0x03, 0x04, 0x05
4745 };
4746
4747 /* identical with ALC880 */
4748 #define alc882_adc_nids         alc880_adc_nids
4749 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4750
4751 /* input MUX */
4752 /* FIXME: should be a matrix-type input source selection */
4753
4754 static struct hda_input_mux alc882_capture_source = {
4755         .num_items = 4,
4756         .items = {
4757                 { "Mic", 0x0 },
4758                 { "Front Mic", 0x1 },
4759                 { "Line", 0x2 },
4760                 { "CD", 0x4 },
4761         },
4762 };
4763 #define alc882_mux_enum_info alc_mux_enum_info
4764 #define alc882_mux_enum_get alc_mux_enum_get
4765
4766 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4767                                struct snd_ctl_elem_value *ucontrol)
4768 {
4769         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4770         struct alc_spec *spec = codec->spec;
4771         const struct hda_input_mux *imux = spec->input_mux;
4772         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4773         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4774         hda_nid_t nid = capture_mixers[adc_idx];
4775         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4776         unsigned int i, idx;
4777
4778         idx = ucontrol->value.enumerated.item[0];
4779         if (idx >= imux->num_items)
4780                 idx = imux->num_items - 1;
4781         if (*cur_val == idx && !codec->in_resume)
4782                 return 0;
4783         for (i = 0; i < imux->num_items; i++) {
4784                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4785                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4786                                     v | (imux->items[i].index << 8));
4787         }
4788         *cur_val = idx;
4789         return 1;
4790 }
4791
4792 /*
4793  * 2ch mode
4794  */
4795 static struct hda_verb alc882_3ST_ch2_init[] = {
4796         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4797         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4798         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4799         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4800         { } /* end */
4801 };
4802
4803 /*
4804  * 6ch mode
4805  */
4806 static struct hda_verb alc882_3ST_ch6_init[] = {
4807         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4808         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4809         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4810         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4811         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4812         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4813         { } /* end */
4814 };
4815
4816 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4817         { 2, alc882_3ST_ch2_init },
4818         { 6, alc882_3ST_ch6_init },
4819 };
4820
4821 /*
4822  * 6ch mode
4823  */
4824 static struct hda_verb alc882_sixstack_ch6_init[] = {
4825         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4826         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4827         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4828         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4829         { } /* end */
4830 };
4831
4832 /*
4833  * 8ch mode
4834  */
4835 static struct hda_verb alc882_sixstack_ch8_init[] = {
4836         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4837         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4838         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4839         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4840         { } /* end */
4841 };
4842
4843 static struct hda_channel_mode alc882_sixstack_modes[2] = {
4844         { 6, alc882_sixstack_ch6_init },
4845         { 8, alc882_sixstack_ch8_init },
4846 };
4847
4848 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4849  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4850  */
4851 static struct snd_kcontrol_new alc882_base_mixer[] = {
4852         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4853         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4854         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4855         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4856         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4857         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4858         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4859         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4860         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4861         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4862         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4863         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4864         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4865         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4866         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4867         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4868         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4869         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4870         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4871         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4872         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4873         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4874         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4875         { } /* end */
4876 };
4877
4878 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4879         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4880         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4881         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4882         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4883         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4884         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4885         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4886         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4887         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4888         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4889         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4890         { } /* end */
4891 };
4892
4893 static struct snd_kcontrol_new alc882_targa_mixer[] = {
4894         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4895         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4896         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4897         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4898         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4899         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4900         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4901         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4902         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4903         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4904         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4905         { } /* end */
4906 };
4907
4908 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4909  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4910  */
4911 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4912         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4913         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4914         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4915         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4916         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4917         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4918         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4919         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4920         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4921         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4922         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4923         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4924         { } /* end */
4925 };
4926
4927 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4928         {
4929                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4930                 .name = "Channel Mode",
4931                 .info = alc_ch_mode_info,
4932                 .get = alc_ch_mode_get,
4933                 .put = alc_ch_mode_put,
4934         },
4935         { } /* end */
4936 };
4937
4938 static struct hda_verb alc882_init_verbs[] = {
4939         /* Front mixer: unmute input/output amp left and right (volume = 0) */
4940         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4941         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4942         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4943         /* Rear mixer */
4944         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4945         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4946         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4947         /* CLFE mixer */
4948         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4949         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4950         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4951         /* Side mixer */
4952         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4953         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4954         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4955
4956         /* Front Pin: output 0 (0x0c) */
4957         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4958         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4959         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4960         /* Rear Pin: output 1 (0x0d) */
4961         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4962         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4963         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4964         /* CLFE Pin: output 2 (0x0e) */
4965         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4966         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4967         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4968         /* Side Pin: output 3 (0x0f) */
4969         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4970         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4971         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4972         /* Mic (rear) pin: input vref at 80% */
4973         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4974         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4975         /* Front Mic pin: input vref at 80% */
4976         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4977         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4978         /* Line In pin: input */
4979         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4980         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4981         /* Line-2 In: Headphone output (output 0 - 0x0c) */
4982         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4983         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4984         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
4985         /* CD pin widget for input */
4986         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4987
4988         /* FIXME: use matrix-type input source selection */
4989         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4990         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4991         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4992         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4993         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4994         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4995         /* Input mixer2 */
4996         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4997         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4998         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4999         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5000         /* Input mixer3 */
5001         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5002         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5003         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5004         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5005         /* ADC1: mute amp left and right */
5006         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5007         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5008         /* ADC2: mute amp left and right */
5009         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5010         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5011         /* ADC3: mute amp left and right */
5012         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5013         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5014
5015         { }
5016 };
5017
5018 static struct hda_verb alc882_eapd_verbs[] = {
5019         /* change to EAPD mode */
5020         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5021         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5022         { }
5023 };
5024
5025 /* Mac Pro test */
5026 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5027         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5028         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5029         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5030         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5031         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5032         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5033         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5034         { } /* end */
5035 };
5036
5037 static struct hda_verb alc882_macpro_init_verbs[] = {
5038         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5039         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5040         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5041         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5042         /* Front Pin: output 0 (0x0c) */
5043         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5044         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5045         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5046         /* Front Mic pin: input vref at 80% */
5047         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5048         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5049         /* Speaker:  output */
5050         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5051         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5052         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5053         /* Headphone output (output 0 - 0x0c) */
5054         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5055         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5056         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5057
5058         /* FIXME: use matrix-type input source selection */
5059         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5060         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5061         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5062         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5063         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5064         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5065         /* Input mixer2 */
5066         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5067         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5068         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5069         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5070         /* Input mixer3 */
5071         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5072         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5073         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5074         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5075         /* ADC1: mute amp left and right */
5076         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5077         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5078         /* ADC2: mute amp left and right */
5079         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5080         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5081         /* ADC3: mute amp left and right */
5082         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5083         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5084
5085         { }
5086 };
5087
5088 static struct hda_verb alc882_targa_verbs[] = {
5089         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5090         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5091
5092         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5093         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5094         
5095         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5096         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5097         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5098
5099         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5100         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5101         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5102         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5103         { } /* end */
5104 };
5105
5106 /* toggle speaker-output according to the hp-jack state */
5107 static void alc882_targa_automute(struct hda_codec *codec)
5108 {
5109         unsigned int present;
5110  
5111         present = snd_hda_codec_read(codec, 0x14, 0,
5112                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5113         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5114                                  0x80, present ? 0x80 : 0);
5115         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5116                                  0x80, present ? 0x80 : 0);
5117         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5118 }
5119
5120 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5121 {
5122         /* Looks like the unsol event is incompatible with the standard
5123          * definition.  4bit tag is placed at 26 bit!
5124          */
5125         if (((res >> 26) == ALC880_HP_EVENT)) {
5126                 alc882_targa_automute(codec);
5127         }
5128 }
5129
5130 static struct hda_verb alc882_asus_a7j_verbs[] = {
5131         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5132         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5133
5134         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5135         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5136         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5137         
5138         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5139         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5140         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5141
5142         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5143         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5144         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5145         { } /* end */
5146 };
5147
5148 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5149 {
5150         unsigned int gpiostate, gpiomask, gpiodir;
5151
5152         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5153                                        AC_VERB_GET_GPIO_DATA, 0);
5154
5155         if (!muted)
5156                 gpiostate |= (1 << pin);
5157         else
5158                 gpiostate &= ~(1 << pin);
5159
5160         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5161                                       AC_VERB_GET_GPIO_MASK, 0);
5162         gpiomask |= (1 << pin);
5163
5164         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5165                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5166         gpiodir |= (1 << pin);
5167
5168
5169         snd_hda_codec_write(codec, codec->afg, 0,
5170                             AC_VERB_SET_GPIO_MASK, gpiomask);
5171         snd_hda_codec_write(codec, codec->afg, 0,
5172                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5173
5174         msleep(1);
5175
5176         snd_hda_codec_write(codec, codec->afg, 0,
5177                             AC_VERB_SET_GPIO_DATA, gpiostate);
5178 }
5179
5180 /*
5181  * generic initialization of ADC, input mixers and output mixers
5182  */
5183 static struct hda_verb alc882_auto_init_verbs[] = {
5184         /*
5185          * Unmute ADC0-2 and set the default input to mic-in
5186          */
5187         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5188         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5189         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5190         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5191         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5192         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5193
5194         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5195          * mixer widget
5196          * Note: PASD motherboards uses the Line In 2 as the input for
5197          * front panel mic (mic 2)
5198          */
5199         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5200         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5201         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5202         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5203         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5204         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5205
5206         /*
5207          * Set up output mixers (0x0c - 0x0f)
5208          */
5209         /* set vol=0 to output mixers */
5210         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5211         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5212         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5213         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5214         /* set up input amps for analog loopback */
5215         /* Amp Indices: DAC = 0, mixer = 1 */
5216         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5217         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5218         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5219         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5220         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5221         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5222         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5223         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5224         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5225         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5226
5227         /* FIXME: use matrix-type input source selection */
5228         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5229         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5230         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5231         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5232         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5233         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5234         /* Input mixer2 */
5235         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5236         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5237         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5238         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5239         /* Input mixer3 */
5240         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5241         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5242         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5243         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5244
5245         { }
5246 };
5247
5248 /* capture mixer elements */
5249 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5250         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5251         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5252         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5253         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5254         {
5255                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5256                 /* The multiple "Capture Source" controls confuse alsamixer
5257                  * So call somewhat different..
5258                  * FIXME: the controls appear in the "playback" view!
5259                  */
5260                 /* .name = "Capture Source", */
5261                 .name = "Input Source",
5262                 .count = 2,
5263                 .info = alc882_mux_enum_info,
5264                 .get = alc882_mux_enum_get,
5265                 .put = alc882_mux_enum_put,
5266         },
5267         { } /* end */
5268 };
5269
5270 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5271         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5272         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5273         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5274         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5275         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5276         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5277         {
5278                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5279                 /* The multiple "Capture Source" controls confuse alsamixer
5280                  * So call somewhat different..
5281                  * FIXME: the controls appear in the "playback" view!
5282                  */
5283                 /* .name = "Capture Source", */
5284                 .name = "Input Source",
5285                 .count = 3,
5286                 .info = alc882_mux_enum_info,
5287                 .get = alc882_mux_enum_get,
5288                 .put = alc882_mux_enum_put,
5289         },
5290         { } /* end */
5291 };
5292
5293 /* pcm configuration: identiacal with ALC880 */
5294 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5295 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5296 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5297 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5298
5299 /*
5300  * configuration and preset
5301  */
5302 static const char *alc882_models[ALC882_MODEL_LAST] = {
5303         [ALC882_3ST_DIG]        = "3stack-dig",
5304         [ALC882_6ST_DIG]        = "6stack-dig",
5305         [ALC882_ARIMA]          = "arima",
5306         [ALC882_W2JC]           = "w2jc",
5307         [ALC885_MACPRO]         = "macpro",
5308         [ALC882_AUTO]           = "auto",
5309 };
5310
5311 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5312         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5313         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5314         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5315         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5316         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5317         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5318         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5319         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5320         {}
5321 };
5322
5323 static struct alc_config_preset alc882_presets[] = {
5324         [ALC882_3ST_DIG] = {
5325                 .mixers = { alc882_base_mixer },
5326                 .init_verbs = { alc882_init_verbs },
5327                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5328                 .dac_nids = alc882_dac_nids,
5329                 .dig_out_nid = ALC882_DIGOUT_NID,
5330                 .dig_in_nid = ALC882_DIGIN_NID,
5331                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5332                 .channel_mode = alc882_ch_modes,
5333                 .need_dac_fix = 1,
5334                 .input_mux = &alc882_capture_source,
5335         },
5336         [ALC882_6ST_DIG] = {
5337                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5338                 .init_verbs = { alc882_init_verbs },
5339                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5340                 .dac_nids = alc882_dac_nids,
5341                 .dig_out_nid = ALC882_DIGOUT_NID,
5342                 .dig_in_nid = ALC882_DIGIN_NID,
5343                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5344                 .channel_mode = alc882_sixstack_modes,
5345                 .input_mux = &alc882_capture_source,
5346         },
5347         [ALC882_ARIMA] = {
5348                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5349                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5350                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5351                 .dac_nids = alc882_dac_nids,
5352                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5353                 .channel_mode = alc882_sixstack_modes,
5354                 .input_mux = &alc882_capture_source,
5355         },
5356         [ALC882_W2JC] = {
5357                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5358                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5359                                 alc880_gpio1_init_verbs },
5360                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5361                 .dac_nids = alc882_dac_nids,
5362                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5363                 .channel_mode = alc880_threestack_modes,
5364                 .need_dac_fix = 1,
5365                 .input_mux = &alc882_capture_source,
5366                 .dig_out_nid = ALC882_DIGOUT_NID,
5367         },
5368         [ALC885_MACPRO] = {
5369                 .mixers = { alc882_macpro_mixer },
5370                 .init_verbs = { alc882_macpro_init_verbs },
5371                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5372                 .dac_nids = alc882_dac_nids,
5373                 .dig_out_nid = ALC882_DIGOUT_NID,
5374                 .dig_in_nid = ALC882_DIGIN_NID,
5375                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5376                 .channel_mode = alc882_ch_modes,
5377                 .input_mux = &alc882_capture_source,
5378         },
5379         [ALC882_TARGA] = {
5380                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5381                             alc882_capture_mixer },
5382                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5383                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5384                 .dac_nids = alc882_dac_nids,
5385                 .dig_out_nid = ALC882_DIGOUT_NID,
5386                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5387                 .adc_nids = alc882_adc_nids,
5388                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5389                 .channel_mode = alc882_3ST_6ch_modes,
5390                 .need_dac_fix = 1,
5391                 .input_mux = &alc882_capture_source,
5392                 .unsol_event = alc882_targa_unsol_event,
5393                 .init_hook = alc882_targa_automute,
5394         },
5395         [ALC882_ASUS_A7J] = {
5396                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5397                             alc882_capture_mixer },
5398                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5399                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5400                 .dac_nids = alc882_dac_nids,
5401                 .dig_out_nid = ALC882_DIGOUT_NID,
5402                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5403                 .adc_nids = alc882_adc_nids,
5404                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5405                 .channel_mode = alc882_3ST_6ch_modes,
5406                 .need_dac_fix = 1,
5407                 .input_mux = &alc882_capture_source,
5408         },      
5409 };
5410
5411
5412 /*
5413  * BIOS auto configuration
5414  */
5415 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5416                                               hda_nid_t nid, int pin_type,
5417                                               int dac_idx)
5418 {
5419         /* set as output */
5420         struct alc_spec *spec = codec->spec;
5421         int idx;
5422
5423         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5424                 idx = 4;
5425         else
5426                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5427
5428         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5429                             pin_type);
5430         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5431                             AMP_OUT_UNMUTE);
5432         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5433
5434 }
5435
5436 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5437 {
5438         struct alc_spec *spec = codec->spec;
5439         int i;
5440
5441         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5442         for (i = 0; i <= HDA_SIDE; i++) {
5443                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5444                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5445                 if (nid)
5446                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5447                                                           i);
5448         }
5449 }
5450
5451 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5452 {
5453         struct alc_spec *spec = codec->spec;
5454         hda_nid_t pin;
5455
5456         pin = spec->autocfg.hp_pins[0];
5457         if (pin) /* connect to front */
5458                 /* use dac 0 */
5459                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5460 }
5461
5462 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5463 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5464
5465 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5466 {
5467         struct alc_spec *spec = codec->spec;
5468         int i;
5469
5470         for (i = 0; i < AUTO_PIN_LAST; i++) {
5471                 hda_nid_t nid = spec->autocfg.input_pins[i];
5472                 if (alc882_is_input_pin(nid)) {
5473                         snd_hda_codec_write(codec, nid, 0,
5474                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5475                                             i <= AUTO_PIN_FRONT_MIC ?
5476                                             PIN_VREF80 : PIN_IN);
5477                         if (nid != ALC882_PIN_CD_NID)
5478                                 snd_hda_codec_write(codec, nid, 0,
5479                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5480                                                     AMP_OUT_MUTE);
5481                 }
5482         }
5483 }
5484
5485 /* almost identical with ALC880 parser... */
5486 static int alc882_parse_auto_config(struct hda_codec *codec)
5487 {
5488         struct alc_spec *spec = codec->spec;
5489         int err = alc880_parse_auto_config(codec);
5490
5491         if (err < 0)
5492                 return err;
5493         else if (err > 0)
5494                 /* hack - override the init verbs */
5495                 spec->init_verbs[0] = alc882_auto_init_verbs;
5496         return err;
5497 }
5498
5499 /* additional initialization for auto-configuration model */
5500 static void alc882_auto_init(struct hda_codec *codec)
5501 {
5502         alc882_auto_init_multi_out(codec);
5503         alc882_auto_init_hp_out(codec);
5504         alc882_auto_init_analog_input(codec);
5505 }
5506
5507 static int patch_alc882(struct hda_codec *codec)
5508 {
5509         struct alc_spec *spec;
5510         int err, board_config;
5511
5512         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5513         if (spec == NULL)
5514                 return -ENOMEM;
5515
5516         codec->spec = spec;
5517
5518         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5519                                                   alc882_models,
5520                                                   alc882_cfg_tbl);
5521
5522         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5523                 /* Pick up systems that don't supply PCI SSID */
5524                 switch (codec->subsystem_id) {
5525                 case 0x106b0c00: /* Mac Pro */
5526                         board_config = ALC885_MACPRO;
5527                         break;
5528                 default:
5529                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5530                                          "trying auto-probe from BIOS...\n");
5531                         board_config = ALC882_AUTO;
5532                 }
5533         }
5534
5535         if (board_config == ALC882_AUTO) {
5536                 /* automatic parse from the BIOS config */
5537                 err = alc882_parse_auto_config(codec);
5538                 if (err < 0) {
5539                         alc_free(codec);
5540                         return err;
5541                 } else if (!err) {
5542                         printk(KERN_INFO
5543                                "hda_codec: Cannot set up configuration "
5544                                "from BIOS.  Using base mode...\n");
5545                         board_config = ALC882_3ST_DIG;
5546                 }
5547         }
5548
5549         if (board_config != ALC882_AUTO)
5550                 setup_preset(spec, &alc882_presets[board_config]);
5551
5552         if (board_config == ALC885_MACPRO) {
5553                 alc882_gpio_mute(codec, 0, 0);
5554                 alc882_gpio_mute(codec, 1, 0);
5555         }
5556
5557         spec->stream_name_analog = "ALC882 Analog";
5558         spec->stream_analog_playback = &alc882_pcm_analog_playback;
5559         spec->stream_analog_capture = &alc882_pcm_analog_capture;
5560
5561         spec->stream_name_digital = "ALC882 Digital";
5562         spec->stream_digital_playback = &alc882_pcm_digital_playback;
5563         spec->stream_digital_capture = &alc882_pcm_digital_capture;
5564
5565         if (!spec->adc_nids && spec->input_mux) {
5566                 /* check whether NID 0x07 is valid */
5567                 unsigned int wcap = get_wcaps(codec, 0x07);
5568                 /* get type */
5569                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5570                 if (wcap != AC_WID_AUD_IN) {
5571                         spec->adc_nids = alc882_adc_nids_alt;
5572                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5573                         spec->mixers[spec->num_mixers] =
5574                                 alc882_capture_alt_mixer;
5575                         spec->num_mixers++;
5576                 } else {
5577                         spec->adc_nids = alc882_adc_nids;
5578                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5579                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5580                         spec->num_mixers++;
5581                 }
5582         }
5583
5584         codec->patch_ops = alc_patch_ops;
5585         if (board_config == ALC882_AUTO)
5586                 spec->init_hook = alc882_auto_init;
5587
5588         return 0;
5589 }
5590
5591 /*
5592  * ALC883 support
5593  *
5594  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5595  * configuration.  Each pin widget can choose any input DACs and a mixer.
5596  * Each ADC is connected from a mixer of all inputs.  This makes possible
5597  * 6-channel independent captures.
5598  *
5599  * In addition, an independent DAC for the multi-playback (not used in this
5600  * driver yet).
5601  */
5602 #define ALC883_DIGOUT_NID       0x06
5603 #define ALC883_DIGIN_NID        0x0a
5604
5605 static hda_nid_t alc883_dac_nids[4] = {
5606         /* front, rear, clfe, rear_surr */
5607         0x02, 0x04, 0x03, 0x05
5608 };
5609
5610 static hda_nid_t alc883_adc_nids[2] = {
5611         /* ADC1-2 */
5612         0x08, 0x09,
5613 };
5614
5615 /* input MUX */
5616 /* FIXME: should be a matrix-type input source selection */
5617
5618 static struct hda_input_mux alc883_capture_source = {
5619         .num_items = 4,
5620         .items = {
5621                 { "Mic", 0x0 },
5622                 { "Front Mic", 0x1 },
5623                 { "Line", 0x2 },
5624                 { "CD", 0x4 },
5625         },
5626 };
5627
5628 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5629         .num_items = 2,
5630         .items = {
5631                 { "Mic", 0x1 },
5632                 { "Line", 0x2 },
5633         },
5634 };
5635
5636 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5637         .num_items = 4,
5638         .items = {
5639                 { "Mic", 0x0 },
5640                 { "iMic", 0x1 },
5641                 { "Line", 0x2 },
5642                 { "CD", 0x4 },
5643         },
5644 };
5645
5646 #define alc883_mux_enum_info alc_mux_enum_info
5647 #define alc883_mux_enum_get alc_mux_enum_get
5648
5649 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5650                                struct snd_ctl_elem_value *ucontrol)
5651 {
5652         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5653         struct alc_spec *spec = codec->spec;
5654         const struct hda_input_mux *imux = spec->input_mux;
5655         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5656         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5657         hda_nid_t nid = capture_mixers[adc_idx];
5658         unsigned int *cur_val = &spec->cur_mux[adc_idx];
5659         unsigned int i, idx;
5660
5661         idx = ucontrol->value.enumerated.item[0];
5662         if (idx >= imux->num_items)
5663                 idx = imux->num_items - 1;
5664         if (*cur_val == idx && !codec->in_resume)
5665                 return 0;
5666         for (i = 0; i < imux->num_items; i++) {
5667                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
5668                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5669                                     v | (imux->items[i].index << 8));
5670         }
5671         *cur_val = idx;
5672         return 1;
5673 }
5674
5675 /*
5676  * 2ch mode
5677  */
5678 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5679         { 2, NULL }
5680 };
5681
5682 /*
5683  * 2ch mode
5684  */
5685 static struct hda_verb alc883_3ST_ch2_init[] = {
5686         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5687         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5688         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5689         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5690         { } /* end */
5691 };
5692
5693 /*
5694  * 6ch mode
5695  */
5696 static struct hda_verb alc883_3ST_ch6_init[] = {
5697         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5698         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5699         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5700         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5701         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5702         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5703         { } /* end */
5704 };
5705
5706 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5707         { 2, alc883_3ST_ch2_init },
5708         { 6, alc883_3ST_ch6_init },
5709 };
5710
5711 /*
5712  * 6ch mode
5713  */
5714 static struct hda_verb alc883_sixstack_ch6_init[] = {
5715         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5716         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5717         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5718         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5719         { } /* end */
5720 };
5721
5722 /*
5723  * 8ch mode
5724  */
5725 static struct hda_verb alc883_sixstack_ch8_init[] = {
5726         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5727         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5728         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5729         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5730         { } /* end */
5731 };
5732
5733 static struct hda_channel_mode alc883_sixstack_modes[2] = {
5734         { 6, alc883_sixstack_ch6_init },
5735         { 8, alc883_sixstack_ch8_init },
5736 };
5737
5738 static struct hda_verb alc883_medion_eapd_verbs[] = {
5739         /* eanable EAPD on medion laptop */
5740         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5741         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5742         { }
5743 };
5744
5745 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5746  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5747  */
5748
5749 static struct snd_kcontrol_new alc883_base_mixer[] = {
5750         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5751         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5752         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5753         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5754         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5755         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5756         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5757         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5758         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5759         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5760         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5761         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5762         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5763         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5764         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5765         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5766         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5767         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5768         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5769         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5770         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5771         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5772         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5773         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5774         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5775         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5776         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5777         {
5778                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5779                 /* .name = "Capture Source", */
5780                 .name = "Input Source",
5781                 .count = 2,
5782                 .info = alc883_mux_enum_info,
5783                 .get = alc883_mux_enum_get,
5784                 .put = alc883_mux_enum_put,
5785         },
5786         { } /* end */
5787 };
5788
5789 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5790         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5791         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5792         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5793         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5794         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5795         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5796         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5797         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5798         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5799         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5800         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5801         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5802         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5803         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5804         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5805         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5806         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5807         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5808         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5809         {
5810                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5811                 /* .name = "Capture Source", */
5812                 .name = "Input Source",
5813                 .count = 2,
5814                 .info = alc883_mux_enum_info,
5815                 .get = alc883_mux_enum_get,
5816                 .put = alc883_mux_enum_put,
5817         },
5818         { } /* end */
5819 };
5820
5821 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5822         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5823         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5824         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5825         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5826         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5827         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5828         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5829         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5830         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5831         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5832         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5833         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5834         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5835         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5836         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5837         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5838         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5839         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5840         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5841         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5842         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5843         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5844         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5845         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5846         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5847         {
5848                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5849                 /* .name = "Capture Source", */
5850                 .name = "Input Source",
5851                 .count = 2,
5852                 .info = alc883_mux_enum_info,
5853                 .get = alc883_mux_enum_get,
5854                 .put = alc883_mux_enum_put,
5855         },
5856         { } /* end */
5857 };
5858
5859 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5860         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5861         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5862         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5863         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5864         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5865         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5866         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5867         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5868         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5869         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5870         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5871         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5872         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5873         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5874         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5875         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5876         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5877         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5878         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5879         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5880         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5881         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5882         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5883
5884         {
5885                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5886                 /* .name = "Capture Source", */
5887                 .name = "Input Source",
5888                 .count = 1,
5889                 .info = alc883_mux_enum_info,
5890                 .get = alc883_mux_enum_get,
5891                 .put = alc883_mux_enum_put,
5892         },
5893         { } /* end */
5894 };
5895
5896 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5897         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5898         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5899         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5900         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5901         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5902         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5903         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5904         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5905         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5906         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5907         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5908         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5909         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5910         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5911         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5912         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5913         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5914         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5915         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5916         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5917         {
5918                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5919                 /* .name = "Capture Source", */
5920                 .name = "Input Source",
5921                 .count = 2,
5922                 .info = alc883_mux_enum_info,
5923                 .get = alc883_mux_enum_get,
5924                 .put = alc883_mux_enum_put,
5925         },
5926         { } /* end */
5927 };
5928
5929 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5930         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5931         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5932         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5933         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5934         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5935         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5936         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5937         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5938         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5939         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5940         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5941         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5942         {
5943                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5944                 /* .name = "Capture Source", */
5945                 .name = "Input Source",
5946                 .count = 2,
5947                 .info = alc883_mux_enum_info,
5948                 .get = alc883_mux_enum_get,
5949                 .put = alc883_mux_enum_put,
5950         },
5951         { } /* end */
5952 };
5953
5954 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
5955         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5956         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5957         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5958         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
5959         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5960         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5961         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5962         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5963         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5964         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5965         {
5966                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5967                 /* .name = "Capture Source", */
5968                 .name = "Input Source",
5969                 .count = 1,
5970                 .info = alc883_mux_enum_info,
5971                 .get = alc883_mux_enum_get,
5972                 .put = alc883_mux_enum_put,
5973         },
5974         { } /* end */
5975 };
5976
5977 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
5978         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5979         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
5980         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5981         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5982         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5983         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5984         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5985         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5986         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5987         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5988         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5989         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5990         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5991         {
5992                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5993                 /* .name = "Capture Source", */
5994                 .name = "Input Source",
5995                 .count = 2,
5996                 .info = alc883_mux_enum_info,
5997                 .get = alc883_mux_enum_get,
5998                 .put = alc883_mux_enum_put,
5999         },
6000         { } /* end */
6001 };
6002
6003 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6004         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6005         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6006         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6007         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6008         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6009         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6010         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6011         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6012         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6013         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6014         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6015         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6016         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6017         {
6018                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6019                 /* .name = "Capture Source", */
6020                 .name = "Input Source",
6021                 .count = 2,
6022                 .info = alc883_mux_enum_info,
6023                 .get = alc883_mux_enum_get,
6024                 .put = alc883_mux_enum_put,
6025         },
6026         { } /* end */
6027 };      
6028
6029 static struct snd_kcontrol_new alc888_hp_nettle_mixer[] = {
6030         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6031         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6032         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6033         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6034         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6035         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6036         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6037         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6038         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6039         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6040         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6041         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6042         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6043         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6044         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6045         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6046         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6047         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6048         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6049         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6050         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6051         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6052         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6053         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6054         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6055         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6056         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6057         {
6058                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6059                 /* .name = "Capture Source", */
6060                 .name = "Input Source",
6061                 .count = 2,
6062                 .info = alc883_mux_enum_info,
6063                 .get = alc883_mux_enum_get,
6064                 .put = alc883_mux_enum_put,
6065         },
6066         { } /* end */
6067 };
6068
6069 static struct snd_kcontrol_new alc888_hp_lucknow_mixer[] = {
6070         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6071         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6072         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6073         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6074         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6075         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6076         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6077         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6078         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6079         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6080         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6081         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6082         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6083         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6084         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6085         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6086         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6087         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6088         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6089         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6090         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6091         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6092         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6093         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6094         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6095         {
6096                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6097                 /* .name = "Capture Source", */
6098                 .name = "Input Source",
6099                 .count = 2,
6100                 .info = alc883_mux_enum_info,
6101                 .get = alc883_mux_enum_get,
6102                 .put = alc883_mux_enum_put,
6103         },
6104         { } /* end */
6105 };
6106
6107 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6108         {
6109                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6110                 .name = "Channel Mode",
6111                 .info = alc_ch_mode_info,
6112                 .get = alc_ch_mode_get,
6113                 .put = alc_ch_mode_put,
6114         },
6115         { } /* end */
6116 };
6117
6118 static struct hda_verb alc883_init_verbs[] = {
6119         /* ADC1: mute amp left and right */
6120         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6121         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6122         /* ADC2: mute amp left and right */
6123         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6124         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6125         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6126         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6127         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6128         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6129         /* Rear mixer */
6130         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6131         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6132         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6133         /* CLFE mixer */
6134         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6135         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6136         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6137         /* Side mixer */
6138         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6139         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6140         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6141
6142         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6143         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6144         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6145         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6146         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6147
6148         /* Front Pin: output 0 (0x0c) */
6149         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6150         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6151         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6152         /* Rear Pin: output 1 (0x0d) */
6153         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6154         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6155         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6156         /* CLFE Pin: output 2 (0x0e) */
6157         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6158         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6159         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6160         /* Side Pin: output 3 (0x0f) */
6161         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6162         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6163         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6164         /* Mic (rear) pin: input vref at 80% */
6165         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6166         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6167         /* Front Mic pin: input vref at 80% */
6168         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6169         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6170         /* Line In pin: input */
6171         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6172         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6173         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6174         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6175         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6176         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6177         /* CD pin widget for input */
6178         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6179
6180         /* FIXME: use matrix-type input source selection */
6181         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6182         /* Input mixer2 */
6183         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6184         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6185         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6186         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6187         /* Input mixer3 */
6188         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6189         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6190         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6191         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6192         { }
6193 };
6194
6195 static struct hda_verb alc883_tagra_verbs[] = {
6196         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6197         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6198
6199         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6200         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6201         
6202         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6203         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6204         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6205
6206         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6207         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6208         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6209         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6210
6211         { } /* end */
6212 };
6213
6214 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6215         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6216         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6217         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6218         { } /* end */
6219 };
6220
6221 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6222         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6223         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6224         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6225         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6226         { } /* end */
6227 };
6228
6229 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6230         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6231         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6232         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6233         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6234         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6235         { } /* end */
6236 };
6237
6238 static struct hda_verb alc888_hp_nettle_verbs[] = {
6239         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6240         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6241         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6242         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6243         { }
6244 };
6245
6246 static struct hda_verb alc888_hp_lucknow_verbs[] = {
6247         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6248         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6249         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6250         { }
6251 };
6252
6253 static struct hda_verb alc888_hp_lucknow_2ch_init[] = {
6254         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6255         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6256         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6257         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6258         { }
6259 };
6260
6261 static struct hda_verb alc888_hp_lucknow_6ch_init[] = {
6262         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6263         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6264         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6265         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6266         { }
6267 };
6268
6269 static struct hda_channel_mode alc888_hp_lucknow_modes[2] = {
6270         { 2, alc888_hp_lucknow_2ch_init },
6271         { 6, alc888_hp_lucknow_6ch_init },
6272 };
6273
6274 /* toggle front-jack and RCA according to the hp-jack state */
6275 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6276 {
6277         unsigned int present;
6278  
6279         present = snd_hda_codec_read(codec, 0x1b, 0,
6280                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6281         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6282                                  0x80, present ? 0x80 : 0);
6283         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6284                                  0x80, present ? 0x80 : 0);
6285         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6286                                  0x80, present ? 0x80 : 0);
6287         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6288                                  0x80, present ? 0x80 : 0);
6289         
6290 }
6291
6292 /* toggle RCA according to the front-jack state */
6293 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6294 {
6295         unsigned int present;
6296  
6297         present = snd_hda_codec_read(codec, 0x14, 0,
6298                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6299         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6300                                  0x80, present ? 0x80 : 0);
6301         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6302                                  0x80, present ? 0x80 : 0);
6303         
6304 }
6305 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6306                                              unsigned int res)
6307 {
6308         if ((res >> 26) == ALC880_HP_EVENT)
6309                 alc888_lenovo_ms7195_front_automute(codec);
6310         if ((res >> 26) == ALC880_FRONT_EVENT)
6311                 alc888_lenovo_ms7195_rca_automute(codec);
6312 }
6313
6314 static struct hda_verb alc883_medion_md2_verbs[] = {
6315         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6316         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6317
6318         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6319
6320         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6321         { } /* end */
6322 };
6323
6324 /* toggle speaker-output according to the hp-jack state */
6325 static void alc883_medion_md2_automute(struct hda_codec *codec)
6326 {
6327         unsigned int present;
6328  
6329         present = snd_hda_codec_read(codec, 0x14, 0,
6330                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6331         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6332                                  0x80, present ? 0x80 : 0);
6333         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6334                                  0x80, present ? 0x80 : 0);
6335 }
6336
6337 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6338                                           unsigned int res)
6339 {
6340         if ((res >> 26) == ALC880_HP_EVENT)
6341                 alc883_medion_md2_automute(codec);
6342 }
6343
6344 /* toggle speaker-output according to the hp-jack state */
6345 static void alc883_tagra_automute(struct hda_codec *codec)
6346 {
6347         unsigned int present;
6348         unsigned char bits;
6349
6350         present = snd_hda_codec_read(codec, 0x14, 0,
6351                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6352         bits = present ? 0x80 : 0;
6353         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
6354                                  0x80, bits);
6355         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
6356                                  0x80, bits);
6357         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6358                             present ? 1 : 3);
6359 }
6360
6361 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6362 {
6363         if ((res >> 26) == ALC880_HP_EVENT)
6364                 alc883_tagra_automute(codec);
6365 }
6366
6367 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6368 {
6369         unsigned int present;
6370         unsigned char bits;
6371
6372         present = snd_hda_codec_read(codec, 0x14, 0,
6373                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6374         bits = present ? 0x80 : 0;
6375         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6376                                  0x80, bits);
6377         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6378                                  0x80, bits);
6379 }
6380
6381 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6382 {
6383         unsigned int present;
6384         unsigned char bits;
6385
6386         present = snd_hda_codec_read(codec, 0x1b, 0,
6387                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6388         bits = present ? 0x80 : 0;
6389         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6390                                  0x80, bits);
6391         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6392                                  0x80, bits);
6393         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6394                                  0x80, bits);
6395         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6396                                  0x80, bits);
6397 }
6398
6399 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6400                                            unsigned int res)
6401 {
6402         if ((res >> 26) == ALC880_HP_EVENT)
6403                 alc883_lenovo_101e_all_automute(codec);
6404         if ((res >> 26) == ALC880_FRONT_EVENT)
6405                 alc883_lenovo_101e_ispeaker_automute(codec);
6406 }
6407
6408 /*
6409  * generic initialization of ADC, input mixers and output mixers
6410  */
6411 static struct hda_verb alc883_auto_init_verbs[] = {
6412         /*
6413          * Unmute ADC0-2 and set the default input to mic-in
6414          */
6415         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6416         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6417         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6418         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6419
6420         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6421          * mixer widget
6422          * Note: PASD motherboards uses the Line In 2 as the input for
6423          * front panel mic (mic 2)
6424          */
6425         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6426         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6427         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6428         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6429         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6430         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6431
6432         /*
6433          * Set up output mixers (0x0c - 0x0f)
6434          */
6435         /* set vol=0 to output mixers */
6436         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6437         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6438         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6439         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6440         /* set up input amps for analog loopback */
6441         /* Amp Indices: DAC = 0, mixer = 1 */
6442         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6443         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6444         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6445         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6446         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6447         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6448         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6449         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6450         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6451         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6452
6453         /* FIXME: use matrix-type input source selection */
6454         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6455         /* Input mixer1 */
6456         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6457         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6458         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6459         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6460         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6461         /* Input mixer2 */
6462         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6463         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6464         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6465         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6466         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6467
6468         { }
6469 };
6470
6471 /* capture mixer elements */
6472 static struct snd_kcontrol_new alc883_capture_mixer[] = {
6473         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6474         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6475         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6476         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6477         {
6478                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6479                 /* The multiple "Capture Source" controls confuse alsamixer
6480                  * So call somewhat different..
6481                  * FIXME: the controls appear in the "playback" view!
6482                  */
6483                 /* .name = "Capture Source", */
6484                 .name = "Input Source",
6485                 .count = 2,
6486                 .info = alc882_mux_enum_info,
6487                 .get = alc882_mux_enum_get,
6488                 .put = alc882_mux_enum_put,
6489         },
6490         { } /* end */
6491 };
6492
6493 /* pcm configuration: identiacal with ALC880 */
6494 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
6495 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
6496 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
6497 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
6498
6499 /*
6500  * configuration and preset
6501  */
6502 static const char *alc883_models[ALC883_MODEL_LAST] = {
6503         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
6504         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
6505         [ALC883_3ST_6ch]        = "3stack-6ch",
6506         [ALC883_6ST_DIG]        = "6stack-dig",
6507         [ALC883_TARGA_DIG]      = "targa-dig",
6508         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
6509         [ALC883_ACER]           = "acer",
6510         [ALC883_MEDION]         = "medion",
6511         [ALC883_MEDION_MD2]     = "medion-md2",
6512         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
6513         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6514         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
6515         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6516         [ALC888_HP_NETTLE]      = "hp-nettle",
6517         [ALC888_HP_LUCKNOW]     = "hp-lucknow",
6518         [ALC883_AUTO]           = "auto",
6519 };
6520
6521 static struct snd_pci_quirk alc883_cfg_tbl[] = {
6522         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6523         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6524         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6525         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6526         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6527         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6528         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6529         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6530         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6531         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6532         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6533         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6534         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6535         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6536         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6537         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6538         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6539         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6540         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6541         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6542         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6543         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6544         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6545         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6546         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6547         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6548         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6549         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6550         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6551         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6552         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_HP_NETTLE),
6553         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_HP_LUCKNOW),
6554         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6555         {}
6556 };
6557
6558 static struct alc_config_preset alc883_presets[] = {
6559         [ALC883_3ST_2ch_DIG] = {
6560                 .mixers = { alc883_3ST_2ch_mixer },
6561                 .init_verbs = { alc883_init_verbs },
6562                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6563                 .dac_nids = alc883_dac_nids,
6564                 .dig_out_nid = ALC883_DIGOUT_NID,
6565                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6566                 .adc_nids = alc883_adc_nids,
6567                 .dig_in_nid = ALC883_DIGIN_NID,
6568                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6569                 .channel_mode = alc883_3ST_2ch_modes,
6570                 .input_mux = &alc883_capture_source,
6571         },
6572         [ALC883_3ST_6ch_DIG] = {
6573                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6574                 .init_verbs = { alc883_init_verbs },
6575                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6576                 .dac_nids = alc883_dac_nids,
6577                 .dig_out_nid = ALC883_DIGOUT_NID,
6578                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6579                 .adc_nids = alc883_adc_nids,
6580                 .dig_in_nid = ALC883_DIGIN_NID,
6581                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6582                 .channel_mode = alc883_3ST_6ch_modes,
6583                 .need_dac_fix = 1,
6584                 .input_mux = &alc883_capture_source,
6585         },
6586         [ALC883_3ST_6ch] = {
6587                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6588                 .init_verbs = { alc883_init_verbs },
6589                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6590                 .dac_nids = alc883_dac_nids,
6591                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6592                 .adc_nids = alc883_adc_nids,
6593                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6594                 .channel_mode = alc883_3ST_6ch_modes,
6595                 .need_dac_fix = 1,
6596                 .input_mux = &alc883_capture_source,
6597         },
6598         [ALC883_6ST_DIG] = {
6599                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
6600                 .init_verbs = { alc883_init_verbs },
6601                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6602                 .dac_nids = alc883_dac_nids,
6603                 .dig_out_nid = ALC883_DIGOUT_NID,
6604                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6605                 .adc_nids = alc883_adc_nids,
6606                 .dig_in_nid = ALC883_DIGIN_NID,
6607                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6608                 .channel_mode = alc883_sixstack_modes,
6609                 .input_mux = &alc883_capture_source,
6610         },
6611         [ALC883_TARGA_DIG] = {
6612                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6613                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6614                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6615                 .dac_nids = alc883_dac_nids,
6616                 .dig_out_nid = ALC883_DIGOUT_NID,
6617                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6618                 .adc_nids = alc883_adc_nids,
6619                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6620                 .channel_mode = alc883_3ST_6ch_modes,
6621                 .need_dac_fix = 1,
6622                 .input_mux = &alc883_capture_source,
6623                 .unsol_event = alc883_tagra_unsol_event,
6624                 .init_hook = alc883_tagra_automute,
6625         },
6626         [ALC883_TARGA_2ch_DIG] = {
6627                 .mixers = { alc883_tagra_2ch_mixer},
6628                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6629                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6630                 .dac_nids = alc883_dac_nids,
6631                 .dig_out_nid = ALC883_DIGOUT_NID,
6632                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6633                 .adc_nids = alc883_adc_nids,
6634                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6635                 .channel_mode = alc883_3ST_2ch_modes,
6636                 .input_mux = &alc883_capture_source,
6637                 .unsol_event = alc883_tagra_unsol_event,
6638                 .init_hook = alc883_tagra_automute,
6639         },
6640         [ALC883_ACER] = {
6641                 .mixers = { alc883_base_mixer,
6642                             alc883_chmode_mixer },
6643                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
6644                  * and the headphone jack.  Turn this on and rely on the
6645                  * standard mute methods whenever the user wants to turn
6646                  * these outputs off.
6647                  */
6648                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6649                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6650                 .dac_nids = alc883_dac_nids,
6651                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6652                 .adc_nids = alc883_adc_nids,
6653                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6654                 .channel_mode = alc883_3ST_2ch_modes,
6655                 .input_mux = &alc883_capture_source,
6656         },
6657         [ALC883_MEDION] = {
6658                 .mixers = { alc883_fivestack_mixer,
6659                             alc883_chmode_mixer },
6660                 .init_verbs = { alc883_init_verbs,
6661                                 alc883_medion_eapd_verbs },
6662                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6663                 .dac_nids = alc883_dac_nids,
6664                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6665                 .adc_nids = alc883_adc_nids,
6666                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6667                 .channel_mode = alc883_sixstack_modes,
6668                 .input_mux = &alc883_capture_source,
6669         },
6670         [ALC883_MEDION_MD2] = {
6671                 .mixers = { alc883_medion_md2_mixer},
6672                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6673                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6674                 .dac_nids = alc883_dac_nids,
6675                 .dig_out_nid = ALC883_DIGOUT_NID,
6676                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6677                 .adc_nids = alc883_adc_nids,
6678                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6679                 .channel_mode = alc883_3ST_2ch_modes,
6680                 .input_mux = &alc883_capture_source,
6681                 .unsol_event = alc883_medion_md2_unsol_event,
6682                 .init_hook = alc883_medion_md2_automute,
6683         },      
6684         [ALC883_LAPTOP_EAPD] = {
6685                 .mixers = { alc883_base_mixer,
6686                             alc883_chmode_mixer },
6687                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6688                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6689                 .dac_nids = alc883_dac_nids,
6690                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6691                 .adc_nids = alc883_adc_nids,
6692                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6693                 .channel_mode = alc883_3ST_2ch_modes,
6694                 .input_mux = &alc883_capture_source,
6695         },
6696         [ALC883_LENOVO_101E_2ch] = {
6697                 .mixers = { alc883_lenovo_101e_2ch_mixer},
6698                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6699                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6700                 .dac_nids = alc883_dac_nids,
6701                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6702                 .adc_nids = alc883_adc_nids,
6703                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6704                 .channel_mode = alc883_3ST_2ch_modes,
6705                 .input_mux = &alc883_lenovo_101e_capture_source,
6706                 .unsol_event = alc883_lenovo_101e_unsol_event,
6707                 .init_hook = alc883_lenovo_101e_all_automute,
6708         },
6709         [ALC883_LENOVO_NB0763] = {
6710                 .mixers = { alc883_lenovo_nb0763_mixer },
6711                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6712                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6713                 .dac_nids = alc883_dac_nids,
6714                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6715                 .adc_nids = alc883_adc_nids,
6716                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6717                 .channel_mode = alc883_3ST_2ch_modes,
6718                 .need_dac_fix = 1,
6719                 .input_mux = &alc883_lenovo_nb0763_capture_source,
6720                 .unsol_event = alc883_medion_md2_unsol_event,
6721                 .init_hook = alc883_medion_md2_automute,
6722         },
6723         [ALC888_LENOVO_MS7195_DIG] = {
6724                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6725                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6726                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6727                 .dac_nids = alc883_dac_nids,
6728                 .dig_out_nid = ALC883_DIGOUT_NID,
6729                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6730                 .adc_nids = alc883_adc_nids,
6731                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6732                 .channel_mode = alc883_3ST_6ch_modes,
6733                 .need_dac_fix = 1,
6734                 .input_mux = &alc883_capture_source,
6735                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
6736                 .init_hook = alc888_lenovo_ms7195_front_automute,
6737         },      
6738         [ALC888_HP_NETTLE] = {
6739                 .mixers = { alc888_hp_nettle_mixer, alc883_chmode_mixer },
6740                 .init_verbs = { alc883_init_verbs, alc888_hp_nettle_verbs },
6741                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6742                 .dac_nids = alc883_dac_nids,
6743                 .dig_out_nid = ALC883_DIGOUT_NID,
6744                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6745                 .adc_nids = alc883_adc_nids,
6746                 .dig_in_nid = ALC883_DIGIN_NID,
6747                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6748                 .channel_mode = alc883_sixstack_modes,
6749                 .input_mux = &alc883_capture_source,
6750         },
6751         [ALC888_HP_LUCKNOW] = {
6752                 .mixers = { alc888_hp_lucknow_mixer, alc883_chmode_mixer },
6753                 .init_verbs = { alc883_init_verbs, alc888_hp_lucknow_verbs },
6754                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6755                 .dac_nids = alc883_dac_nids,
6756                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6757                 .adc_nids = alc883_adc_nids,
6758                 .num_channel_mode = ARRAY_SIZE(alc888_hp_lucknow_modes),
6759                 .channel_mode = alc888_hp_lucknow_modes,
6760                 .need_dac_fix = 1,
6761                 .input_mux = &alc883_capture_source,
6762         },
6763 };
6764
6765
6766 /*
6767  * BIOS auto configuration
6768  */
6769 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6770                                               hda_nid_t nid, int pin_type,
6771                                               int dac_idx)
6772 {
6773         /* set as output */
6774         struct alc_spec *spec = codec->spec;
6775         int idx;
6776
6777         if (spec->multiout.dac_nids[dac_idx] == 0x25)
6778                 idx = 4;
6779         else
6780                 idx = spec->multiout.dac_nids[dac_idx] - 2;
6781
6782         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6783                             pin_type);
6784         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6785                             AMP_OUT_UNMUTE);
6786         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6787
6788 }
6789
6790 static void alc883_auto_init_multi_out(struct hda_codec *codec)
6791 {
6792         struct alc_spec *spec = codec->spec;
6793         int i;
6794
6795         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6796         for (i = 0; i <= HDA_SIDE; i++) {
6797                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6798                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6799                 if (nid)
6800                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6801                                                           i);
6802         }
6803 }
6804
6805 static void alc883_auto_init_hp_out(struct hda_codec *codec)
6806 {
6807         struct alc_spec *spec = codec->spec;
6808         hda_nid_t pin;
6809
6810         pin = spec->autocfg.hp_pins[0];
6811         if (pin) /* connect to front */
6812                 /* use dac 0 */
6813                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6814 }
6815
6816 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
6817 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
6818
6819 static void alc883_auto_init_analog_input(struct hda_codec *codec)
6820 {
6821         struct alc_spec *spec = codec->spec;
6822         int i;
6823
6824         for (i = 0; i < AUTO_PIN_LAST; i++) {
6825                 hda_nid_t nid = spec->autocfg.input_pins[i];
6826                 if (alc883_is_input_pin(nid)) {
6827                         snd_hda_codec_write(codec, nid, 0,
6828                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
6829                                             (i <= AUTO_PIN_FRONT_MIC ?
6830                                              PIN_VREF80 : PIN_IN));
6831                         if (nid != ALC883_PIN_CD_NID)
6832                                 snd_hda_codec_write(codec, nid, 0,
6833                                                     AC_VERB_SET_AMP_GAIN_MUTE,
6834                                                     AMP_OUT_MUTE);
6835                 }
6836         }
6837 }
6838
6839 /* almost identical with ALC880 parser... */
6840 static int alc883_parse_auto_config(struct hda_codec *codec)
6841 {
6842         struct alc_spec *spec = codec->spec;
6843         int err = alc880_parse_auto_config(codec);
6844
6845         if (err < 0)
6846                 return err;
6847         else if (err > 0)
6848                 /* hack - override the init verbs */
6849                 spec->init_verbs[0] = alc883_auto_init_verbs;
6850         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
6851         spec->num_mixers++;
6852         return err;
6853 }
6854
6855 /* additional initialization for auto-configuration model */
6856 static void alc883_auto_init(struct hda_codec *codec)
6857 {
6858         alc883_auto_init_multi_out(codec);
6859         alc883_auto_init_hp_out(codec);
6860         alc883_auto_init_analog_input(codec);
6861 }
6862
6863 static int patch_alc883(struct hda_codec *codec)
6864 {
6865         struct alc_spec *spec;
6866         int err, board_config;
6867
6868         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6869         if (spec == NULL)
6870                 return -ENOMEM;
6871
6872         codec->spec = spec;
6873
6874         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
6875                                                   alc883_models,
6876                                                   alc883_cfg_tbl);
6877         if (board_config < 0) {
6878                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
6879                        "trying auto-probe from BIOS...\n");
6880                 board_config = ALC883_AUTO;
6881         }
6882
6883         if (board_config == ALC883_AUTO) {
6884                 /* automatic parse from the BIOS config */
6885                 err = alc883_parse_auto_config(codec);
6886                 if (err < 0) {
6887                         alc_free(codec);
6888                         return err;
6889                 } else if (!err) {
6890                         printk(KERN_INFO
6891                                "hda_codec: Cannot set up configuration "
6892                                "from BIOS.  Using base mode...\n");
6893                         board_config = ALC883_3ST_2ch_DIG;
6894                 }
6895         }
6896
6897         if (board_config != ALC883_AUTO)
6898                 setup_preset(spec, &alc883_presets[board_config]);
6899
6900         spec->stream_name_analog = "ALC883 Analog";
6901         spec->stream_analog_playback = &alc883_pcm_analog_playback;
6902         spec->stream_analog_capture = &alc883_pcm_analog_capture;
6903
6904         spec->stream_name_digital = "ALC883 Digital";
6905         spec->stream_digital_playback = &alc883_pcm_digital_playback;
6906         spec->stream_digital_capture = &alc883_pcm_digital_capture;
6907
6908         if (!spec->adc_nids && spec->input_mux) {
6909                 spec->adc_nids = alc883_adc_nids;
6910                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
6911         }
6912
6913         codec->patch_ops = alc_patch_ops;
6914         if (board_config == ALC883_AUTO)
6915                 spec->init_hook = alc883_auto_init;
6916
6917         return 0;
6918 }
6919
6920 /*
6921  * ALC262 support
6922  */
6923
6924 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
6925 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
6926
6927 #define alc262_dac_nids         alc260_dac_nids
6928 #define alc262_adc_nids         alc882_adc_nids
6929 #define alc262_adc_nids_alt     alc882_adc_nids_alt
6930
6931 #define alc262_modes            alc260_modes
6932 #define alc262_capture_source   alc882_capture_source
6933
6934 static struct snd_kcontrol_new alc262_base_mixer[] = {
6935         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6936         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6937         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6938         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6939         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6940         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6941         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6942         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6943         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6944         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6945         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6946         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6947         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6948            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
6949         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
6950         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6951         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6952         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6953         { } /* end */
6954 };
6955
6956 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
6957         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6958         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6959         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6960         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6961         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6962         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6963         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6964         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6965         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6966         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6967         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6968         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6969         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6970            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
6971         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
6972         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6973         { } /* end */
6974 };
6975
6976 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
6977         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6978         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6979         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6980         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6981         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6982
6983         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6984         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6985         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6986         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6987         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6988         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6989         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6990         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6991         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6992         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6993         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6994         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
6995         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
6996         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
6997         { } /* end */
6998 };
6999
7000 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7001         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7002         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7003         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7004         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7005         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7006         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7007         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7008         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7009         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7010         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7011         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7012         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7013         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7014         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7015         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7016         { } /* end */
7017 };
7018
7019 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7020         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7021         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7022         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7023         { } /* end */
7024 };
7025
7026 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7027         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7028         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7029         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7030         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7031         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7032         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7033         { } /* end */
7034 };
7035
7036 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7037         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7038         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7039         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7040         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7041         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7042         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7043         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7044         { } /* end */
7045 };
7046
7047 #define alc262_capture_mixer            alc882_capture_mixer
7048 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7049
7050 /*
7051  * generic initialization of ADC, input mixers and output mixers
7052  */
7053 static struct hda_verb alc262_init_verbs[] = {
7054         /*
7055          * Unmute ADC0-2 and set the default input to mic-in
7056          */
7057         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7058         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7059         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7060         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7061         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7062         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7063
7064         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7065          * mixer widget
7066          * Note: PASD motherboards uses the Line In 2 as the input for
7067          * front panel mic (mic 2)
7068          */
7069         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7070         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7071         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7072         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7073         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7074         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7075
7076         /*
7077          * Set up output mixers (0x0c - 0x0e)
7078          */
7079         /* set vol=0 to output mixers */
7080         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7081         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7082         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7083         /* set up input amps for analog loopback */
7084         /* Amp Indices: DAC = 0, mixer = 1 */
7085         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7086         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7087         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7088         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7089         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7090         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7091
7092         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7093         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7094         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7095         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7096         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7097         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7098
7099         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7100         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7101         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7102         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7103         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7104         
7105         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7106         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7107         
7108         /* FIXME: use matrix-type input source selection */
7109         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7110         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7111         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7112         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7113         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7114         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7115         /* Input mixer2 */
7116         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7117         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7118         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7119         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7120         /* Input mixer3 */
7121         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7122         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7123         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7124         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7125
7126         { }
7127 };
7128
7129 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7130         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7131         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7132         {}
7133 };
7134
7135 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7136         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7137         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7138         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7139
7140         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7141         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7142         {}
7143 };
7144
7145 static struct hda_verb alc262_sony_unsol_verbs[] = {
7146         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7147         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7148         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7149
7150         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7151         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7152 };
7153
7154 /* mute/unmute internal speaker according to the hp jack and mute state */
7155 static void alc262_hippo_automute(struct hda_codec *codec, int force)
7156 {
7157         struct alc_spec *spec = codec->spec;
7158         unsigned int mute;
7159
7160         if (force || !spec->sense_updated) {
7161                 unsigned int present;
7162                 /* need to execute and sync at first */
7163                 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7164                 present = snd_hda_codec_read(codec, 0x15, 0,
7165                                          AC_VERB_GET_PIN_SENSE, 0);
7166                 spec->jack_present = (present & 0x80000000) != 0;
7167                 spec->sense_updated = 1;
7168         }
7169         if (spec->jack_present) {
7170                 /* mute internal speaker */
7171                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7172                                          0x80, 0x80);
7173                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7174                                          0x80, 0x80);
7175         } else {
7176                 /* unmute internal speaker if necessary */
7177                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7178                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7179                                          0x80, mute & 0x80);
7180                 mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
7181                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7182                                          0x80, mute & 0x80);
7183         }
7184 }
7185
7186 /* unsolicited event for HP jack sensing */
7187 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7188                                        unsigned int res)
7189 {
7190         if ((res >> 26) != ALC880_HP_EVENT)
7191                 return;
7192         alc262_hippo_automute(codec, 1);
7193 }
7194
7195 static void alc262_hippo1_automute(struct hda_codec *codec, int force)
7196 {
7197         struct alc_spec *spec = codec->spec;
7198         unsigned int mute;
7199
7200         if (force || !spec->sense_updated) {
7201                 unsigned int present;
7202                 /* need to execute and sync at first */
7203                 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7204                 present = snd_hda_codec_read(codec, 0x1b, 0,
7205                                          AC_VERB_GET_PIN_SENSE, 0);
7206                 spec->jack_present = (present & 0x80000000) != 0;
7207                 spec->sense_updated = 1;
7208         }
7209         if (spec->jack_present) {
7210                 /* mute internal speaker */
7211                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7212                                          0x80, 0x80);
7213                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7214                                          0x80, 0x80);
7215         } else {
7216                 /* unmute internal speaker if necessary */
7217                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7218                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7219                                          0x80, mute & 0x80);
7220                 mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
7221                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7222                                          0x80, mute & 0x80);
7223         }
7224 }
7225
7226 /* unsolicited event for HP jack sensing */
7227 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7228                                        unsigned int res)
7229 {
7230         if ((res >> 26) != ALC880_HP_EVENT)
7231                 return;
7232         alc262_hippo1_automute(codec, 1);
7233 }
7234
7235 /*
7236  * fujitsu model
7237  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7238  */
7239
7240 #define ALC_HP_EVENT    0x37
7241
7242 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7243         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7244         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7245         {}
7246 };
7247
7248 static struct hda_input_mux alc262_fujitsu_capture_source = {
7249         .num_items = 2,
7250         .items = {
7251                 { "Mic", 0x0 },
7252                 { "CD", 0x4 },
7253         },
7254 };
7255
7256 static struct hda_input_mux alc262_HP_capture_source = {
7257         .num_items = 5,
7258         .items = {
7259                 { "Mic", 0x0 },
7260                 { "Front Mic", 0x3 },
7261                 { "Line", 0x2 },
7262                 { "CD", 0x4 },
7263                 { "AUX IN", 0x6 },
7264         },
7265 };
7266
7267 /* mute/unmute internal speaker according to the hp jack and mute state */
7268 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7269 {
7270         struct alc_spec *spec = codec->spec;
7271         unsigned int mute;
7272
7273         if (force || !spec->sense_updated) {
7274                 unsigned int present;
7275                 /* need to execute and sync at first */
7276                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7277                 present = snd_hda_codec_read(codec, 0x14, 0,
7278                                          AC_VERB_GET_PIN_SENSE, 0);
7279                 spec->jack_present = (present & 0x80000000) != 0;
7280                 spec->sense_updated = 1;
7281         }
7282         if (spec->jack_present) {
7283                 /* mute internal speaker */
7284                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7285                                          0x80, 0x80);
7286                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7287                                          0x80, 0x80);
7288         } else {
7289                 /* unmute internal speaker if necessary */
7290                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7291                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7292                                          0x80, mute & 0x80);
7293                 mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
7294                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7295                                          0x80, mute & 0x80);
7296         }
7297 }
7298
7299 /* unsolicited event for HP jack sensing */
7300 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7301                                        unsigned int res)
7302 {
7303         if ((res >> 26) != ALC_HP_EVENT)
7304                 return;
7305         alc262_fujitsu_automute(codec, 1);
7306 }
7307
7308 /* bind volumes of both NID 0x0c and 0x0d */
7309 static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
7310                                          struct snd_ctl_elem_value *ucontrol)
7311 {
7312         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7313         long *valp = ucontrol->value.integer.value;
7314         int change;
7315
7316         change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
7317                                           0x7f, valp[0] & 0x7f);
7318         change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
7319                                            0x7f, valp[1] & 0x7f);
7320         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
7321                                  0x7f, valp[0] & 0x7f);
7322         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
7323                                  0x7f, valp[1] & 0x7f);
7324         return change;
7325 }
7326
7327 /* bind hp and internal speaker mute (with plug check) */
7328 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7329                                          struct snd_ctl_elem_value *ucontrol)
7330 {
7331         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7332         long *valp = ucontrol->value.integer.value;
7333         int change;
7334
7335         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7336                                           0x80, valp[0] ? 0 : 0x80);
7337         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7338                                            0x80, valp[1] ? 0 : 0x80);
7339         if (change || codec->in_resume)
7340                 alc262_fujitsu_automute(codec, codec->in_resume);
7341         return change;
7342 }
7343
7344 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7345         {
7346                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7347                 .name = "Master Playback Volume",
7348                 .info = snd_hda_mixer_amp_volume_info,
7349                 .get = snd_hda_mixer_amp_volume_get,
7350                 .put = alc262_fujitsu_master_vol_put,
7351                 .tlv = { .c = snd_hda_mixer_amp_tlv },
7352                 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7353         },
7354         {
7355                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7356                 .name = "Master Playback Switch",
7357                 .info = snd_hda_mixer_amp_switch_info,
7358                 .get = snd_hda_mixer_amp_switch_get,
7359                 .put = alc262_fujitsu_master_sw_put,
7360                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7361         },
7362         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7363         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7364         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7365         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7366         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7367         { } /* end */
7368 };
7369
7370 /* additional init verbs for Benq laptops */
7371 static struct hda_verb alc262_EAPD_verbs[] = {
7372         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7373         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7374         {}
7375 };
7376
7377 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7378         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7379         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7380
7381         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7382         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7383         {}
7384 };
7385
7386 /* add playback controls from the parsed DAC table */
7387 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7388                                              const struct auto_pin_cfg *cfg)
7389 {
7390         hda_nid_t nid;
7391         int err;
7392
7393         spec->multiout.num_dacs = 1;    /* only use one dac */
7394         spec->multiout.dac_nids = spec->private_dac_nids;
7395         spec->multiout.dac_nids[0] = 2;
7396
7397         nid = cfg->line_out_pins[0];
7398         if (nid) {
7399                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7400                                   "Front Playback Volume",
7401                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7402                 if (err < 0)
7403                         return err;
7404                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7405                                   "Front Playback Switch",
7406                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7407                 if (err < 0)
7408                         return err;
7409         }
7410
7411         nid = cfg->speaker_pins[0];
7412         if (nid) {
7413                 if (nid == 0x16) {
7414                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7415                                           "Speaker Playback Volume",
7416                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7417                                                               HDA_OUTPUT));
7418                         if (err < 0)
7419                                 return err;
7420                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7421                                           "Speaker Playback Switch",
7422                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7423                                                               HDA_OUTPUT));
7424                         if (err < 0)
7425                                 return err;
7426                 } else {
7427                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7428                                           "Speaker Playback Switch",
7429                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7430                                                               HDA_OUTPUT));
7431                         if (err < 0)
7432                                 return err;
7433                 }
7434         }
7435         nid = cfg->hp_pins[0];
7436         if (nid) {
7437                 /* spec->multiout.hp_nid = 2; */
7438                 if (nid == 0x16) {
7439                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7440                                           "Headphone Playback Volume",
7441                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7442                                                               HDA_OUTPUT));
7443                         if (err < 0)
7444                                 return err;
7445                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7446                                           "Headphone Playback Switch",
7447                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7448                                                               HDA_OUTPUT));
7449                         if (err < 0)
7450                                 return err;
7451                 } else {
7452                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7453                                           "Headphone Playback Switch",
7454                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7455                                                               HDA_OUTPUT));
7456                         if (err < 0)
7457                                 return err;
7458                 }
7459         }
7460         return 0;
7461 }
7462
7463 /* identical with ALC880 */
7464 #define alc262_auto_create_analog_input_ctls \
7465         alc880_auto_create_analog_input_ctls
7466
7467 /*
7468  * generic initialization of ADC, input mixers and output mixers
7469  */
7470 static struct hda_verb alc262_volume_init_verbs[] = {
7471         /*
7472          * Unmute ADC0-2 and set the default input to mic-in
7473          */
7474         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7475         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7476         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7477         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7478         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7479         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7480
7481         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7482          * mixer widget
7483          * Note: PASD motherboards uses the Line In 2 as the input for
7484          * front panel mic (mic 2)
7485          */
7486         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7487         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7488         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7489         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7490         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7491         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7492
7493         /*
7494          * Set up output mixers (0x0c - 0x0f)
7495          */
7496         /* set vol=0 to output mixers */
7497         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7498         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7499         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7500         
7501         /* set up input amps for analog loopback */
7502         /* Amp Indices: DAC = 0, mixer = 1 */
7503         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7504         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7505         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7506         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7507         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7508         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7509
7510         /* FIXME: use matrix-type input source selection */
7511         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7512         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7513         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7514         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7515         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7516         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7517         /* Input mixer2 */
7518         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7519         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7520         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7521         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7522         /* Input mixer3 */
7523         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7524         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7525         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7526         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7527
7528         { }
7529 };
7530
7531 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7532         /*
7533          * Unmute ADC0-2 and set the default input to mic-in
7534          */
7535         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7536         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7537         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7538         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7539         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7540         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7541
7542         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7543          * mixer widget
7544          * Note: PASD motherboards uses the Line In 2 as the input for
7545          * front panel mic (mic 2)
7546          */
7547         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7548         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7549         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7550         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7551         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7552         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7553         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7554         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7555         
7556         /*
7557          * Set up output mixers (0x0c - 0x0e)
7558          */
7559         /* set vol=0 to output mixers */
7560         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7561         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7562         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7563
7564         /* set up input amps for analog loopback */
7565         /* Amp Indices: DAC = 0, mixer = 1 */
7566         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7567         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7568         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7569         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7570         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7571         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7572
7573         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7574         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7575         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7576
7577         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7578         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7579
7580         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7581         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7582
7583         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7584         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7585         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7586         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7587         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7588
7589         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7590         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7591         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7592         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7593         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7594         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7595
7596
7597         /* FIXME: use matrix-type input source selection */
7598         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7599         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7600         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7601         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7602         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7603         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7604         /* Input mixer2 */
7605         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7606         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7607         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7608         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7609         /* Input mixer3 */
7610         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7611         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7612         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7613         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7614
7615         { }
7616 };
7617
7618 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7619         /*
7620          * Unmute ADC0-2 and set the default input to mic-in
7621          */
7622         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7623         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7624         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7625         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7626         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7627         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7628
7629         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7630          * mixer widget
7631          * Note: PASD motherboards uses the Line In 2 as the input for front
7632          * panel mic (mic 2)
7633          */
7634         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7635         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7636         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7637         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7638         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7639         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7640         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7641         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7642         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
7643         /*
7644          * Set up output mixers (0x0c - 0x0e)
7645          */
7646         /* set vol=0 to output mixers */
7647         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7648         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7649         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7650
7651         /* set up input amps for analog loopback */
7652         /* Amp Indices: DAC = 0, mixer = 1 */
7653         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7654         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7655         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7656         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7657         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7658         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7659
7660
7661         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
7662         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
7663         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
7664         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
7665         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
7666         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
7667         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
7668
7669         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7670         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7671
7672         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7673         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7674
7675         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7676         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7677         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7678         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7679         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7680         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7681
7682         /* FIXME: use matrix-type input source selection */
7683         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7684         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7685         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7686         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7687         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7688         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7689         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7690         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7691         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7692         /* Input mixer2 */
7693         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7694         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7695         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7696         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7697         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7698         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7699         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7700         /* Input mixer3 */
7701         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7702         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7703         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7704         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7705         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7706         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7707         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7708
7709         { }
7710 };
7711
7712 /* pcm configuration: identiacal with ALC880 */
7713 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
7714 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
7715 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
7716 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
7717
7718 /*
7719  * BIOS auto configuration
7720  */
7721 static int alc262_parse_auto_config(struct hda_codec *codec)
7722 {
7723         struct alc_spec *spec = codec->spec;
7724         int err;
7725         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7726
7727         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7728                                            alc262_ignore);
7729         if (err < 0)
7730                 return err;
7731         if (!spec->autocfg.line_outs)
7732                 return 0; /* can't find valid BIOS pin config */
7733         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7734         if (err < 0)
7735                 return err;
7736         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7737         if (err < 0)
7738                 return err;
7739
7740         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7741
7742         if (spec->autocfg.dig_out_pin)
7743                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7744         if (spec->autocfg.dig_in_pin)
7745                 spec->dig_in_nid = ALC262_DIGIN_NID;
7746
7747         if (spec->kctl_alloc)
7748                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7749
7750         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7751         spec->num_mux_defs = 1;
7752         spec->input_mux = &spec->private_imux;
7753
7754         return 1;
7755 }
7756
7757 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
7758 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
7759 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
7760
7761
7762 /* init callback for auto-configuration model -- overriding the default init */
7763 static void alc262_auto_init(struct hda_codec *codec)
7764 {
7765         alc262_auto_init_multi_out(codec);
7766         alc262_auto_init_hp_out(codec);
7767         alc262_auto_init_analog_input(codec);
7768 }
7769
7770 /*
7771  * configuration and preset
7772  */
7773 static const char *alc262_models[ALC262_MODEL_LAST] = {
7774         [ALC262_BASIC]          = "basic",
7775         [ALC262_HIPPO]          = "hippo",
7776         [ALC262_HIPPO_1]        = "hippo_1",
7777         [ALC262_FUJITSU]        = "fujitsu",
7778         [ALC262_HP_BPC]         = "hp-bpc",
7779         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7780         [ALC262_BENQ_ED8]       = "benq",
7781         [ALC262_BENQ_ED8]       = "sony-assamd",
7782         [ALC262_AUTO]           = "auto",
7783 };
7784
7785 static struct snd_pci_quirk alc262_cfg_tbl[] = {
7786         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7787         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7788         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7789         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7790         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7791         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7792         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7793         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7794         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7795         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7796         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7797         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7798         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7799         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7800         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7801         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7802         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7803         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7804         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7805         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7806         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7807         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7808         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7809         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7810         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7811         {}
7812 };
7813
7814 static struct alc_config_preset alc262_presets[] = {
7815         [ALC262_BASIC] = {
7816                 .mixers = { alc262_base_mixer },
7817                 .init_verbs = { alc262_init_verbs },
7818                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7819                 .dac_nids = alc262_dac_nids,
7820                 .hp_nid = 0x03,
7821                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7822                 .channel_mode = alc262_modes,
7823                 .input_mux = &alc262_capture_source,
7824         },
7825         [ALC262_HIPPO] = {
7826                 .mixers = { alc262_base_mixer },
7827                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
7828                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7829                 .dac_nids = alc262_dac_nids,
7830                 .hp_nid = 0x03,
7831                 .dig_out_nid = ALC262_DIGOUT_NID,
7832                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7833                 .channel_mode = alc262_modes,
7834                 .input_mux = &alc262_capture_source,
7835                 .unsol_event = alc262_hippo_unsol_event,
7836         },
7837         [ALC262_HIPPO_1] = {
7838                 .mixers = { alc262_hippo1_mixer },
7839                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
7840                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7841                 .dac_nids = alc262_dac_nids,
7842                 .hp_nid = 0x02,
7843                 .dig_out_nid = ALC262_DIGOUT_NID,
7844                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7845                 .channel_mode = alc262_modes,
7846                 .input_mux = &alc262_capture_source,
7847                 .unsol_event = alc262_hippo1_unsol_event,
7848         },
7849         [ALC262_FUJITSU] = {
7850                 .mixers = { alc262_fujitsu_mixer },
7851                 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
7852                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7853                 .dac_nids = alc262_dac_nids,
7854                 .hp_nid = 0x03,
7855                 .dig_out_nid = ALC262_DIGOUT_NID,
7856                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7857                 .channel_mode = alc262_modes,
7858                 .input_mux = &alc262_fujitsu_capture_source,
7859                 .unsol_event = alc262_fujitsu_unsol_event,
7860         },
7861         [ALC262_HP_BPC] = {
7862                 .mixers = { alc262_HP_BPC_mixer },
7863                 .init_verbs = { alc262_HP_BPC_init_verbs },
7864                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7865                 .dac_nids = alc262_dac_nids,
7866                 .hp_nid = 0x03,
7867                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7868                 .channel_mode = alc262_modes,
7869                 .input_mux = &alc262_HP_capture_source,
7870         },
7871         [ALC262_HP_BPC_D7000_WF] = {
7872                 .mixers = { alc262_HP_BPC_WildWest_mixer },
7873                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7874                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7875                 .dac_nids = alc262_dac_nids,
7876                 .hp_nid = 0x03,
7877                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7878                 .channel_mode = alc262_modes,
7879                 .input_mux = &alc262_HP_capture_source,
7880         },
7881         [ALC262_HP_BPC_D7000_WL] = {
7882                 .mixers = { alc262_HP_BPC_WildWest_mixer,
7883                             alc262_HP_BPC_WildWest_option_mixer },
7884                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7885                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7886                 .dac_nids = alc262_dac_nids,
7887                 .hp_nid = 0x03,
7888                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7889                 .channel_mode = alc262_modes,
7890                 .input_mux = &alc262_HP_capture_source,
7891         },
7892         [ALC262_BENQ_ED8] = {
7893                 .mixers = { alc262_base_mixer },
7894                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
7895                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7896                 .dac_nids = alc262_dac_nids,
7897                 .hp_nid = 0x03,
7898                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7899                 .channel_mode = alc262_modes,
7900                 .input_mux = &alc262_capture_source,
7901         },
7902         [ALC262_SONY_ASSAMD] = {
7903                 .mixers = { alc262_sony_mixer },
7904                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
7905                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7906                 .dac_nids = alc262_dac_nids,
7907                 .hp_nid = 0x02,
7908                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7909                 .channel_mode = alc262_modes,
7910                 .input_mux = &alc262_capture_source,
7911                 .unsol_event = alc262_hippo_unsol_event,
7912         },
7913         [ALC262_BENQ_T31] = {
7914                 .mixers = { alc262_benq_t31_mixer },
7915                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
7916                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7917                 .dac_nids = alc262_dac_nids,
7918                 .hp_nid = 0x03,
7919                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7920                 .channel_mode = alc262_modes,
7921                 .input_mux = &alc262_capture_source,
7922                 .unsol_event = alc262_hippo_unsol_event,
7923         },      
7924 };
7925
7926 static int patch_alc262(struct hda_codec *codec)
7927 {
7928         struct alc_spec *spec;
7929         int board_config;
7930         int err;
7931
7932         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7933         if (spec == NULL)
7934                 return -ENOMEM;
7935
7936         codec->spec = spec;
7937 #if 0
7938         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
7939          * under-run
7940          */
7941         {
7942         int tmp;
7943         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
7944         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
7945         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
7946         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
7947         }
7948 #endif
7949
7950         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
7951                                                   alc262_models,
7952                                                   alc262_cfg_tbl);
7953
7954         if (board_config < 0) {
7955                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
7956                        "trying auto-probe from BIOS...\n");
7957                 board_config = ALC262_AUTO;
7958         }
7959
7960         if (board_config == ALC262_AUTO) {
7961                 /* automatic parse from the BIOS config */
7962                 err = alc262_parse_auto_config(codec);
7963                 if (err < 0) {
7964                         alc_free(codec);
7965                         return err;
7966                 } else if (!err) {
7967                         printk(KERN_INFO
7968                                "hda_codec: Cannot set up configuration "
7969                                "from BIOS.  Using base mode...\n");
7970                         board_config = ALC262_BASIC;
7971                 }
7972         }
7973
7974         if (board_config != ALC262_AUTO)
7975                 setup_preset(spec, &alc262_presets[board_config]);
7976
7977         spec->stream_name_analog = "ALC262 Analog";
7978         spec->stream_analog_playback = &alc262_pcm_analog_playback;
7979         spec->stream_analog_capture = &alc262_pcm_analog_capture;
7980                 
7981         spec->stream_name_digital = "ALC262 Digital";
7982         spec->stream_digital_playback = &alc262_pcm_digital_playback;
7983         spec->stream_digital_capture = &alc262_pcm_digital_capture;
7984
7985         if (!spec->adc_nids && spec->input_mux) {
7986                 /* check whether NID 0x07 is valid */
7987                 unsigned int wcap = get_wcaps(codec, 0x07);
7988
7989                 /* get type */
7990                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7991                 if (wcap != AC_WID_AUD_IN) {
7992                         spec->adc_nids = alc262_adc_nids_alt;
7993                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
7994                         spec->mixers[spec->num_mixers] =
7995                                 alc262_capture_alt_mixer;
7996                         spec->num_mixers++;
7997                 } else {
7998                         spec->adc_nids = alc262_adc_nids;
7999                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8000                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8001                         spec->num_mixers++;
8002                 }
8003         }
8004
8005         codec->patch_ops = alc_patch_ops;
8006         if (board_config == ALC262_AUTO)
8007                 spec->init_hook = alc262_auto_init;
8008                 
8009         return 0;
8010 }
8011
8012 /*
8013  *  ALC268 channel source setting (2 channel)
8014  */
8015 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8016 #define alc268_modes            alc260_modes
8017         
8018 static hda_nid_t alc268_dac_nids[2] = {
8019         /* front, hp */
8020         0x02, 0x03
8021 };
8022
8023 static hda_nid_t alc268_adc_nids[2] = {
8024         /* ADC0-1 */
8025         0x08, 0x07
8026 };
8027
8028 static hda_nid_t alc268_adc_nids_alt[1] = {
8029         /* ADC0 */
8030         0x08
8031 };
8032
8033 static struct snd_kcontrol_new alc268_base_mixer[] = {
8034         /* output mixer control */
8035         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8036         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8037         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8038         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8039         { }
8040 };
8041
8042 /*
8043  * generic initialization of ADC, input mixers and output mixers
8044  */
8045 static struct hda_verb alc268_base_init_verbs[] = {
8046         /* Unmute DAC0-1 and set vol = 0 */
8047         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8048         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8049         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8050         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8051         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8052         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8053
8054         /*
8055          * Set up output mixers (0x0c - 0x0e)
8056          */
8057         /* set vol=0 to output mixers */
8058         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8059         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8060         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8061         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8062
8063         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8064         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8065
8066         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8067         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8068         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8069         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8070         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8071         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8072         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8073         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8074
8075         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8076         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8077         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8078         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8079         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8080         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8081         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8082         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8083
8084         /* FIXME: use matrix-type input source selection */
8085         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8086         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8087         /* Input mixer2 */
8088         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8089         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8090         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8091         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8092
8093         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8094         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8095         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8096         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8097         { }
8098 };
8099
8100 /*
8101  * generic initialization of ADC, input mixers and output mixers
8102  */
8103 static struct hda_verb alc268_volume_init_verbs[] = {
8104         /* set output DAC */
8105         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8106         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8107         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8108         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8109
8110         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8111         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8112         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8113         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8114         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8115
8116         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8117         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8118         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8119         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8120         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8121
8122         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8123         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8124         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8125         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8126
8127         /* set PCBEEP vol = 0 */
8128         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8129
8130         { }
8131 };
8132
8133 #define alc268_mux_enum_info alc_mux_enum_info
8134 #define alc268_mux_enum_get alc_mux_enum_get
8135
8136 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8137                                struct snd_ctl_elem_value *ucontrol)
8138 {
8139         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8140         struct alc_spec *spec = codec->spec;
8141         const struct hda_input_mux *imux = spec->input_mux;
8142         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8143         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8144         hda_nid_t nid = capture_mixers[adc_idx];
8145         unsigned int *cur_val = &spec->cur_mux[adc_idx];
8146         unsigned int i, idx;
8147
8148         idx = ucontrol->value.enumerated.item[0];
8149         if (idx >= imux->num_items)
8150                 idx = imux->num_items - 1;
8151         if (*cur_val == idx && !codec->in_resume)
8152                 return 0;
8153         for (i = 0; i < imux->num_items; i++) {
8154                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8155                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8156                                     v | (imux->items[i].index << 8));
8157                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
8158                                     idx );
8159         }
8160         *cur_val = idx;
8161         return 1;
8162 }
8163
8164 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8165         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8166         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8167         {
8168                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8169                 /* The multiple "Capture Source" controls confuse alsamixer
8170                  * So call somewhat different..
8171                  * FIXME: the controls appear in the "playback" view!
8172                  */
8173                 /* .name = "Capture Source", */
8174                 .name = "Input Source",
8175                 .count = 1,
8176                 .info = alc268_mux_enum_info,
8177                 .get = alc268_mux_enum_get,
8178                 .put = alc268_mux_enum_put,
8179         },
8180         { } /* end */
8181 };
8182
8183 static struct snd_kcontrol_new alc268_capture_mixer[] = {
8184         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8185         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8186         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8187         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8188         {
8189                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8190                 /* The multiple "Capture Source" controls confuse alsamixer
8191                  * So call somewhat different..
8192                  * FIXME: the controls appear in the "playback" view!
8193                  */
8194                 /* .name = "Capture Source", */
8195                 .name = "Input Source",
8196                 .count = 2,
8197                 .info = alc268_mux_enum_info,
8198                 .get = alc268_mux_enum_get,
8199                 .put = alc268_mux_enum_put,
8200         },
8201         { } /* end */
8202 };
8203
8204 static struct hda_input_mux alc268_capture_source = {
8205         .num_items = 4,
8206         .items = {
8207                 { "Mic", 0x0 },
8208                 { "Front Mic", 0x1 },
8209                 { "Line", 0x2 },
8210                 { "CD", 0x3 },
8211         },
8212 };
8213
8214 /* create input playback/capture controls for the given pin */
8215 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8216                                     const char *ctlname, int idx)
8217 {
8218         char name[32];
8219         int err;
8220
8221         sprintf(name, "%s Playback Volume", ctlname);
8222         if (nid == 0x14) {
8223                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8224                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8225                                                       HDA_OUTPUT));
8226                 if (err < 0)
8227                         return err;
8228         } else if (nid == 0x15) {
8229                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8230                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8231                                                       HDA_OUTPUT));
8232                 if (err < 0)
8233                         return err;
8234         } else
8235                 return -1;
8236         sprintf(name, "%s Playback Switch", ctlname);
8237         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8238                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8239         if (err < 0)
8240                 return err;
8241         return 0;
8242 }
8243
8244 /* add playback controls from the parsed DAC table */
8245 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8246                                              const struct auto_pin_cfg *cfg)
8247 {
8248         hda_nid_t nid;
8249         int err;
8250
8251         spec->multiout.num_dacs = 2;    /* only use one dac */
8252         spec->multiout.dac_nids = spec->private_dac_nids;
8253         spec->multiout.dac_nids[0] = 2;
8254         spec->multiout.dac_nids[1] = 3;
8255
8256         nid = cfg->line_out_pins[0];
8257         if (nid)
8258                 alc268_new_analog_output(spec, nid, "Front", 0);        
8259
8260         nid = cfg->speaker_pins[0];
8261         if (nid == 0x1d) {
8262                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8263                                   "Speaker Playback Volume",
8264                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8265                 if (err < 0)
8266                         return err;
8267         }
8268         nid = cfg->hp_pins[0];
8269         if (nid)
8270                 alc268_new_analog_output(spec, nid, "Headphone", 0);
8271
8272         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8273         if (nid == 0x16) {
8274                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8275                                   "Mono Playback Switch",
8276                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8277                 if (err < 0)
8278                         return err;
8279         }
8280         return 0;       
8281 }
8282
8283 /* create playback/capture controls for input pins */
8284 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8285                                                 const struct auto_pin_cfg *cfg)
8286 {
8287         struct hda_input_mux *imux = &spec->private_imux;
8288         int i, idx1;
8289
8290         for (i = 0; i < AUTO_PIN_LAST; i++) {
8291                 switch(cfg->input_pins[i]) {
8292                 case 0x18:
8293                         idx1 = 0;       /* Mic 1 */
8294                         break;
8295                 case 0x19:
8296                         idx1 = 1;       /* Mic 2 */
8297                         break;
8298                 case 0x1a:
8299                         idx1 = 2;       /* Line In */
8300                         break;
8301                 case 0x1c:      
8302                         idx1 = 3;       /* CD */
8303                         break;
8304                 default:
8305                         continue;
8306                 }
8307                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8308                 imux->items[imux->num_items].index = idx1;
8309                 imux->num_items++;      
8310         }
8311         return 0;
8312 }
8313
8314 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8315 {
8316         struct alc_spec *spec = codec->spec;
8317         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8318         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8319         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8320         unsigned int    dac_vol1, dac_vol2;
8321
8322         if (speaker_nid) {
8323                 snd_hda_codec_write(codec, speaker_nid, 0,
8324                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8325                 snd_hda_codec_write(codec, 0x0f, 0,
8326                                     AC_VERB_SET_AMP_GAIN_MUTE,
8327                                     AMP_IN_UNMUTE(1));
8328                 snd_hda_codec_write(codec, 0x10, 0,
8329                                     AC_VERB_SET_AMP_GAIN_MUTE,
8330                                     AMP_IN_UNMUTE(1));
8331         } else {
8332                 snd_hda_codec_write(codec, 0x0f, 0,
8333                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8334                 snd_hda_codec_write(codec, 0x10, 0,
8335                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8336         }
8337
8338         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
8339         if (line_nid == 0x14)   
8340                 dac_vol2 = AMP_OUT_ZERO;
8341         else if (line_nid == 0x15)
8342                 dac_vol1 = AMP_OUT_ZERO;
8343         if (hp_nid == 0x14)     
8344                 dac_vol2 = AMP_OUT_ZERO;
8345         else if (hp_nid == 0x15)
8346                 dac_vol1 = AMP_OUT_ZERO;
8347         if (line_nid != 0x16 || hp_nid != 0x16 ||
8348             spec->autocfg.line_out_pins[1] != 0x16 ||
8349             spec->autocfg.line_out_pins[2] != 0x16)
8350                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8351
8352         snd_hda_codec_write(codec, 0x02, 0,
8353                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8354         snd_hda_codec_write(codec, 0x03, 0,
8355                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8356 }
8357
8358 /* pcm configuration: identiacal with ALC880 */
8359 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
8360 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
8361 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
8362
8363 /*
8364  * BIOS auto configuration
8365  */
8366 static int alc268_parse_auto_config(struct hda_codec *codec)
8367 {
8368         struct alc_spec *spec = codec->spec;
8369         int err;
8370         static hda_nid_t alc268_ignore[] = { 0 };
8371
8372         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8373                                            alc268_ignore);
8374         if (err < 0)
8375                 return err;
8376         if (!spec->autocfg.line_outs)
8377                 return 0; /* can't find valid BIOS pin config */
8378
8379         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8380         if (err < 0)
8381                 return err;
8382         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8383         if (err < 0)
8384                 return err;
8385
8386         spec->multiout.max_channels = 2;
8387
8388         /* digital only support output */
8389         if (spec->autocfg.dig_out_pin)
8390                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8391
8392         if (spec->kctl_alloc)
8393                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8394
8395         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8396         spec->num_mux_defs = 1;
8397         spec->input_mux = &spec->private_imux;
8398
8399         return 1;
8400 }
8401
8402 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
8403 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
8404 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
8405
8406 /* init callback for auto-configuration model -- overriding the default init */
8407 static void alc268_auto_init(struct hda_codec *codec)
8408 {
8409         alc268_auto_init_multi_out(codec);
8410         alc268_auto_init_hp_out(codec);
8411         alc268_auto_init_mono_speaker_out(codec);
8412         alc268_auto_init_analog_input(codec);
8413 }
8414
8415 /*
8416  * configuration and preset
8417  */
8418 static const char *alc268_models[ALC268_MODEL_LAST] = {
8419         [ALC268_3ST]            = "3stack",
8420         [ALC268_AUTO]           = "auto",
8421 };
8422
8423 static struct snd_pci_quirk alc268_cfg_tbl[] = {
8424         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8425         {}
8426 };
8427
8428 static struct alc_config_preset alc268_presets[] = {
8429         [ALC268_3ST] = {
8430                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8431                 .init_verbs = { alc268_base_init_verbs },
8432                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8433                 .dac_nids = alc268_dac_nids,
8434                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8435                 .adc_nids = alc268_adc_nids_alt,
8436                 .hp_nid = 0x03,
8437                 .dig_out_nid = ALC268_DIGOUT_NID,
8438                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8439                 .channel_mode = alc268_modes,
8440                 .input_mux = &alc268_capture_source,
8441         },
8442 };
8443
8444 static int patch_alc268(struct hda_codec *codec)
8445 {
8446         struct alc_spec *spec;
8447         int board_config;
8448         int err;
8449
8450         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8451         if (spec == NULL)
8452                 return -ENOMEM;
8453
8454         codec->spec = spec;
8455
8456         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8457                                                   alc268_models,
8458                                                   alc268_cfg_tbl);
8459
8460         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8461                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8462                        "trying auto-probe from BIOS...\n");
8463                 board_config = ALC268_AUTO;
8464         }
8465
8466         if (board_config == ALC268_AUTO) {
8467                 /* automatic parse from the BIOS config */
8468                 err = alc268_parse_auto_config(codec);
8469                 if (err < 0) {
8470                         alc_free(codec);
8471                         return err;
8472                 } else if (!err) {
8473                         printk(KERN_INFO
8474                                "hda_codec: Cannot set up configuration "
8475                                "from BIOS.  Using base mode...\n");
8476                         board_config = ALC268_3ST;
8477                 }
8478         }
8479
8480         if (board_config != ALC268_AUTO)
8481                 setup_preset(spec, &alc268_presets[board_config]);
8482
8483         spec->stream_name_analog = "ALC268 Analog";
8484         spec->stream_analog_playback = &alc268_pcm_analog_playback;
8485         spec->stream_analog_capture = &alc268_pcm_analog_capture;
8486
8487         spec->stream_name_digital = "ALC268 Digital";
8488         spec->stream_digital_playback = &alc268_pcm_digital_playback;
8489
8490         if (board_config == ALC268_AUTO) {
8491                 if (!spec->adc_nids && spec->input_mux) {
8492                         /* check whether NID 0x07 is valid */
8493                         unsigned int wcap = get_wcaps(codec, 0x07);
8494
8495                         /* get type */
8496                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8497                         if (wcap != AC_WID_AUD_IN) {
8498                                 spec->adc_nids = alc268_adc_nids_alt;
8499                                 spec->num_adc_nids =
8500                                         ARRAY_SIZE(alc268_adc_nids_alt);
8501                                 spec->mixers[spec->num_mixers] =
8502                                         alc268_capture_alt_mixer;
8503                                 spec->num_mixers++;
8504                         } else {
8505                                 spec->adc_nids = alc268_adc_nids;
8506                                 spec->num_adc_nids =
8507                                         ARRAY_SIZE(alc268_adc_nids);
8508                                 spec->mixers[spec->num_mixers] =
8509                                         alc268_capture_mixer;
8510                                 spec->num_mixers++;
8511                         }
8512                 }
8513         }
8514         codec->patch_ops = alc_patch_ops;
8515         if (board_config == ALC268_AUTO)
8516                 spec->init_hook = alc268_auto_init;
8517                 
8518         return 0;
8519 }
8520
8521 /*
8522  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8523  */
8524
8525 /*
8526  * set the path ways for 2 channel output
8527  * need to set the codec line out and mic 1 pin widgets to inputs
8528  */
8529 static struct hda_verb alc861_threestack_ch2_init[] = {
8530         /* set pin widget 1Ah (line in) for input */
8531         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8532         /* set pin widget 18h (mic1/2) for input, for mic also enable
8533          * the vref
8534          */
8535         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8536
8537         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8538 #if 0
8539         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8540         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8541 #endif
8542         { } /* end */
8543 };
8544 /*
8545  * 6ch mode
8546  * need to set the codec line out and mic 1 pin widgets to outputs
8547  */
8548 static struct hda_verb alc861_threestack_ch6_init[] = {
8549         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8550         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8551         /* set pin widget 18h (mic1) for output (CLFE)*/
8552         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8553
8554         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8555         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8556
8557         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8558 #if 0
8559         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8560         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8561 #endif
8562         { } /* end */
8563 };
8564
8565 static struct hda_channel_mode alc861_threestack_modes[2] = {
8566         { 2, alc861_threestack_ch2_init },
8567         { 6, alc861_threestack_ch6_init },
8568 };
8569 /* Set mic1 as input and unmute the mixer */
8570 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8571         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8572         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8573         { } /* end */
8574 };
8575 /* Set mic1 as output and mute mixer */
8576 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8577         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8578         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8579         { } /* end */
8580 };
8581
8582 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8583         { 2, alc861_uniwill_m31_ch2_init },
8584         { 4, alc861_uniwill_m31_ch4_init },
8585 };
8586
8587 /* Set mic1 and line-in as input and unmute the mixer */
8588 static struct hda_verb alc861_asus_ch2_init[] = {
8589         /* set pin widget 1Ah (line in) for input */
8590         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8591         /* set pin widget 18h (mic1/2) for input, for mic also enable
8592          * the vref
8593          */
8594         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8595
8596         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8597 #if 0
8598         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8599         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8600 #endif
8601         { } /* end */
8602 };
8603 /* Set mic1 nad line-in as output and mute mixer */
8604 static struct hda_verb alc861_asus_ch6_init[] = {
8605         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8606         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8607         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8608         /* set pin widget 18h (mic1) for output (CLFE)*/
8609         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8610         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8611         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8612         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8613
8614         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8615 #if 0
8616         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8617         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8618 #endif
8619         { } /* end */
8620 };
8621
8622 static struct hda_channel_mode alc861_asus_modes[2] = {
8623         { 2, alc861_asus_ch2_init },
8624         { 6, alc861_asus_ch6_init },
8625 };
8626
8627 /* patch-ALC861 */
8628
8629 static struct snd_kcontrol_new alc861_base_mixer[] = {
8630         /* output mixer control */
8631         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8632         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8633         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8634         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8635         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8636
8637         /*Input mixer control */
8638         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8639            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8640         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8641         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8642         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8643         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8644         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8645         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8646         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8647         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8648
8649         /* Capture mixer control */
8650         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8651         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8652         {
8653                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8654                 .name = "Capture Source",
8655                 .count = 1,
8656                 .info = alc_mux_enum_info,
8657                 .get = alc_mux_enum_get,
8658                 .put = alc_mux_enum_put,
8659         },
8660         { } /* end */
8661 };
8662
8663 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8664         /* output mixer control */
8665         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8666         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8667         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8668         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8669         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8670
8671         /* Input mixer control */
8672         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8673            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8674         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8675         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8676         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8677         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8678         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8679         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8680         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8681         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8682
8683         /* Capture mixer control */
8684         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8685         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8686         {
8687                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8688                 .name = "Capture Source",
8689                 .count = 1,
8690                 .info = alc_mux_enum_info,
8691                 .get = alc_mux_enum_get,
8692                 .put = alc_mux_enum_put,
8693         },
8694         {
8695                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8696                 .name = "Channel Mode",
8697                 .info = alc_ch_mode_info,
8698                 .get = alc_ch_mode_get,
8699                 .put = alc_ch_mode_put,
8700                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
8701         },
8702         { } /* end */
8703 };
8704
8705 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8706         /* output mixer control */
8707         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8708         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8709         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8710         
8711         /*Capture mixer control */
8712         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8713         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8714         {
8715                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8716                 .name = "Capture Source",
8717                 .count = 1,
8718                 .info = alc_mux_enum_info,
8719                 .get = alc_mux_enum_get,
8720                 .put = alc_mux_enum_put,
8721         },
8722
8723         { } /* end */
8724 };
8725
8726 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8727         /* output mixer control */
8728         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8729         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8730         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8731         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8732         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8733
8734         /* Input mixer control */
8735         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8736            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8737         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8738         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8739         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8740         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8741         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8742         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8743         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8744         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8745
8746         /* Capture mixer control */
8747         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8748         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8749         {
8750                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8751                 .name = "Capture Source",
8752                 .count = 1,
8753                 .info = alc_mux_enum_info,
8754                 .get = alc_mux_enum_get,
8755                 .put = alc_mux_enum_put,
8756         },
8757         {
8758                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8759                 .name = "Channel Mode",
8760                 .info = alc_ch_mode_info,
8761                 .get = alc_ch_mode_get,
8762                 .put = alc_ch_mode_put,
8763                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8764         },
8765         { } /* end */
8766 };
8767
8768 static struct snd_kcontrol_new alc861_asus_mixer[] = {
8769         /* output mixer control */
8770         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8771         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8772         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8773         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8774         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8775
8776         /* Input mixer control */
8777         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8778         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8779         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8780         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8781         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8782         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8783         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8784         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8785         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8786         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
8787
8788         /* Capture mixer control */
8789         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8790         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8791         {
8792                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8793                 .name = "Capture Source",
8794                 .count = 1,
8795                 .info = alc_mux_enum_info,
8796                 .get = alc_mux_enum_get,
8797                 .put = alc_mux_enum_put,
8798         },
8799         {
8800                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8801                 .name = "Channel Mode",
8802                 .info = alc_ch_mode_info,
8803                 .get = alc_ch_mode_get,
8804                 .put = alc_ch_mode_put,
8805                 .private_value = ARRAY_SIZE(alc861_asus_modes),
8806         },
8807         { }
8808 };
8809
8810 /* additional mixer */
8811 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
8812         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8813         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8814         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
8815         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
8816         { }
8817 };
8818
8819 /*
8820  * generic initialization of ADC, input mixers and output mixers
8821  */
8822 static struct hda_verb alc861_base_init_verbs[] = {
8823         /*
8824          * Unmute ADC0 and set the default input to mic-in
8825          */
8826         /* port-A for surround (rear panel) */
8827         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8828         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
8829         /* port-B for mic-in (rear panel) with vref */
8830         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8831         /* port-C for line-in (rear panel) */
8832         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8833         /* port-D for Front */
8834         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8835         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8836         /* port-E for HP out (front panel) */
8837         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8838         /* route front PCM to HP */
8839         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8840         /* port-F for mic-in (front panel) with vref */
8841         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8842         /* port-G for CLFE (rear panel) */
8843         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8844         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8845         /* port-H for side (rear panel) */
8846         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8847         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
8848         /* CD-in */
8849         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8850         /* route front mic to ADC1*/
8851         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8852         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8853         
8854         /* Unmute DAC0~3 & spdif out*/
8855         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8856         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8857         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8858         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8859         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8860         
8861         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8862         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8863         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8864         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8865         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8866         
8867         /* Unmute Stereo Mixer 15 */
8868         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8869         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8870         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8871         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8872
8873         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8874         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8875         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8876         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8877         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8878         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8879         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8880         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8881         /* hp used DAC 3 (Front) */
8882         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8883         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8884
8885         { }
8886 };
8887
8888 static struct hda_verb alc861_threestack_init_verbs[] = {
8889         /*
8890          * Unmute ADC0 and set the default input to mic-in
8891          */
8892         /* port-A for surround (rear panel) */
8893         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8894         /* port-B for mic-in (rear panel) with vref */
8895         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8896         /* port-C for line-in (rear panel) */
8897         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8898         /* port-D for Front */
8899         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8900         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8901         /* port-E for HP out (front panel) */
8902         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8903         /* route front PCM to HP */
8904         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8905         /* port-F for mic-in (front panel) with vref */
8906         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8907         /* port-G for CLFE (rear panel) */
8908         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8909         /* port-H for side (rear panel) */
8910         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8911         /* CD-in */
8912         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8913         /* route front mic to ADC1*/
8914         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8915         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8916         /* Unmute DAC0~3 & spdif out*/
8917         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8918         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8919         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8920         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8921         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8922         
8923         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8924         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8925         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8926         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8927         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8928         
8929         /* Unmute Stereo Mixer 15 */
8930         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8931         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8932         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8933         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8934
8935         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8936         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8937         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8938         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8939         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8940         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8941         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8942         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8943         /* hp used DAC 3 (Front) */
8944         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8945         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8946         { }
8947 };
8948
8949 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
8950         /*
8951          * Unmute ADC0 and set the default input to mic-in
8952          */
8953         /* port-A for surround (rear panel) */
8954         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8955         /* port-B for mic-in (rear panel) with vref */
8956         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8957         /* port-C for line-in (rear panel) */
8958         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8959         /* port-D for Front */
8960         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8961         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8962         /* port-E for HP out (front panel) */
8963         /* this has to be set to VREF80 */
8964         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8965         /* route front PCM to HP */
8966         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8967         /* port-F for mic-in (front panel) with vref */
8968         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8969         /* port-G for CLFE (rear panel) */
8970         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8971         /* port-H for side (rear panel) */
8972         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8973         /* CD-in */
8974         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8975         /* route front mic to ADC1*/
8976         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8977         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8978         /* Unmute DAC0~3 & spdif out*/
8979         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8980         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8981         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8982         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8983         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8984         
8985         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8986         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8987         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8988         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8989         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8990         
8991         /* Unmute Stereo Mixer 15 */
8992         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8993         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8994         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8995         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8996
8997         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8998         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8999         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9000         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9001         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9002         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9003         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9004         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9005         /* hp used DAC 3 (Front) */
9006         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9007         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9008         { }
9009 };
9010
9011 static struct hda_verb alc861_asus_init_verbs[] = {
9012         /*
9013          * Unmute ADC0 and set the default input to mic-in
9014          */
9015         /* port-A for surround (rear panel)
9016          * according to codec#0 this is the HP jack
9017          */
9018         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9019         /* route front PCM to HP */
9020         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9021         /* port-B for mic-in (rear panel) with vref */
9022         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9023         /* port-C for line-in (rear panel) */
9024         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9025         /* port-D for Front */
9026         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9027         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9028         /* port-E for HP out (front panel) */
9029         /* this has to be set to VREF80 */
9030         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9031         /* route front PCM to HP */
9032         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9033         /* port-F for mic-in (front panel) with vref */
9034         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9035         /* port-G for CLFE (rear panel) */
9036         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9037         /* port-H for side (rear panel) */
9038         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9039         /* CD-in */
9040         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9041         /* route front mic to ADC1*/
9042         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9043         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9044         /* Unmute DAC0~3 & spdif out*/
9045         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9046         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9047         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9048         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9049         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9050         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9051         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9052         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9053         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9054         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9055         
9056         /* Unmute Stereo Mixer 15 */
9057         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9058         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9059         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9060         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9061
9062         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9063         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9064         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9066         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9067         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9068         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9070         /* hp used DAC 3 (Front) */
9071         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9072         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9073         { }
9074 };
9075
9076 /* additional init verbs for ASUS laptops */
9077 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9078         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9079         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9080         { }
9081 };
9082
9083 /*
9084  * generic initialization of ADC, input mixers and output mixers
9085  */
9086 static struct hda_verb alc861_auto_init_verbs[] = {
9087         /*
9088          * Unmute ADC0 and set the default input to mic-in
9089          */
9090         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9091         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9092         
9093         /* Unmute DAC0~3 & spdif out*/
9094         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9095         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9096         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9097         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9098         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9099         
9100         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9101         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9102         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9103         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9104         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9105         
9106         /* Unmute Stereo Mixer 15 */
9107         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9108         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9109         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9110         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9111
9112         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9113         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9114         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9115         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9116         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9117         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9118         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9119         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9120
9121         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9122         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9123         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9124         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9125         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9126         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9127         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9128         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9129
9130         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
9131
9132         { }
9133 };
9134
9135 static struct hda_verb alc861_toshiba_init_verbs[] = {
9136         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9137
9138         { }
9139 };
9140
9141 /* toggle speaker-output according to the hp-jack state */
9142 static void alc861_toshiba_automute(struct hda_codec *codec)
9143 {
9144         unsigned int present;
9145
9146         present = snd_hda_codec_read(codec, 0x0f, 0,
9147                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9148         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
9149                                  0x80, present ? 0x80 : 0);
9150         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
9151                                  0x80, present ? 0x80 : 0);
9152         snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
9153                                  0x80, present ? 0 : 0x80);
9154         snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
9155                                  0x80, present ? 0 : 0x80);
9156 }
9157
9158 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9159                                        unsigned int res)
9160 {
9161         if ((res >> 26) == ALC880_HP_EVENT)
9162                 alc861_toshiba_automute(codec);
9163 }
9164
9165 /* pcm configuration: identiacal with ALC880 */
9166 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
9167 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
9168 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
9169 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
9170
9171
9172 #define ALC861_DIGOUT_NID       0x07
9173
9174 static struct hda_channel_mode alc861_8ch_modes[1] = {
9175         { 8, NULL }
9176 };
9177
9178 static hda_nid_t alc861_dac_nids[4] = {
9179         /* front, surround, clfe, side */
9180         0x03, 0x06, 0x05, 0x04
9181 };
9182
9183 static hda_nid_t alc660_dac_nids[3] = {
9184         /* front, clfe, surround */
9185         0x03, 0x05, 0x06
9186 };
9187
9188 static hda_nid_t alc861_adc_nids[1] = {
9189         /* ADC0-2 */
9190         0x08,
9191 };
9192
9193 static struct hda_input_mux alc861_capture_source = {
9194         .num_items = 5,
9195         .items = {
9196                 { "Mic", 0x0 },
9197                 { "Front Mic", 0x3 },
9198                 { "Line", 0x1 },
9199                 { "CD", 0x4 },
9200                 { "Mixer", 0x5 },
9201         },
9202 };
9203
9204 /* fill in the dac_nids table from the parsed pin configuration */
9205 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9206                                      const struct auto_pin_cfg *cfg)
9207 {
9208         int i;
9209         hda_nid_t nid;
9210
9211         spec->multiout.dac_nids = spec->private_dac_nids;
9212         for (i = 0; i < cfg->line_outs; i++) {
9213                 nid = cfg->line_out_pins[i];
9214                 if (nid) {
9215                         if (i >= ARRAY_SIZE(alc861_dac_nids))
9216                                 continue;
9217                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9218                 }
9219         }
9220         spec->multiout.num_dacs = cfg->line_outs;
9221         return 0;
9222 }
9223
9224 /* add playback controls from the parsed DAC table */
9225 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9226                                              const struct auto_pin_cfg *cfg)
9227 {
9228         char name[32];
9229         static const char *chname[4] = {
9230                 "Front", "Surround", NULL /*CLFE*/, "Side"
9231         };
9232         hda_nid_t nid;
9233         int i, idx, err;
9234
9235         for (i = 0; i < cfg->line_outs; i++) {
9236                 nid = spec->multiout.dac_nids[i];
9237                 if (!nid)
9238                         continue;
9239                 if (nid == 0x05) {
9240                         /* Center/LFE */
9241                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9242                                           "Center Playback Switch",
9243                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9244                                                               HDA_OUTPUT));
9245                         if (err < 0)
9246                                 return err;
9247                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9248                                           "LFE Playback Switch",
9249                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9250                                                               HDA_OUTPUT));
9251                         if (err < 0)
9252                                 return err;
9253                 } else {
9254                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9255                              idx++)
9256                                 if (nid == alc861_dac_nids[idx])
9257                                         break;
9258                         sprintf(name, "%s Playback Switch", chname[idx]);
9259                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9260                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9261                                                               HDA_OUTPUT));
9262                         if (err < 0)
9263                                 return err;
9264                 }
9265         }
9266         return 0;
9267 }
9268
9269 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9270 {
9271         int err;
9272         hda_nid_t nid;
9273
9274         if (!pin)
9275                 return 0;
9276
9277         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9278                 nid = 0x03;
9279                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9280                                   "Headphone Playback Switch",
9281                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9282                 if (err < 0)
9283                         return err;
9284                 spec->multiout.hp_nid = nid;
9285         }
9286         return 0;
9287 }
9288
9289 /* create playback/capture controls for input pins */
9290 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9291                                                 const struct auto_pin_cfg *cfg)
9292 {
9293         struct hda_input_mux *imux = &spec->private_imux;
9294         int i, err, idx, idx1;
9295
9296         for (i = 0; i < AUTO_PIN_LAST; i++) {
9297                 switch (cfg->input_pins[i]) {
9298                 case 0x0c:
9299                         idx1 = 1;
9300                         idx = 2;        /* Line In */
9301                         break;
9302                 case 0x0f:
9303                         idx1 = 2;
9304                         idx = 2;        /* Line In */
9305                         break;
9306                 case 0x0d:
9307                         idx1 = 0;
9308                         idx = 1;        /* Mic In */
9309                         break;
9310                 case 0x10:
9311                         idx1 = 3;
9312                         idx = 1;        /* Mic In */
9313                         break;
9314                 case 0x11:
9315                         idx1 = 4;
9316                         idx = 0;        /* CD */
9317                         break;
9318                 default:
9319                         continue;
9320                 }
9321
9322                 err = new_analog_input(spec, cfg->input_pins[i],
9323                                        auto_pin_cfg_labels[i], idx, 0x15);
9324                 if (err < 0)
9325                         return err;
9326
9327                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9328                 imux->items[imux->num_items].index = idx1;
9329                 imux->num_items++;
9330         }
9331         return 0;
9332 }
9333
9334 static struct snd_kcontrol_new alc861_capture_mixer[] = {
9335         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9336         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9337
9338         {
9339                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9340                 /* The multiple "Capture Source" controls confuse alsamixer
9341                  * So call somewhat different..
9342                  *FIXME: the controls appear in the "playback" view!
9343                  */
9344                 /* .name = "Capture Source", */
9345                 .name = "Input Source",
9346                 .count = 1,
9347                 .info = alc_mux_enum_info,
9348                 .get = alc_mux_enum_get,
9349                 .put = alc_mux_enum_put,
9350         },
9351         { } /* end */
9352 };
9353
9354 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9355                                               hda_nid_t nid,
9356                                               int pin_type, int dac_idx)
9357 {
9358         /* set as output */
9359
9360         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9361                             pin_type);
9362         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9363                             AMP_OUT_UNMUTE);
9364
9365 }
9366
9367 static void alc861_auto_init_multi_out(struct hda_codec *codec)
9368 {
9369         struct alc_spec *spec = codec->spec;
9370         int i;
9371
9372         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9373         for (i = 0; i < spec->autocfg.line_outs; i++) {
9374                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9375                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9376                 if (nid)
9377                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9378                                                           spec->multiout.dac_nids[i]);
9379         }
9380 }
9381
9382 static void alc861_auto_init_hp_out(struct hda_codec *codec)
9383 {
9384         struct alc_spec *spec = codec->spec;
9385         hda_nid_t pin;
9386
9387         pin = spec->autocfg.hp_pins[0];
9388         if (pin) /* connect to front */
9389                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9390                                                   spec->multiout.dac_nids[0]);
9391 }
9392
9393 static void alc861_auto_init_analog_input(struct hda_codec *codec)
9394 {
9395         struct alc_spec *spec = codec->spec;
9396         int i;
9397
9398         for (i = 0; i < AUTO_PIN_LAST; i++) {
9399                 hda_nid_t nid = spec->autocfg.input_pins[i];
9400                 if (nid >= 0x0c && nid <= 0x11) {
9401                         snd_hda_codec_write(codec, nid, 0,
9402                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
9403                                             i <= AUTO_PIN_FRONT_MIC ?
9404                                             PIN_VREF80 : PIN_IN);
9405                 }
9406         }
9407 }
9408
9409 /* parse the BIOS configuration and set up the alc_spec */
9410 /* return 1 if successful, 0 if the proper config is not found,
9411  * or a negative error code
9412  */
9413 static int alc861_parse_auto_config(struct hda_codec *codec)
9414 {
9415         struct alc_spec *spec = codec->spec;
9416         int err;
9417         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9418
9419         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9420                                            alc861_ignore);
9421         if (err < 0)
9422                 return err;
9423         if (!spec->autocfg.line_outs)
9424                 return 0; /* can't find valid BIOS pin config */
9425
9426         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9427         if (err < 0)
9428                 return err;
9429         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9430         if (err < 0)
9431                 return err;
9432         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9433         if (err < 0)
9434                 return err;
9435         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9436         if (err < 0)
9437                 return err;
9438
9439         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9440
9441         if (spec->autocfg.dig_out_pin)
9442                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9443
9444         if (spec->kctl_alloc)
9445                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9446
9447         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9448
9449         spec->num_mux_defs = 1;
9450         spec->input_mux = &spec->private_imux;
9451
9452         spec->adc_nids = alc861_adc_nids;
9453         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9454         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9455         spec->num_mixers++;
9456
9457         return 1;
9458 }
9459
9460 /* additional initialization for auto-configuration model */
9461 static void alc861_auto_init(struct hda_codec *codec)
9462 {
9463         alc861_auto_init_multi_out(codec);
9464         alc861_auto_init_hp_out(codec);
9465         alc861_auto_init_analog_input(codec);
9466 }
9467
9468
9469 /*
9470  * configuration and preset
9471  */
9472 static const char *alc861_models[ALC861_MODEL_LAST] = {
9473         [ALC861_3ST]            = "3stack",
9474         [ALC660_3ST]            = "3stack-660",
9475         [ALC861_3ST_DIG]        = "3stack-dig",
9476         [ALC861_6ST_DIG]        = "6stack-dig",
9477         [ALC861_UNIWILL_M31]    = "uniwill-m31",
9478         [ALC861_TOSHIBA]        = "toshiba",
9479         [ALC861_ASUS]           = "asus",
9480         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
9481         [ALC861_AUTO]           = "auto",
9482 };
9483
9484 static struct snd_pci_quirk alc861_cfg_tbl[] = {
9485         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9486         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9487         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9488         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9489         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9490         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9491         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9492         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9493         SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
9494         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9495         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9496         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9497         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9498         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9499         {}
9500 };
9501
9502 static struct alc_config_preset alc861_presets[] = {
9503         [ALC861_3ST] = {
9504                 .mixers = { alc861_3ST_mixer },
9505                 .init_verbs = { alc861_threestack_init_verbs },
9506                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9507                 .dac_nids = alc861_dac_nids,
9508                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9509                 .channel_mode = alc861_threestack_modes,
9510                 .need_dac_fix = 1,
9511                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9512                 .adc_nids = alc861_adc_nids,
9513                 .input_mux = &alc861_capture_source,
9514         },
9515         [ALC861_3ST_DIG] = {
9516                 .mixers = { alc861_base_mixer },
9517                 .init_verbs = { alc861_threestack_init_verbs },
9518                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9519                 .dac_nids = alc861_dac_nids,
9520                 .dig_out_nid = ALC861_DIGOUT_NID,
9521                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9522                 .channel_mode = alc861_threestack_modes,
9523                 .need_dac_fix = 1,
9524                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9525                 .adc_nids = alc861_adc_nids,
9526                 .input_mux = &alc861_capture_source,
9527         },
9528         [ALC861_6ST_DIG] = {
9529                 .mixers = { alc861_base_mixer },
9530                 .init_verbs = { alc861_base_init_verbs },
9531                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9532                 .dac_nids = alc861_dac_nids,
9533                 .dig_out_nid = ALC861_DIGOUT_NID,
9534                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9535                 .channel_mode = alc861_8ch_modes,
9536                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9537                 .adc_nids = alc861_adc_nids,
9538                 .input_mux = &alc861_capture_source,
9539         },
9540         [ALC660_3ST] = {
9541                 .mixers = { alc861_3ST_mixer },
9542                 .init_verbs = { alc861_threestack_init_verbs },
9543                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
9544                 .dac_nids = alc660_dac_nids,
9545                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9546                 .channel_mode = alc861_threestack_modes,
9547                 .need_dac_fix = 1,
9548                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9549                 .adc_nids = alc861_adc_nids,
9550                 .input_mux = &alc861_capture_source,
9551         },
9552         [ALC861_UNIWILL_M31] = {
9553                 .mixers = { alc861_uniwill_m31_mixer },
9554                 .init_verbs = { alc861_uniwill_m31_init_verbs },
9555                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9556                 .dac_nids = alc861_dac_nids,
9557                 .dig_out_nid = ALC861_DIGOUT_NID,
9558                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9559                 .channel_mode = alc861_uniwill_m31_modes,
9560                 .need_dac_fix = 1,
9561                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9562                 .adc_nids = alc861_adc_nids,
9563                 .input_mux = &alc861_capture_source,
9564         },
9565         [ALC861_TOSHIBA] = {
9566                 .mixers = { alc861_toshiba_mixer },
9567                 .init_verbs = { alc861_base_init_verbs,
9568                                 alc861_toshiba_init_verbs },
9569                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9570                 .dac_nids = alc861_dac_nids,
9571                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9572                 .channel_mode = alc883_3ST_2ch_modes,
9573                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9574                 .adc_nids = alc861_adc_nids,
9575                 .input_mux = &alc861_capture_source,
9576                 .unsol_event = alc861_toshiba_unsol_event,
9577                 .init_hook = alc861_toshiba_automute,
9578         },
9579         [ALC861_ASUS] = {
9580                 .mixers = { alc861_asus_mixer },
9581                 .init_verbs = { alc861_asus_init_verbs },
9582                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9583                 .dac_nids = alc861_dac_nids,
9584                 .dig_out_nid = ALC861_DIGOUT_NID,
9585                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9586                 .channel_mode = alc861_asus_modes,
9587                 .need_dac_fix = 1,
9588                 .hp_nid = 0x06,
9589                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9590                 .adc_nids = alc861_adc_nids,
9591                 .input_mux = &alc861_capture_source,
9592         },
9593         [ALC861_ASUS_LAPTOP] = {
9594                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9595                 .init_verbs = { alc861_asus_init_verbs,
9596                                 alc861_asus_laptop_init_verbs },
9597                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9598                 .dac_nids = alc861_dac_nids,
9599                 .dig_out_nid = ALC861_DIGOUT_NID,
9600                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9601                 .channel_mode = alc883_3ST_2ch_modes,
9602                 .need_dac_fix = 1,
9603                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9604                 .adc_nids = alc861_adc_nids,
9605                 .input_mux = &alc861_capture_source,
9606         },
9607 };
9608
9609
9610 static int patch_alc861(struct hda_codec *codec)
9611 {
9612         struct alc_spec *spec;
9613         int board_config;
9614         int err;
9615
9616         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9617         if (spec == NULL)
9618                 return -ENOMEM;
9619
9620         codec->spec = spec;
9621
9622         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9623                                                   alc861_models,
9624                                                   alc861_cfg_tbl);
9625
9626         if (board_config < 0) {
9627                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9628                        "trying auto-probe from BIOS...\n");
9629                 board_config = ALC861_AUTO;
9630         }
9631
9632         if (board_config == ALC861_AUTO) {
9633                 /* automatic parse from the BIOS config */
9634                 err = alc861_parse_auto_config(codec);
9635                 if (err < 0) {
9636                         alc_free(codec);
9637                         return err;
9638                 } else if (!err) {
9639                         printk(KERN_INFO
9640                                "hda_codec: Cannot set up configuration "
9641                                "from BIOS.  Using base mode...\n");
9642                    board_config = ALC861_3ST_DIG;
9643                 }
9644         }
9645
9646         if (board_config != ALC861_AUTO)
9647                 setup_preset(spec, &alc861_presets[board_config]);
9648
9649         spec->stream_name_analog = "ALC861 Analog";
9650         spec->stream_analog_playback = &alc861_pcm_analog_playback;
9651         spec->stream_analog_capture = &alc861_pcm_analog_capture;
9652
9653         spec->stream_name_digital = "ALC861 Digital";
9654         spec->stream_digital_playback = &alc861_pcm_digital_playback;
9655         spec->stream_digital_capture = &alc861_pcm_digital_capture;
9656
9657         codec->patch_ops = alc_patch_ops;
9658         if (board_config == ALC861_AUTO)
9659                 spec->init_hook = alc861_auto_init;
9660                 
9661         return 0;
9662 }
9663
9664 /*
9665  * ALC861-VD support
9666  *
9667  * Based on ALC882
9668  *
9669  * In addition, an independent DAC
9670  */
9671 #define ALC861VD_DIGOUT_NID     0x06
9672
9673 static hda_nid_t alc861vd_dac_nids[4] = {
9674         /* front, surr, clfe, side surr */
9675         0x02, 0x03, 0x04, 0x05
9676 };
9677
9678 /* dac_nids for ALC660vd are in a different order - according to
9679  * Realtek's driver.
9680  * This should probably tesult in a different mixer for 6stack models
9681  * of ALC660vd codecs, but for now there is only 3stack mixer
9682  * - and it is the same as in 861vd.
9683  * adc_nids in ALC660vd are (is) the same as in 861vd
9684  */
9685 static hda_nid_t alc660vd_dac_nids[3] = {
9686         /* front, rear, clfe, rear_surr */
9687         0x02, 0x04, 0x03
9688 };
9689
9690 static hda_nid_t alc861vd_adc_nids[1] = {
9691         /* ADC0 */
9692         0x09,
9693 };
9694
9695 /* input MUX */
9696 /* FIXME: should be a matrix-type input source selection */
9697 static struct hda_input_mux alc861vd_capture_source = {
9698         .num_items = 4,
9699         .items = {
9700                 { "Mic", 0x0 },
9701                 { "Front Mic", 0x1 },
9702                 { "Line", 0x2 },
9703                 { "CD", 0x4 },
9704         },
9705 };
9706
9707 static struct hda_input_mux alc861vd_dallas_capture_source = {
9708         .num_items = 3,
9709         .items = {
9710                 { "Front Mic", 0x0 },
9711                 { "ATAPI Mic", 0x1 },
9712                 { "Line In", 0x5 },
9713         },
9714 };
9715
9716 #define alc861vd_mux_enum_info alc_mux_enum_info
9717 #define alc861vd_mux_enum_get alc_mux_enum_get
9718
9719 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9720                                 struct snd_ctl_elem_value *ucontrol)
9721 {
9722         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9723         struct alc_spec *spec = codec->spec;
9724         const struct hda_input_mux *imux = spec->input_mux;
9725         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9726         static hda_nid_t capture_mixers[1] = { 0x22 };
9727         hda_nid_t nid = capture_mixers[adc_idx];
9728         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9729         unsigned int i, idx;
9730
9731         idx = ucontrol->value.enumerated.item[0];
9732         if (idx >= imux->num_items)
9733                 idx = imux->num_items - 1;
9734         if (*cur_val == idx && !codec->in_resume)
9735                 return 0;
9736         for (i = 0; i < imux->num_items; i++) {
9737                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
9738                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9739                                     v | (imux->items[i].index << 8));
9740         }
9741         *cur_val = idx;
9742         return 1;
9743 }
9744
9745 /*
9746  * 2ch mode
9747  */
9748 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9749         { 2, NULL }
9750 };
9751
9752 /*
9753  * 6ch mode
9754  */
9755 static struct hda_verb alc861vd_6stack_ch6_init[] = {
9756         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9757         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9758         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9759         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9760         { } /* end */
9761 };
9762
9763 /*
9764  * 8ch mode
9765  */
9766 static struct hda_verb alc861vd_6stack_ch8_init[] = {
9767         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9768         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9769         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9770         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9771         { } /* end */
9772 };
9773
9774 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
9775         { 6, alc861vd_6stack_ch6_init },
9776         { 8, alc861vd_6stack_ch8_init },
9777 };
9778
9779 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
9780         {
9781                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9782                 .name = "Channel Mode",
9783                 .info = alc_ch_mode_info,
9784                 .get = alc_ch_mode_get,
9785                 .put = alc_ch_mode_put,
9786         },
9787         { } /* end */
9788 };
9789
9790 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
9791         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9792         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9793
9794         {
9795                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9796                 /* The multiple "Capture Source" controls confuse alsamixer
9797                  * So call somewhat different..
9798                  *FIXME: the controls appear in the "playback" view!
9799                  */
9800                 /* .name = "Capture Source", */
9801                 .name = "Input Source",
9802                 .count = 1,
9803                 .info = alc861vd_mux_enum_info,
9804                 .get = alc861vd_mux_enum_get,
9805                 .put = alc861vd_mux_enum_put,
9806         },
9807         { } /* end */
9808 };
9809
9810 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9811  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9812  */
9813 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
9814         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9815         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9816
9817         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9818         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9819
9820         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
9821                                 HDA_OUTPUT),
9822         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
9823                                 HDA_OUTPUT),
9824         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9825         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9826
9827         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
9828         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9829
9830         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9831
9832         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9833         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9834         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9835
9836         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9837         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9838         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9839
9840         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9841         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9842
9843         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9844         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9845
9846         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9847         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9848
9849         { } /* end */
9850 };
9851
9852 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
9853         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9854         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9855
9856         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9857
9858         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9859         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9860         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9861
9862         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9863         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9864         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9865
9866         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9867         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9868
9869         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9870         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9871
9872         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9873         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9874
9875         { } /* end */
9876 };
9877
9878 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
9879         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9880         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
9881         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9882
9883         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9884
9885         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9886         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9887         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9888
9889         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9890         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9891         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9892
9893         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9894         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9895
9896         { } /* end */
9897 };
9898
9899 /* Pin assignment: Front=0x14, HP = 0x15,
9900  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
9901  */
9902 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
9903         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9904         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9905         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9906         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
9907         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9908         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9909         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9910         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9911         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
9912         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
9913         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9914         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9915         {
9916                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9917                 /* .name = "Capture Source", */
9918                 .name = "Input Source",
9919                 .count = 1,
9920                 .info = alc882_mux_enum_info,
9921                 .get = alc882_mux_enum_get,
9922                 .put = alc882_mux_enum_put,
9923         },
9924         { } /* end */
9925 };
9926
9927 /*
9928  * generic initialization of ADC, input mixers and output mixers
9929  */
9930 static struct hda_verb alc861vd_volume_init_verbs[] = {
9931         /*
9932          * Unmute ADC0 and set the default input to mic-in
9933          */
9934         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9935         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9936
9937         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
9938          * the analog-loopback mixer widget
9939          */
9940         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9941         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9942         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9943         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9944         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9945         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9946
9947         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
9948         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9949         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9950         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9951         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9952
9953         /*
9954          * Set up output mixers (0x02 - 0x05)
9955          */
9956         /* set vol=0 to output mixers */
9957         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9958         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9959         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9960         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9961
9962         /* set up input amps for analog loopback */
9963         /* Amp Indices: DAC = 0, mixer = 1 */
9964         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9965         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9966         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9967         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9968         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9969         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9970         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9971         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9972
9973         { }
9974 };
9975
9976 /*
9977  * 3-stack pin configuration:
9978  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
9979  */
9980 static struct hda_verb alc861vd_3stack_init_verbs[] = {
9981         /*
9982          * Set pin mode and muting
9983          */
9984         /* set front pin widgets 0x14 for output */
9985         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9986         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9987         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9988
9989         /* Mic (rear) pin: input vref at 80% */
9990         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9991         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9992         /* Front Mic pin: input vref at 80% */
9993         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9994         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9995         /* Line In pin: input */
9996         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9997         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9998         /* Line-2 In: Headphone output (output 0 - 0x0c) */
9999         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10000         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10001         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10002         /* CD pin widget for input */
10003         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10004
10005         { }
10006 };
10007
10008 /*
10009  * 6-stack pin configuration:
10010  */
10011 static struct hda_verb alc861vd_6stack_init_verbs[] = {
10012         /*
10013          * Set pin mode and muting
10014          */
10015         /* set front pin widgets 0x14 for output */
10016         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10017         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10018         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10019
10020         /* Rear Pin: output 1 (0x0d) */
10021         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10022         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10023         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10024         /* CLFE Pin: output 2 (0x0e) */
10025         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10026         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10027         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10028         /* Side Pin: output 3 (0x0f) */
10029         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10030         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10031         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10032
10033         /* Mic (rear) pin: input vref at 80% */
10034         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10035         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10036         /* Front Mic pin: input vref at 80% */
10037         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10038         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10039         /* Line In pin: input */
10040         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10041         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10042         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10043         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10044         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10045         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10046         /* CD pin widget for input */
10047         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10048
10049         { }
10050 };
10051
10052 static struct hda_verb alc861vd_eapd_verbs[] = {
10053         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10054         { }
10055 };
10056
10057 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10058         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10059         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10060         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10061         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10062         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
10063         {}
10064 };
10065
10066 /* toggle speaker-output according to the hp-jack state */
10067 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10068 {
10069         unsigned int present;
10070         unsigned char bits;
10071
10072         present = snd_hda_codec_read(codec, 0x1b, 0,
10073                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10074         bits = present ? 0x80 : 0;
10075         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10076                                  0x80, bits);
10077         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10078                                  0x80, bits);
10079 }
10080
10081 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10082 {
10083         unsigned int present;
10084         unsigned char bits;
10085
10086         present = snd_hda_codec_read(codec, 0x18, 0,
10087                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10088         bits = present ? 0x80 : 0;
10089         snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
10090                                  0x80, bits);
10091         snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
10092                                  0x80, bits);
10093 }
10094
10095 static void alc861vd_lenovo_automute(struct hda_codec *codec)
10096 {
10097         alc861vd_lenovo_hp_automute(codec);
10098         alc861vd_lenovo_mic_automute(codec);
10099 }
10100
10101 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10102                                         unsigned int res)
10103 {
10104         switch (res >> 26) {
10105         case ALC880_HP_EVENT:
10106                 alc861vd_lenovo_hp_automute(codec);
10107                 break;
10108         case ALC880_MIC_EVENT:
10109                 alc861vd_lenovo_mic_automute(codec);
10110                 break;
10111         }
10112 }
10113
10114 static struct hda_verb alc861vd_dallas_verbs[] = {
10115         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10116         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10117         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10118         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10119
10120         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10121         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10122         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10123         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10124         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10125         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10126         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10127         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10128         
10129         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10130         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10131         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10132         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10133         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10134         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10135         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10136         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10137
10138         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10139         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10140         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10141         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10142         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10143         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10144         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10145         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10146
10147         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10148         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10149         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10150         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10151
10152         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10153         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
10154         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10155
10156         { } /* end */
10157 };
10158
10159 /* toggle speaker-output according to the hp-jack state */
10160 static void alc861vd_dallas_automute(struct hda_codec *codec)
10161 {
10162         unsigned int present;
10163
10164         present = snd_hda_codec_read(codec, 0x15, 0,
10165                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10166         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10167                                  0x80, present ? 0x80 : 0);
10168         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10169                                  0x80, present ? 0x80 : 0);
10170 }
10171
10172 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10173 {
10174         if ((res >> 26) == ALC880_HP_EVENT)
10175                 alc861vd_dallas_automute(codec);
10176 }
10177
10178 /* pcm configuration: identiacal with ALC880 */
10179 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
10180 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
10181 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
10182 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
10183
10184 /*
10185  * configuration and preset
10186  */
10187 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10188         [ALC660VD_3ST]          = "3stack-660",
10189         [ALC660VD_3ST_DIG]= "3stack-660-digout",
10190         [ALC861VD_3ST]          = "3stack",
10191         [ALC861VD_3ST_DIG]      = "3stack-digout",
10192         [ALC861VD_6ST_DIG]      = "6stack-digout",
10193         [ALC861VD_LENOVO]       = "lenovo",
10194         [ALC861VD_DALLAS]       = "dallas",
10195         [ALC861VD_AUTO]         = "auto",
10196 };
10197
10198 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10199         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10200         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10201         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10202         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10203         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10204
10205         SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10206         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10207         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10208         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10209         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10210         {}
10211 };
10212
10213 static struct alc_config_preset alc861vd_presets[] = {
10214         [ALC660VD_3ST] = {
10215                 .mixers = { alc861vd_3st_mixer },
10216                 .init_verbs = { alc861vd_volume_init_verbs,
10217                                  alc861vd_3stack_init_verbs },
10218                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10219                 .dac_nids = alc660vd_dac_nids,
10220                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10221                 .adc_nids = alc861vd_adc_nids,
10222                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10223                 .channel_mode = alc861vd_3stack_2ch_modes,
10224                 .input_mux = &alc861vd_capture_source,
10225         },
10226         [ALC660VD_3ST_DIG] = {
10227                 .mixers = { alc861vd_3st_mixer },
10228                 .init_verbs = { alc861vd_volume_init_verbs,
10229                                  alc861vd_3stack_init_verbs },
10230                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10231                 .dac_nids = alc660vd_dac_nids,
10232                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10233                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10234                 .adc_nids = alc861vd_adc_nids,
10235                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10236                 .channel_mode = alc861vd_3stack_2ch_modes,
10237                 .input_mux = &alc861vd_capture_source,
10238         },
10239         [ALC861VD_3ST] = {
10240                 .mixers = { alc861vd_3st_mixer },
10241                 .init_verbs = { alc861vd_volume_init_verbs,
10242                                  alc861vd_3stack_init_verbs },
10243                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10244                 .dac_nids = alc861vd_dac_nids,
10245                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10246                 .channel_mode = alc861vd_3stack_2ch_modes,
10247                 .input_mux = &alc861vd_capture_source,
10248         },
10249         [ALC861VD_3ST_DIG] = {
10250                 .mixers = { alc861vd_3st_mixer },
10251                 .init_verbs = { alc861vd_volume_init_verbs,
10252                                  alc861vd_3stack_init_verbs },
10253                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10254                 .dac_nids = alc861vd_dac_nids,
10255                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10256                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10257                 .channel_mode = alc861vd_3stack_2ch_modes,
10258                 .input_mux = &alc861vd_capture_source,
10259         },
10260         [ALC861VD_6ST_DIG] = {
10261                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10262                 .init_verbs = { alc861vd_volume_init_verbs,
10263                                 alc861vd_6stack_init_verbs },
10264                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10265                 .dac_nids = alc861vd_dac_nids,
10266                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10267                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10268                 .channel_mode = alc861vd_6stack_modes,
10269                 .input_mux = &alc861vd_capture_source,
10270         },
10271         [ALC861VD_LENOVO] = {
10272                 .mixers = { alc861vd_lenovo_mixer },
10273                 .init_verbs = { alc861vd_volume_init_verbs,
10274                                 alc861vd_3stack_init_verbs,
10275                                 alc861vd_eapd_verbs,
10276                                 alc861vd_lenovo_unsol_verbs },
10277                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10278                 .dac_nids = alc660vd_dac_nids,
10279                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10280                 .adc_nids = alc861vd_adc_nids,
10281                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10282                 .channel_mode = alc861vd_3stack_2ch_modes,
10283                 .input_mux = &alc861vd_capture_source,
10284                 .unsol_event = alc861vd_lenovo_unsol_event,
10285                 .init_hook = alc861vd_lenovo_automute,
10286         },
10287         [ALC861VD_DALLAS] = {
10288                 .mixers = { alc861vd_dallas_mixer },
10289                 .init_verbs = { alc861vd_dallas_verbs },
10290                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10291                 .dac_nids = alc861vd_dac_nids,
10292                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10293                 .adc_nids = alc861vd_adc_nids,
10294                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10295                 .channel_mode = alc861vd_3stack_2ch_modes,
10296                 .input_mux = &alc861vd_dallas_capture_source,
10297                 .unsol_event = alc861vd_dallas_unsol_event,
10298                 .init_hook = alc861vd_dallas_automute,
10299         },      
10300 };
10301
10302 /*
10303  * BIOS auto configuration
10304  */
10305 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10306                                 hda_nid_t nid, int pin_type, int dac_idx)
10307 {
10308         /* set as output */
10309         snd_hda_codec_write(codec, nid, 0,
10310                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10311         snd_hda_codec_write(codec, nid, 0,
10312                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10313 }
10314
10315 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10316 {
10317         struct alc_spec *spec = codec->spec;
10318         int i;
10319
10320         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10321         for (i = 0; i <= HDA_SIDE; i++) {
10322                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10323                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10324                 if (nid)
10325                         alc861vd_auto_set_output_and_unmute(codec, nid,
10326                                                             pin_type, i);
10327         }
10328 }
10329
10330
10331 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10332 {
10333         struct alc_spec *spec = codec->spec;
10334         hda_nid_t pin;
10335
10336         pin = spec->autocfg.hp_pins[0];
10337         if (pin) /* connect to front and  use dac 0 */
10338                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10339 }
10340
10341 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
10342 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
10343
10344 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10345 {
10346         struct alc_spec *spec = codec->spec;
10347         int i;
10348
10349         for (i = 0; i < AUTO_PIN_LAST; i++) {
10350                 hda_nid_t nid = spec->autocfg.input_pins[i];
10351                 if (alc861vd_is_input_pin(nid)) {
10352                         snd_hda_codec_write(codec, nid, 0,
10353                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
10354                                         i <= AUTO_PIN_FRONT_MIC ?
10355                                                         PIN_VREF80 : PIN_IN);
10356                         if (nid != ALC861VD_PIN_CD_NID)
10357                                 snd_hda_codec_write(codec, nid, 0,
10358                                                 AC_VERB_SET_AMP_GAIN_MUTE,
10359                                                 AMP_OUT_MUTE);
10360                 }
10361         }
10362 }
10363
10364 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
10365 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
10366
10367 /* add playback controls from the parsed DAC table */
10368 /* Based on ALC880 version. But ALC861VD has separate,
10369  * different NIDs for mute/unmute switch and volume control */
10370 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10371                                              const struct auto_pin_cfg *cfg)
10372 {
10373         char name[32];
10374         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10375         hda_nid_t nid_v, nid_s;
10376         int i, err;
10377
10378         for (i = 0; i < cfg->line_outs; i++) {
10379                 if (!spec->multiout.dac_nids[i])
10380                         continue;
10381                 nid_v = alc861vd_idx_to_mixer_vol(
10382                                 alc880_dac_to_idx(
10383                                         spec->multiout.dac_nids[i]));
10384                 nid_s = alc861vd_idx_to_mixer_switch(
10385                                 alc880_dac_to_idx(
10386                                         spec->multiout.dac_nids[i]));
10387
10388                 if (i == 2) {
10389                         /* Center/LFE */
10390                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10391                                           "Center Playback Volume",
10392                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10393                                                               HDA_OUTPUT));
10394                         if (err < 0)
10395                                 return err;
10396                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10397                                           "LFE Playback Volume",
10398                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10399                                                               HDA_OUTPUT));
10400                         if (err < 0)
10401                                 return err;
10402                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10403                                           "Center Playback Switch",
10404                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10405                                                               HDA_INPUT));
10406                         if (err < 0)
10407                                 return err;
10408                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10409                                           "LFE Playback Switch",
10410                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10411                                                               HDA_INPUT));
10412                         if (err < 0)
10413                                 return err;
10414                 } else {
10415                         sprintf(name, "%s Playback Volume", chname[i]);
10416                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10417                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10418                                                               HDA_OUTPUT));
10419                         if (err < 0)
10420                                 return err;
10421                         sprintf(name, "%s Playback Switch", chname[i]);
10422                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10423                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10424                                                               HDA_INPUT));
10425                         if (err < 0)
10426                                 return err;
10427                 }
10428         }
10429         return 0;
10430 }
10431
10432 /* add playback controls for speaker and HP outputs */
10433 /* Based on ALC880 version. But ALC861VD has separate,
10434  * different NIDs for mute/unmute switch and volume control */
10435 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10436                                         hda_nid_t pin, const char *pfx)
10437 {
10438         hda_nid_t nid_v, nid_s;
10439         int err;
10440         char name[32];
10441
10442         if (!pin)
10443                 return 0;
10444
10445         if (alc880_is_fixed_pin(pin)) {
10446                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10447                 /* specify the DAC as the extra output */
10448                 if (!spec->multiout.hp_nid)
10449                         spec->multiout.hp_nid = nid_v;
10450                 else
10451                         spec->multiout.extra_out_nid[0] = nid_v;
10452                 /* control HP volume/switch on the output mixer amp */
10453                 nid_v = alc861vd_idx_to_mixer_vol(
10454                                 alc880_fixed_pin_idx(pin));
10455                 nid_s = alc861vd_idx_to_mixer_switch(
10456                                 alc880_fixed_pin_idx(pin));
10457
10458                 sprintf(name, "%s Playback Volume", pfx);
10459                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10460                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10461                 if (err < 0)
10462                         return err;
10463                 sprintf(name, "%s Playback Switch", pfx);
10464                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10465                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10466                 if (err < 0)
10467                         return err;
10468         } else if (alc880_is_multi_pin(pin)) {
10469                 /* set manual connection */
10470                 /* we have only a switch on HP-out PIN */
10471                 sprintf(name, "%s Playback Switch", pfx);
10472                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10473                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10474                 if (err < 0)
10475                         return err;
10476         }
10477         return 0;
10478 }
10479
10480 /* parse the BIOS configuration and set up the alc_spec
10481  * return 1 if successful, 0 if the proper config is not found,
10482  * or a negative error code
10483  * Based on ALC880 version - had to change it to override
10484  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10485 static int alc861vd_parse_auto_config(struct hda_codec *codec)
10486 {
10487         struct alc_spec *spec = codec->spec;
10488         int err;
10489         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10490
10491         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10492                                            alc861vd_ignore);
10493         if (err < 0)
10494                 return err;
10495         if (!spec->autocfg.line_outs)
10496                 return 0; /* can't find valid BIOS pin config */
10497
10498         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10499         if (err < 0)
10500                 return err;
10501         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10502         if (err < 0)
10503                 return err;
10504         err = alc861vd_auto_create_extra_out(spec,
10505                                              spec->autocfg.speaker_pins[0],
10506                                              "Speaker");
10507         if (err < 0)
10508                 return err;
10509         err = alc861vd_auto_create_extra_out(spec,
10510                                              spec->autocfg.hp_pins[0],
10511                                              "Headphone");
10512         if (err < 0)
10513                 return err;
10514         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10515         if (err < 0)
10516                 return err;
10517
10518         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10519
10520         if (spec->autocfg.dig_out_pin)
10521                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10522
10523         if (spec->kctl_alloc)
10524                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10525
10526         spec->init_verbs[spec->num_init_verbs++]
10527                 = alc861vd_volume_init_verbs;
10528
10529         spec->num_mux_defs = 1;
10530         spec->input_mux = &spec->private_imux;
10531
10532         return 1;
10533 }
10534
10535 /* additional initialization for auto-configuration model */
10536 static void alc861vd_auto_init(struct hda_codec *codec)
10537 {
10538         alc861vd_auto_init_multi_out(codec);
10539         alc861vd_auto_init_hp_out(codec);
10540         alc861vd_auto_init_analog_input(codec);
10541 }
10542
10543 static int patch_alc861vd(struct hda_codec *codec)
10544 {
10545         struct alc_spec *spec;
10546         int err, board_config;
10547
10548         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10549         if (spec == NULL)
10550                 return -ENOMEM;
10551
10552         codec->spec = spec;
10553
10554         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10555                                                   alc861vd_models,
10556                                                   alc861vd_cfg_tbl);
10557
10558         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10559                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10560                         "ALC861VD, trying auto-probe from BIOS...\n");
10561                 board_config = ALC861VD_AUTO;
10562         }
10563
10564         if (board_config == ALC861VD_AUTO) {
10565                 /* automatic parse from the BIOS config */
10566                 err = alc861vd_parse_auto_config(codec);
10567                 if (err < 0) {
10568                         alc_free(codec);
10569                         return err;
10570                 } else if (!err) {
10571                         printk(KERN_INFO
10572                                "hda_codec: Cannot set up configuration "
10573                                "from BIOS.  Using base mode...\n");
10574                         board_config = ALC861VD_3ST;
10575                 }
10576         }
10577
10578         if (board_config != ALC861VD_AUTO)
10579                 setup_preset(spec, &alc861vd_presets[board_config]);
10580
10581         spec->stream_name_analog = "ALC861VD Analog";
10582         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10583         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10584
10585         spec->stream_name_digital = "ALC861VD Digital";
10586         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10587         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10588
10589         spec->adc_nids = alc861vd_adc_nids;
10590         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10591
10592         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10593         spec->num_mixers++;
10594
10595         codec->patch_ops = alc_patch_ops;
10596
10597         if (board_config == ALC861VD_AUTO)
10598                 spec->init_hook = alc861vd_auto_init;
10599
10600         return 0;
10601 }
10602
10603 /*
10604  * ALC662 support
10605  *
10606  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10607  * configuration.  Each pin widget can choose any input DACs and a mixer.
10608  * Each ADC is connected from a mixer of all inputs.  This makes possible
10609  * 6-channel independent captures.
10610  *
10611  * In addition, an independent DAC for the multi-playback (not used in this
10612  * driver yet).
10613  */
10614 #define ALC662_DIGOUT_NID       0x06
10615 #define ALC662_DIGIN_NID        0x0a
10616
10617 static hda_nid_t alc662_dac_nids[4] = {
10618         /* front, rear, clfe, rear_surr */
10619         0x02, 0x03, 0x04
10620 };
10621
10622 static hda_nid_t alc662_adc_nids[1] = {
10623         /* ADC1-2 */
10624         0x09,
10625 };
10626 /* input MUX */
10627 /* FIXME: should be a matrix-type input source selection */
10628
10629 static struct hda_input_mux alc662_capture_source = {
10630         .num_items = 4,
10631         .items = {
10632                 { "Mic", 0x0 },
10633                 { "Front Mic", 0x1 },
10634                 { "Line", 0x2 },
10635                 { "CD", 0x4 },
10636         },
10637 };
10638
10639 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10640         .num_items = 2,
10641         .items = {
10642                 { "Mic", 0x1 },
10643                 { "Line", 0x2 },
10644         },
10645 };
10646 #define alc662_mux_enum_info alc_mux_enum_info
10647 #define alc662_mux_enum_get alc_mux_enum_get
10648
10649 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10650                                struct snd_ctl_elem_value *ucontrol)
10651 {
10652         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10653         struct alc_spec *spec = codec->spec;
10654         const struct hda_input_mux *imux = spec->input_mux;
10655         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10656         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
10657         hda_nid_t nid = capture_mixers[adc_idx];
10658         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10659         unsigned int i, idx;
10660
10661         idx = ucontrol->value.enumerated.item[0];
10662         if (idx >= imux->num_items)
10663                 idx = imux->num_items - 1;
10664         if (*cur_val == idx && !codec->in_resume)
10665                 return 0;
10666         for (i = 0; i < imux->num_items; i++) {
10667                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
10668                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10669                                     v | (imux->items[i].index << 8));
10670         }
10671         *cur_val = idx;
10672         return 1;
10673 }
10674 /*
10675  * 2ch mode
10676  */
10677 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10678         { 2, NULL }
10679 };
10680
10681 /*
10682  * 2ch mode
10683  */
10684 static struct hda_verb alc662_3ST_ch2_init[] = {
10685         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10686         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10687         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10688         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10689         { } /* end */
10690 };
10691
10692 /*
10693  * 6ch mode
10694  */
10695 static struct hda_verb alc662_3ST_ch6_init[] = {
10696         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10697         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10698         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10699         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10700         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10701         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10702         { } /* end */
10703 };
10704
10705 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10706         { 2, alc662_3ST_ch2_init },
10707         { 6, alc662_3ST_ch6_init },
10708 };
10709
10710 /*
10711  * 2ch mode
10712  */
10713 static struct hda_verb alc662_sixstack_ch6_init[] = {
10714         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10715         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10716         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10717         { } /* end */
10718 };
10719
10720 /*
10721  * 6ch mode
10722  */
10723 static struct hda_verb alc662_sixstack_ch8_init[] = {
10724         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10725         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10726         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10727         { } /* end */
10728 };
10729
10730 static struct hda_channel_mode alc662_5stack_modes[2] = {
10731         { 2, alc662_sixstack_ch6_init },
10732         { 6, alc662_sixstack_ch8_init },
10733 };
10734
10735 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10736  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10737  */
10738
10739 static struct snd_kcontrol_new alc662_base_mixer[] = {
10740         /* output mixer control */
10741         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10742         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
10743         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10744         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10745         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10746         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10747         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10748         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10749         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10750
10751         /*Input mixer control */
10752         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
10753         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
10754         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
10755         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
10756         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
10757         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
10758         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
10759         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
10760
10761         /* Capture mixer control */
10762         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10763         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10764         {
10765                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10766                 .name = "Capture Source",
10767                 .count = 1,
10768                 .info = alc_mux_enum_info,
10769                 .get = alc_mux_enum_get,
10770                 .put = alc_mux_enum_put,
10771         },
10772         { } /* end */
10773 };
10774
10775 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
10776         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10777         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10778         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10779         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10780         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10781         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10782         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10783         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10784         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10785         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10786         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10787         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10788         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10789         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10790         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10791         {
10792                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10793                 /* .name = "Capture Source", */
10794                 .name = "Input Source",
10795                 .count = 1,
10796                 .info = alc662_mux_enum_info,
10797                 .get = alc662_mux_enum_get,
10798                 .put = alc662_mux_enum_put,
10799         },
10800         { } /* end */
10801 };
10802
10803 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
10804         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10805         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10806         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10807         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
10808         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10809         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10810         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10811         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10812         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10813         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10814         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10815         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10816         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10817         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10818         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10819         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10820         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10821         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10822         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10823         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10824         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10825         {
10826                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10827                 /* .name = "Capture Source", */
10828                 .name = "Input Source",
10829                 .count = 1,
10830                 .info = alc662_mux_enum_info,
10831                 .get = alc662_mux_enum_get,
10832                 .put = alc662_mux_enum_put,
10833         },
10834         { } /* end */
10835 };
10836
10837 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
10838         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10839         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10840         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10841         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
10842         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10843         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10844         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10845         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10846         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10847         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10848         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10849         {
10850                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10851                 /* .name = "Capture Source", */
10852                 .name = "Input Source",
10853                 .count = 1,
10854                 .info = alc662_mux_enum_info,
10855                 .get = alc662_mux_enum_get,
10856                 .put = alc662_mux_enum_put,
10857         },
10858         { } /* end */
10859 };
10860
10861 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
10862         {
10863                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10864                 .name = "Channel Mode",
10865                 .info = alc_ch_mode_info,
10866                 .get = alc_ch_mode_get,
10867                 .put = alc_ch_mode_put,
10868         },
10869         { } /* end */
10870 };
10871
10872 static struct hda_verb alc662_init_verbs[] = {
10873         /* ADC: mute amp left and right */
10874         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10875         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10876         /* Front mixer: unmute input/output amp left and right (volume = 0) */
10877
10878         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10879         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10880         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10881         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10882         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10883
10884         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10885         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10886         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10887         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10888         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10889         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10890
10891         /* Front Pin: output 0 (0x0c) */
10892         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10893         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10894
10895         /* Rear Pin: output 1 (0x0d) */
10896         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10897         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10898
10899         /* CLFE Pin: output 2 (0x0e) */
10900         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10901         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10902
10903         /* Mic (rear) pin: input vref at 80% */
10904         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10905         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10906         /* Front Mic pin: input vref at 80% */
10907         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10908         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10909         /* Line In pin: input */
10910         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10911         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10912         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10913         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10914         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10915         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10916         /* CD pin widget for input */
10917         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10918
10919         /* FIXME: use matrix-type input source selection */
10920         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10921         /* Input mixer */
10922         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10923         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10924         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10925         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10926         { }
10927 };
10928
10929 static struct hda_verb alc662_sue_init_verbs[] = {
10930         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
10931         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
10932         {}
10933 };
10934
10935 /*
10936  * generic initialization of ADC, input mixers and output mixers
10937  */
10938 static struct hda_verb alc662_auto_init_verbs[] = {
10939         /*
10940          * Unmute ADC and set the default input to mic-in
10941          */
10942         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10943         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10944
10945         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10946          * mixer widget
10947          * Note: PASD motherboards uses the Line In 2 as the input for front
10948          * panel mic (mic 2)
10949          */
10950         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10951         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10952         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10953         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10954         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10955         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10956
10957         /*
10958          * Set up output mixers (0x0c - 0x0f)
10959          */
10960         /* set vol=0 to output mixers */
10961         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10962         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10963         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10964
10965         /* set up input amps for analog loopback */
10966         /* Amp Indices: DAC = 0, mixer = 1 */
10967         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10968         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10969         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10970         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10971         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10972         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10973
10974
10975         /* FIXME: use matrix-type input source selection */
10976         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10977         /* Input mixer */
10978         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10979         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10980         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10981         /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
10982         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10983
10984         { }
10985 };
10986
10987 /* capture mixer elements */
10988 static struct snd_kcontrol_new alc662_capture_mixer[] = {
10989         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10990         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10991         {
10992                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10993                 /* The multiple "Capture Source" controls confuse alsamixer
10994                  * So call somewhat different..
10995                  * FIXME: the controls appear in the "playback" view!
10996                  */
10997                 /* .name = "Capture Source", */
10998                 .name = "Input Source",
10999                 .count = 1,
11000                 .info = alc882_mux_enum_info,
11001                 .get = alc882_mux_enum_get,
11002                 .put = alc882_mux_enum_put,
11003         },
11004         { } /* end */
11005 };
11006
11007 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11008 {
11009         unsigned int present;
11010         unsigned char bits;
11011
11012         present = snd_hda_codec_read(codec, 0x14, 0,
11013                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11014         bits = present ? 0x80 : 0;
11015         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11016                                  0x80, bits);
11017         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11018                                  0x80, bits);
11019 }
11020
11021 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11022 {
11023         unsigned int present;
11024         unsigned char bits;
11025
11026         present = snd_hda_codec_read(codec, 0x1b, 0,
11027                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11028         bits = present ? 0x80 : 0;
11029         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11030                                  0x80, bits);
11031         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11032                                  0x80, bits);
11033         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11034                                  0x80, bits);
11035         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11036                                  0x80, bits);
11037 }
11038
11039 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11040                                            unsigned int res)
11041 {
11042         if ((res >> 26) == ALC880_HP_EVENT)
11043                 alc662_lenovo_101e_all_automute(codec);
11044         if ((res >> 26) == ALC880_FRONT_EVENT)
11045                 alc662_lenovo_101e_ispeaker_automute(codec);
11046 }
11047
11048
11049 /* pcm configuration: identiacal with ALC880 */
11050 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
11051 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
11052 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
11053 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
11054
11055 /*
11056  * configuration and preset
11057  */
11058 static const char *alc662_models[ALC662_MODEL_LAST] = {
11059         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
11060         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
11061         [ALC662_3ST_6ch]        = "3stack-6ch",
11062         [ALC662_5ST_DIG]        = "6stack-dig",
11063         [ALC662_LENOVO_101E]    = "lenovo-101e",
11064         [ALC662_AUTO]           = "auto",
11065 };
11066
11067 static struct snd_pci_quirk alc662_cfg_tbl[] = {
11068         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11069         {}
11070 };
11071
11072 static struct alc_config_preset alc662_presets[] = {
11073         [ALC662_3ST_2ch_DIG] = {
11074                 .mixers = { alc662_3ST_2ch_mixer },
11075                 .init_verbs = { alc662_init_verbs },
11076                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11077                 .dac_nids = alc662_dac_nids,
11078                 .dig_out_nid = ALC662_DIGOUT_NID,
11079                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11080                 .adc_nids = alc662_adc_nids,
11081                 .dig_in_nid = ALC662_DIGIN_NID,
11082                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11083                 .channel_mode = alc662_3ST_2ch_modes,
11084                 .input_mux = &alc662_capture_source,
11085         },
11086         [ALC662_3ST_6ch_DIG] = {
11087                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11088                 .init_verbs = { alc662_init_verbs },
11089                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11090                 .dac_nids = alc662_dac_nids,
11091                 .dig_out_nid = ALC662_DIGOUT_NID,
11092                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11093                 .adc_nids = alc662_adc_nids,
11094                 .dig_in_nid = ALC662_DIGIN_NID,
11095                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11096                 .channel_mode = alc662_3ST_6ch_modes,
11097                 .need_dac_fix = 1,
11098                 .input_mux = &alc662_capture_source,
11099         },
11100         [ALC662_3ST_6ch] = {
11101                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11102                 .init_verbs = { alc662_init_verbs },
11103                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11104                 .dac_nids = alc662_dac_nids,
11105                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11106                 .adc_nids = alc662_adc_nids,
11107                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11108                 .channel_mode = alc662_3ST_6ch_modes,
11109                 .need_dac_fix = 1,
11110                 .input_mux = &alc662_capture_source,
11111         },
11112         [ALC662_5ST_DIG] = {
11113                 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
11114                 .init_verbs = { alc662_init_verbs },
11115                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11116                 .dac_nids = alc662_dac_nids,
11117                 .dig_out_nid = ALC662_DIGOUT_NID,
11118                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11119                 .adc_nids = alc662_adc_nids,
11120                 .dig_in_nid = ALC662_DIGIN_NID,
11121                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11122                 .channel_mode = alc662_5stack_modes,
11123                 .input_mux = &alc662_capture_source,
11124         },
11125         [ALC662_LENOVO_101E] = {
11126                 .mixers = { alc662_lenovo_101e_mixer },
11127                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11128                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11129                 .dac_nids = alc662_dac_nids,
11130                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11131                 .adc_nids = alc662_adc_nids,
11132                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11133                 .channel_mode = alc662_3ST_2ch_modes,
11134                 .input_mux = &alc662_lenovo_101e_capture_source,
11135                 .unsol_event = alc662_lenovo_101e_unsol_event,
11136                 .init_hook = alc662_lenovo_101e_all_automute,
11137         },
11138
11139 };
11140
11141
11142 /*
11143  * BIOS auto configuration
11144  */
11145
11146 /* add playback controls from the parsed DAC table */
11147 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11148                                              const struct auto_pin_cfg *cfg)
11149 {
11150         char name[32];
11151         static const char *chname[4] = {
11152                 "Front", "Surround", NULL /*CLFE*/, "Side"
11153         };
11154         hda_nid_t nid;
11155         int i, err;
11156
11157         for (i = 0; i < cfg->line_outs; i++) {
11158                 if (!spec->multiout.dac_nids[i])
11159                         continue;
11160                 nid = alc880_idx_to_mixer(i);
11161                 if (i == 2) {
11162                         /* Center/LFE */
11163                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11164                                           "Center Playback Volume",
11165                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11166                                                               HDA_OUTPUT));
11167                         if (err < 0)
11168                                 return err;
11169                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11170                                           "LFE Playback Volume",
11171                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11172                                                               HDA_OUTPUT));
11173                         if (err < 0)
11174                                 return err;
11175                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11176                                           "Center Playback Switch",
11177                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11178                                                               HDA_INPUT));
11179                         if (err < 0)
11180                                 return err;
11181                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11182                                           "LFE Playback Switch",
11183                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11184                                                               HDA_INPUT));
11185                         if (err < 0)
11186                                 return err;
11187                 } else {
11188                         sprintf(name, "%s Playback Volume", chname[i]);
11189                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11190                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11191                                                               HDA_OUTPUT));
11192                         if (err < 0)
11193                                 return err;
11194                         sprintf(name, "%s Playback Switch", chname[i]);
11195                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11196                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11197                                                               HDA_INPUT));
11198                         if (err < 0)
11199                                 return err;
11200                 }
11201         }
11202         return 0;
11203 }
11204
11205 /* add playback controls for speaker and HP outputs */
11206 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11207                                         const char *pfx)
11208 {
11209         hda_nid_t nid;
11210         int err;
11211         char name[32];
11212
11213         if (!pin)
11214                 return 0;
11215
11216         if (alc880_is_fixed_pin(pin)) {
11217                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11218                 /* printk("DAC nid=%x\n",nid); */
11219                 /* specify the DAC as the extra output */
11220                 if (!spec->multiout.hp_nid)
11221                         spec->multiout.hp_nid = nid;
11222                 else
11223                         spec->multiout.extra_out_nid[0] = nid;
11224                 /* control HP volume/switch on the output mixer amp */
11225                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11226                 sprintf(name, "%s Playback Volume", pfx);
11227                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11228                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11229                 if (err < 0)
11230                         return err;
11231                 sprintf(name, "%s Playback Switch", pfx);
11232                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11233                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11234                 if (err < 0)
11235                         return err;
11236         } else if (alc880_is_multi_pin(pin)) {
11237                 /* set manual connection */
11238                 /* we have only a switch on HP-out PIN */
11239                 sprintf(name, "%s Playback Switch", pfx);
11240                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11241                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11242                 if (err < 0)
11243                         return err;
11244         }
11245         return 0;
11246 }
11247
11248 /* create playback/capture controls for input pins */
11249 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11250                                                 const struct auto_pin_cfg *cfg)
11251 {
11252         struct hda_input_mux *imux = &spec->private_imux;
11253         int i, err, idx;
11254
11255         for (i = 0; i < AUTO_PIN_LAST; i++) {
11256                 if (alc880_is_input_pin(cfg->input_pins[i])) {
11257                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
11258                         err = new_analog_input(spec, cfg->input_pins[i],
11259                                                auto_pin_cfg_labels[i],
11260                                                idx, 0x0b);
11261                         if (err < 0)
11262                                 return err;
11263                         imux->items[imux->num_items].label =
11264                                 auto_pin_cfg_labels[i];
11265                         imux->items[imux->num_items].index =
11266                                 alc880_input_pin_idx(cfg->input_pins[i]);
11267                         imux->num_items++;
11268                 }
11269         }
11270         return 0;
11271 }
11272
11273 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11274                                               hda_nid_t nid, int pin_type,
11275                                               int dac_idx)
11276 {
11277         /* set as output */
11278         snd_hda_codec_write(codec, nid, 0,
11279                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11280         snd_hda_codec_write(codec, nid, 0,
11281                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11282         /* need the manual connection? */
11283         if (alc880_is_multi_pin(nid)) {
11284                 struct alc_spec *spec = codec->spec;
11285                 int idx = alc880_multi_pin_idx(nid);
11286                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11287                                     AC_VERB_SET_CONNECT_SEL,
11288                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11289         }
11290 }
11291
11292 static void alc662_auto_init_multi_out(struct hda_codec *codec)
11293 {
11294         struct alc_spec *spec = codec->spec;
11295         int i;
11296
11297         for (i = 0; i <= HDA_SIDE; i++) {
11298                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11299                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11300                 if (nid)
11301                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11302                                                           i);
11303         }
11304 }
11305
11306 static void alc662_auto_init_hp_out(struct hda_codec *codec)
11307 {
11308         struct alc_spec *spec = codec->spec;
11309         hda_nid_t pin;
11310
11311         pin = spec->autocfg.hp_pins[0];
11312         if (pin) /* connect to front */
11313                 /* use dac 0 */
11314                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11315 }
11316
11317 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
11318 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
11319
11320 static void alc662_auto_init_analog_input(struct hda_codec *codec)
11321 {
11322         struct alc_spec *spec = codec->spec;
11323         int i;
11324
11325         for (i = 0; i < AUTO_PIN_LAST; i++) {
11326                 hda_nid_t nid = spec->autocfg.input_pins[i];
11327                 if (alc662_is_input_pin(nid)) {
11328                         snd_hda_codec_write(codec, nid, 0,
11329                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
11330                                             (i <= AUTO_PIN_FRONT_MIC ?
11331                                              PIN_VREF80 : PIN_IN));
11332                         if (nid != ALC662_PIN_CD_NID)
11333                                 snd_hda_codec_write(codec, nid, 0,
11334                                                     AC_VERB_SET_AMP_GAIN_MUTE,
11335                                                     AMP_OUT_MUTE);
11336                 }
11337         }
11338 }
11339
11340 static int alc662_parse_auto_config(struct hda_codec *codec)
11341 {
11342         struct alc_spec *spec = codec->spec;
11343         int err;
11344         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11345
11346         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11347                                            alc662_ignore);
11348         if (err < 0)
11349                 return err;
11350         if (!spec->autocfg.line_outs)
11351                 return 0; /* can't find valid BIOS pin config */
11352
11353         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11354         if (err < 0)
11355                 return err;
11356         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11357         if (err < 0)
11358                 return err;
11359         err = alc662_auto_create_extra_out(spec,
11360                                            spec->autocfg.speaker_pins[0],
11361                                            "Speaker");
11362         if (err < 0)
11363                 return err;
11364         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11365                                            "Headphone");
11366         if (err < 0)
11367                 return err;
11368         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11369         if (err < 0)
11370                 return err;
11371
11372         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11373
11374         if (spec->autocfg.dig_out_pin)
11375                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11376
11377         if (spec->kctl_alloc)
11378                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11379
11380         spec->num_mux_defs = 1;
11381         spec->input_mux = &spec->private_imux;
11382         
11383         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11384         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11385         spec->num_mixers++;
11386         return 1;
11387 }
11388
11389 /* additional initialization for auto-configuration model */
11390 static void alc662_auto_init(struct hda_codec *codec)
11391 {
11392         alc662_auto_init_multi_out(codec);
11393         alc662_auto_init_hp_out(codec);
11394         alc662_auto_init_analog_input(codec);
11395 }
11396
11397 static int patch_alc662(struct hda_codec *codec)
11398 {
11399         struct alc_spec *spec;
11400         int err, board_config;
11401
11402         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11403         if (!spec)
11404                 return -ENOMEM;
11405
11406         codec->spec = spec;
11407
11408         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11409                                                   alc662_models,
11410                                                   alc662_cfg_tbl);
11411         if (board_config < 0) {
11412                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11413                        "trying auto-probe from BIOS...\n");
11414                 board_config = ALC662_AUTO;
11415         }
11416
11417         if (board_config == ALC662_AUTO) {
11418                 /* automatic parse from the BIOS config */
11419                 err = alc662_parse_auto_config(codec);
11420                 if (err < 0) {
11421                         alc_free(codec);
11422                         return err;
11423                 } else if (!err) {
11424                         printk(KERN_INFO
11425                                "hda_codec: Cannot set up configuration "
11426                                "from BIOS.  Using base mode...\n");
11427                         board_config = ALC662_3ST_2ch_DIG;
11428                 }
11429         }
11430
11431         if (board_config != ALC662_AUTO)
11432                 setup_preset(spec, &alc662_presets[board_config]);
11433
11434         spec->stream_name_analog = "ALC662 Analog";
11435         spec->stream_analog_playback = &alc662_pcm_analog_playback;
11436         spec->stream_analog_capture = &alc662_pcm_analog_capture;
11437
11438         spec->stream_name_digital = "ALC662 Digital";
11439         spec->stream_digital_playback = &alc662_pcm_digital_playback;
11440         spec->stream_digital_capture = &alc662_pcm_digital_capture;
11441
11442         if (!spec->adc_nids && spec->input_mux) {
11443                 spec->adc_nids = alc662_adc_nids;
11444                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11445         }
11446
11447         codec->patch_ops = alc_patch_ops;
11448         if (board_config == ALC662_AUTO)
11449                 spec->init_hook = alc662_auto_init;
11450
11451         return 0;
11452 }
11453
11454 /*
11455  * patch entries
11456  */
11457 struct hda_codec_preset snd_hda_preset_realtek[] = {
11458         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11459         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11460         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11461         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11462           .patch = patch_alc861 },
11463         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11464         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11465         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11466         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11467           .patch = patch_alc883 },
11468         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11469           .patch = patch_alc662 },
11470         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11471         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11472         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11473         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11474         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11475         {} /* terminator */
11476 };