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