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