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