]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - sound/pci/hda/patch_realtek.c
[ALSA] hda-intel: support for iMac 24'' released on 09/2006
[linux-2.6.git] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_BENQ_ED8,
96         ALC262_SONY_ASSAMD,
97         ALC262_BENQ_T31,
98         ALC262_AUTO,
99         ALC262_MODEL_LAST /* last tag */
100 };
101
102 /* ALC268 models */
103 enum {
104         ALC268_3ST,
105         ALC268_AUTO,
106         ALC268_MODEL_LAST /* last tag */
107 };
108
109 /* ALC861 models */
110 enum {
111         ALC861_3ST,
112         ALC660_3ST,
113         ALC861_3ST_DIG,
114         ALC861_6ST_DIG,
115         ALC861_UNIWILL_M31,
116         ALC861_TOSHIBA,
117         ALC861_ASUS,
118         ALC861_ASUS_LAPTOP,
119         ALC861_AUTO,
120         ALC861_MODEL_LAST,
121 };
122
123 /* ALC861-VD models */
124 enum {
125         ALC660VD_3ST,
126         ALC660VD_3ST_DIG,
127         ALC861VD_3ST,
128         ALC861VD_3ST_DIG,
129         ALC861VD_6ST_DIG,
130         ALC861VD_LENOVO,
131         ALC861VD_DALLAS,
132         ALC861VD_AUTO,
133         ALC861VD_MODEL_LAST,
134 };
135
136 /* ALC662 models */
137 enum {
138         ALC662_3ST_2ch_DIG,
139         ALC662_3ST_6ch_DIG,
140         ALC662_3ST_6ch,
141         ALC662_5ST_DIG,
142         ALC662_LENOVO_101E,
143         ALC662_AUTO,
144         ALC662_MODEL_LAST,
145 };
146
147 /* ALC882 models */
148 enum {
149         ALC882_3ST_DIG,
150         ALC882_6ST_DIG,
151         ALC882_ARIMA,
152         ALC882_W2JC,
153         ALC882_TARGA,
154         ALC882_ASUS_A7J,
155         ALC885_MACPRO,
156         ALC885_IMAC24,
157         ALC882_AUTO,
158         ALC882_MODEL_LAST,
159 };
160
161 /* ALC883 models */
162 enum {
163         ALC883_3ST_2ch_DIG,
164         ALC883_3ST_6ch_DIG,
165         ALC883_3ST_6ch,
166         ALC883_6ST_DIG,
167         ALC883_TARGA_DIG,
168         ALC883_TARGA_2ch_DIG,
169         ALC883_ACER,
170         ALC883_MEDION,
171         ALC883_MEDION_MD2,      
172         ALC883_LAPTOP_EAPD,
173         ALC883_LENOVO_101E_2ch,
174         ALC883_LENOVO_NB0763,
175         ALC888_LENOVO_MS7195_DIG,               
176         ALC888_6ST_HP,
177         ALC888_3ST_HP,
178         ALC883_AUTO,
179         ALC883_MODEL_LAST,
180 };
181
182 /* for GPIO Poll */
183 #define GPIO_MASK       0x03
184
185 struct alc_spec {
186         /* codec parameterization */
187         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
188         unsigned int num_mixers;
189
190         const struct hda_verb *init_verbs[5];   /* initialization verbs
191                                                  * don't forget NULL
192                                                  * termination!
193                                                  */
194         unsigned int num_init_verbs;
195
196         char *stream_name_analog;       /* analog PCM stream */
197         struct hda_pcm_stream *stream_analog_playback;
198         struct hda_pcm_stream *stream_analog_capture;
199
200         char *stream_name_digital;      /* digital PCM stream */
201         struct hda_pcm_stream *stream_digital_playback;
202         struct hda_pcm_stream *stream_digital_capture;
203
204         /* playback */
205         struct hda_multi_out multiout;  /* playback set-up
206                                          * max_channels, dacs must be set
207                                          * dig_out_nid and hp_nid are optional
208                                          */
209
210         /* capture */
211         unsigned int num_adc_nids;
212         hda_nid_t *adc_nids;
213         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
214
215         /* capture source */
216         unsigned int num_mux_defs;
217         const struct hda_input_mux *input_mux;
218         unsigned int cur_mux[3];
219
220         /* channel model */
221         const struct hda_channel_mode *channel_mode;
222         int num_channel_mode;
223         int need_dac_fix;
224
225         /* PCM information */
226         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
227
228         /* dynamic controls, init_verbs and input_mux */
229         struct auto_pin_cfg autocfg;
230         unsigned int num_kctl_alloc, num_kctl_used;
231         struct snd_kcontrol_new *kctl_alloc;
232         struct hda_input_mux private_imux;
233         hda_nid_t private_dac_nids[5];
234
235         /* hooks */
236         void (*init_hook)(struct hda_codec *codec);
237         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
238
239         /* for pin sensing */
240         unsigned int sense_updated: 1;
241         unsigned int jack_present: 1;
242 };
243
244 /*
245  * configuration template - to be copied to the spec instance
246  */
247 struct alc_config_preset {
248         struct snd_kcontrol_new *mixers[5]; /* should be identical size
249                                              * with spec
250                                              */
251         const struct hda_verb *init_verbs[5];
252         unsigned int num_dacs;
253         hda_nid_t *dac_nids;
254         hda_nid_t dig_out_nid;          /* optional */
255         hda_nid_t hp_nid;               /* optional */
256         unsigned int num_adc_nids;
257         hda_nid_t *adc_nids;
258         hda_nid_t dig_in_nid;
259         unsigned int num_channel_mode;
260         const struct hda_channel_mode *channel_mode;
261         int need_dac_fix;
262         unsigned int num_mux_defs;
263         const struct hda_input_mux *input_mux;
264         void (*unsol_event)(struct hda_codec *, unsigned int);
265         void (*init_hook)(struct hda_codec *);
266 };
267
268
269 /*
270  * input MUX handling
271  */
272 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
273                              struct snd_ctl_elem_info *uinfo)
274 {
275         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
276         struct alc_spec *spec = codec->spec;
277         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
278         if (mux_idx >= spec->num_mux_defs)
279                 mux_idx = 0;
280         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
281 }
282
283 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
284                             struct snd_ctl_elem_value *ucontrol)
285 {
286         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
287         struct alc_spec *spec = codec->spec;
288         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
289
290         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
291         return 0;
292 }
293
294 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
295                             struct snd_ctl_elem_value *ucontrol)
296 {
297         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
298         struct alc_spec *spec = codec->spec;
299         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
300         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
301         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
302                                      spec->adc_nids[adc_idx],
303                                      &spec->cur_mux[adc_idx]);
304 }
305
306
307 /*
308  * channel mode setting
309  */
310 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
311                             struct snd_ctl_elem_info *uinfo)
312 {
313         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
314         struct alc_spec *spec = codec->spec;
315         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
316                                     spec->num_channel_mode);
317 }
318
319 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
320                            struct snd_ctl_elem_value *ucontrol)
321 {
322         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
323         struct alc_spec *spec = codec->spec;
324         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
325                                    spec->num_channel_mode,
326                                    spec->multiout.max_channels);
327 }
328
329 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
330                            struct snd_ctl_elem_value *ucontrol)
331 {
332         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
333         struct alc_spec *spec = codec->spec;
334         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
335                                       spec->num_channel_mode,
336                                       &spec->multiout.max_channels);
337         if (err >= 0 && spec->need_dac_fix)
338                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
339         return err;
340 }
341
342 /*
343  * Control the mode of pin widget settings via the mixer.  "pc" is used
344  * instead of "%" to avoid consequences of accidently treating the % as 
345  * being part of a format specifier.  Maximum allowed length of a value is
346  * 63 characters plus NULL terminator.
347  *
348  * Note: some retasking pin complexes seem to ignore requests for input
349  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
350  * are requested.  Therefore order this list so that this behaviour will not
351  * cause problems when mixer clients move through the enum sequentially.
352  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
353  * March 2006.
354  */
355 static char *alc_pin_mode_names[] = {
356         "Mic 50pc bias", "Mic 80pc bias",
357         "Line in", "Line out", "Headphone out",
358 };
359 static unsigned char alc_pin_mode_values[] = {
360         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
361 };
362 /* The control can present all 5 options, or it can limit the options based
363  * in the pin being assumed to be exclusively an input or an output pin.  In
364  * addition, "input" pins may or may not process the mic bias option
365  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
366  * accept requests for bias as of chip versions up to March 2006) and/or
367  * wiring in the computer.
368  */
369 #define ALC_PIN_DIR_IN              0x00
370 #define ALC_PIN_DIR_OUT             0x01
371 #define ALC_PIN_DIR_INOUT           0x02
372 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
373 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
374
375 /* Info about the pin modes supported by the different pin direction modes. 
376  * For each direction the minimum and maximum values are given.
377  */
378 static signed char alc_pin_mode_dir_info[5][2] = {
379         { 0, 2 },    /* ALC_PIN_DIR_IN */
380         { 3, 4 },    /* ALC_PIN_DIR_OUT */
381         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
382         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
383         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
384 };
385 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
386 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
387 #define alc_pin_mode_n_items(_dir) \
388         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
389
390 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
391                              struct snd_ctl_elem_info *uinfo)
392 {
393         unsigned int item_num = uinfo->value.enumerated.item;
394         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
395
396         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
397         uinfo->count = 1;
398         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
399
400         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
401                 item_num = alc_pin_mode_min(dir);
402         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
403         return 0;
404 }
405
406 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
407                             struct snd_ctl_elem_value *ucontrol)
408 {
409         unsigned int i;
410         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
411         hda_nid_t nid = kcontrol->private_value & 0xffff;
412         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
413         long *valp = ucontrol->value.integer.value;
414         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
415                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
416                                                  0x00);
417
418         /* Find enumerated value for current pinctl setting */
419         i = alc_pin_mode_min(dir);
420         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
421                 i++;
422         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
423         return 0;
424 }
425
426 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
427                             struct snd_ctl_elem_value *ucontrol)
428 {
429         signed int change;
430         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
431         hda_nid_t nid = kcontrol->private_value & 0xffff;
432         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
433         long val = *ucontrol->value.integer.value;
434         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
435                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
436                                                  0x00);
437
438         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
439                 val = alc_pin_mode_min(dir);
440
441         change = pinctl != alc_pin_mode_values[val];
442         if (change) {
443                 /* Set pin mode to that requested */
444                 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
445                                     alc_pin_mode_values[val]);
446
447                 /* Also enable the retasking pin's input/output as required 
448                  * for the requested pin mode.  Enum values of 2 or less are
449                  * input modes.
450                  *
451                  * Dynamically switching the input/output buffers probably
452                  * reduces noise slightly (particularly on input) so we'll
453                  * do it.  However, having both input and output buffers
454                  * enabled simultaneously doesn't seem to be problematic if
455                  * this turns out to be necessary in the future.
456                  */
457                 if (val <= 2) {
458                         snd_hda_codec_write(codec, nid, 0,
459                                             AC_VERB_SET_AMP_GAIN_MUTE,
460                                             AMP_OUT_MUTE);
461                         snd_hda_codec_write(codec, nid, 0,
462                                             AC_VERB_SET_AMP_GAIN_MUTE,
463                                             AMP_IN_UNMUTE(0));
464                 } else {
465                         snd_hda_codec_write(codec, nid, 0,
466                                             AC_VERB_SET_AMP_GAIN_MUTE,
467                                             AMP_IN_MUTE(0));
468                         snd_hda_codec_write(codec, nid, 0,
469                                             AC_VERB_SET_AMP_GAIN_MUTE,
470                                             AMP_OUT_UNMUTE);
471                 }
472         }
473         return change;
474 }
475
476 #define ALC_PIN_MODE(xname, nid, dir) \
477         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
478           .info = alc_pin_mode_info, \
479           .get = alc_pin_mode_get, \
480           .put = alc_pin_mode_put, \
481           .private_value = nid | (dir<<16) }
482
483 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
484  * together using a mask with more than one bit set.  This control is
485  * currently used only by the ALC260 test model.  At this stage they are not
486  * needed for any "production" models.
487  */
488 #ifdef CONFIG_SND_DEBUG
489 static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
490                               struct snd_ctl_elem_info *uinfo)
491 {
492         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
493         uinfo->count = 1;
494         uinfo->value.integer.min = 0;
495         uinfo->value.integer.max = 1;
496         return 0;
497 }
498
499 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
500                              struct snd_ctl_elem_value *ucontrol)
501 {
502         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
503         hda_nid_t nid = kcontrol->private_value & 0xffff;
504         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
505         long *valp = ucontrol->value.integer.value;
506         unsigned int val = snd_hda_codec_read(codec, nid, 0,
507                                               AC_VERB_GET_GPIO_DATA, 0x00);
508
509         *valp = (val & mask) != 0;
510         return 0;
511 }
512 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
513                              struct snd_ctl_elem_value *ucontrol)
514 {
515         signed int change;
516         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517         hda_nid_t nid = kcontrol->private_value & 0xffff;
518         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
519         long val = *ucontrol->value.integer.value;
520         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
521                                                     AC_VERB_GET_GPIO_DATA,
522                                                     0x00);
523
524         /* Set/unset the masked GPIO bit(s) as needed */
525         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
526         if (val == 0)
527                 gpio_data &= ~mask;
528         else
529                 gpio_data |= mask;
530         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
531
532         return change;
533 }
534 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
535         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
536           .info = alc_gpio_data_info, \
537           .get = alc_gpio_data_get, \
538           .put = alc_gpio_data_put, \
539           .private_value = nid | (mask<<16) }
540 #endif   /* CONFIG_SND_DEBUG */
541
542 /* A switch control to allow the enabling of the digital IO pins on the
543  * ALC260.  This is incredibly simplistic; the intention of this control is
544  * to provide something in the test model allowing digital outputs to be
545  * identified if present.  If models are found which can utilise these
546  * outputs a more complete mixer control can be devised for those models if
547  * necessary.
548  */
549 #ifdef CONFIG_SND_DEBUG
550 static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
551                                struct snd_ctl_elem_info *uinfo)
552 {
553         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
554         uinfo->count = 1;
555         uinfo->value.integer.min = 0;
556         uinfo->value.integer.max = 1;
557         return 0;
558 }
559
560 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
561                               struct snd_ctl_elem_value *ucontrol)
562 {
563         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
564         hda_nid_t nid = kcontrol->private_value & 0xffff;
565         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
566         long *valp = ucontrol->value.integer.value;
567         unsigned int val = snd_hda_codec_read(codec, nid, 0,
568                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
569
570         *valp = (val & mask) != 0;
571         return 0;
572 }
573 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
574                               struct snd_ctl_elem_value *ucontrol)
575 {
576         signed int change;
577         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
578         hda_nid_t nid = kcontrol->private_value & 0xffff;
579         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
580         long val = *ucontrol->value.integer.value;
581         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
582                                                     AC_VERB_GET_DIGI_CONVERT,
583                                                     0x00);
584
585         /* Set/unset the masked control bit(s) as needed */
586         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
587         if (val==0)
588                 ctrl_data &= ~mask;
589         else
590                 ctrl_data |= mask;
591         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
592                             ctrl_data);
593
594         return change;
595 }
596 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
597         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
598           .info = alc_spdif_ctrl_info, \
599           .get = alc_spdif_ctrl_get, \
600           .put = alc_spdif_ctrl_put, \
601           .private_value = nid | (mask<<16) }
602 #endif   /* CONFIG_SND_DEBUG */
603
604 /*
605  * set up from the preset table
606  */
607 static void setup_preset(struct alc_spec *spec,
608                          const struct alc_config_preset *preset)
609 {
610         int i;
611
612         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
613                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
614         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
615              i++)
616                 spec->init_verbs[spec->num_init_verbs++] =
617                         preset->init_verbs[i];
618         
619         spec->channel_mode = preset->channel_mode;
620         spec->num_channel_mode = preset->num_channel_mode;
621         spec->need_dac_fix = preset->need_dac_fix;
622
623         spec->multiout.max_channels = spec->channel_mode[0].channels;
624
625         spec->multiout.num_dacs = preset->num_dacs;
626         spec->multiout.dac_nids = preset->dac_nids;
627         spec->multiout.dig_out_nid = preset->dig_out_nid;
628         spec->multiout.hp_nid = preset->hp_nid;
629         
630         spec->num_mux_defs = preset->num_mux_defs;
631         if (!spec->num_mux_defs)
632                 spec->num_mux_defs = 1;
633         spec->input_mux = preset->input_mux;
634
635         spec->num_adc_nids = preset->num_adc_nids;
636         spec->adc_nids = preset->adc_nids;
637         spec->dig_in_nid = preset->dig_in_nid;
638
639         spec->unsol_event = preset->unsol_event;
640         spec->init_hook = preset->init_hook;
641 }
642
643 /* Enable GPIO mask and set output */
644 static struct hda_verb alc_gpio1_init_verbs[] = {
645         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
646         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
647         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
648         { }
649 };
650
651 static struct hda_verb alc_gpio2_init_verbs[] = {
652         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
653         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
654         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
655         { }
656 };
657
658 static struct hda_verb alc_gpio3_init_verbs[] = {
659         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
660         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
661         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
662         { }
663 };
664
665 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
666  *      31 ~ 16 :       Manufacture ID
667  *      15 ~ 8  :       SKU ID
668  *      7  ~ 0  :       Assembly ID
669  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
670  */
671 static void alc_subsystem_id(struct hda_codec *codec,
672                              unsigned int porta, unsigned int porte,
673                              unsigned int portd)
674 {
675         unsigned int ass, tmp;
676
677         ass = codec->subsystem_id;
678         if (!(ass & 1))
679                 return;
680
681         /* Override */
682         tmp = (ass & 0x38) >> 3;        /* external Amp control */
683         switch (tmp) {
684         case 1:
685                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
686                 break;
687         case 3:
688                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
689                 break;
690         case 7:
691                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
692                 break;
693         case 5:
694                 switch (codec->vendor_id) {
695                 case 0x10ec0862:
696                 case 0x10ec0660:
697                 case 0x10ec0662:        
698                 case 0x10ec0267:
699                 case 0x10ec0268:
700                         snd_hda_codec_write(codec, 0x14, 0,
701                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
702                         snd_hda_codec_write(codec, 0x15, 0,
703                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
704                         return;
705                 }
706         case 6:
707                 if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
708                         hda_nid_t port = 0;
709                         tmp = (ass & 0x1800) >> 11;
710                         switch (tmp) {
711                         case 0: port = porta; break;
712                         case 1: port = porte; break;
713                         case 2: port = portd; break;
714                         }
715                         if (port)
716                                 snd_hda_codec_write(codec, port, 0,
717                                                     AC_VERB_SET_EAPD_BTLENABLE,
718                                                     2);
719                 }
720                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
721                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
722                                     (tmp == 5 ? 0x3040 : 0x3050));
723                 break;
724         }
725 }
726
727 /*
728  * Fix-up pin default configurations
729  */
730
731 struct alc_pincfg {
732         hda_nid_t nid;
733         u32 val;
734 };
735
736 static void alc_fix_pincfg(struct hda_codec *codec,
737                            const struct snd_pci_quirk *quirk,
738                            const struct alc_pincfg **pinfix)
739 {
740         const struct alc_pincfg *cfg;
741
742         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
743         if (!quirk)
744                 return;
745
746         cfg = pinfix[quirk->value];
747         for (; cfg->nid; cfg++) {
748                 int i;
749                 u32 val = cfg->val;
750                 for (i = 0; i < 4; i++) {
751                         snd_hda_codec_write(codec, cfg->nid, 0,
752                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
753                                     val & 0xff);
754                         val >>= 8;
755                 }
756         }
757 }
758
759 /*
760  * ALC880 3-stack model
761  *
762  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
763  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
764  *                 F-Mic = 0x1b, HP = 0x19
765  */
766
767 static hda_nid_t alc880_dac_nids[4] = {
768         /* front, rear, clfe, rear_surr */
769         0x02, 0x05, 0x04, 0x03
770 };
771
772 static hda_nid_t alc880_adc_nids[3] = {
773         /* ADC0-2 */
774         0x07, 0x08, 0x09,
775 };
776
777 /* The datasheet says the node 0x07 is connected from inputs,
778  * but it shows zero connection in the real implementation on some devices.
779  * Note: this is a 915GAV bug, fixed on 915GLV
780  */
781 static hda_nid_t alc880_adc_nids_alt[2] = {
782         /* ADC1-2 */
783         0x08, 0x09,
784 };
785
786 #define ALC880_DIGOUT_NID       0x06
787 #define ALC880_DIGIN_NID        0x0a
788
789 static struct hda_input_mux alc880_capture_source = {
790         .num_items = 4,
791         .items = {
792                 { "Mic", 0x0 },
793                 { "Front Mic", 0x3 },
794                 { "Line", 0x2 },
795                 { "CD", 0x4 },
796         },
797 };
798
799 /* channel source setting (2/6 channel selection for 3-stack) */
800 /* 2ch mode */
801 static struct hda_verb alc880_threestack_ch2_init[] = {
802         /* set line-in to input, mute it */
803         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
804         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
805         /* set mic-in to input vref 80%, mute it */
806         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
807         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
808         { } /* end */
809 };
810
811 /* 6ch mode */
812 static struct hda_verb alc880_threestack_ch6_init[] = {
813         /* set line-in to output, unmute it */
814         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
815         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
816         /* set mic-in to output, unmute it */
817         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
818         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
819         { } /* end */
820 };
821
822 static struct hda_channel_mode alc880_threestack_modes[2] = {
823         { 2, alc880_threestack_ch2_init },
824         { 6, alc880_threestack_ch6_init },
825 };
826
827 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
828         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
829         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
830         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
831         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
832         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
833         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
834         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
835         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
836         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
837         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
838         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
839         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
840         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
841         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
842         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
843         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
844         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
845         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
846         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
847         {
848                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
849                 .name = "Channel Mode",
850                 .info = alc_ch_mode_info,
851                 .get = alc_ch_mode_get,
852                 .put = alc_ch_mode_put,
853         },
854         { } /* end */
855 };
856
857 /* capture mixer elements */
858 static struct snd_kcontrol_new alc880_capture_mixer[] = {
859         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
860         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
861         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
862         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
863         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
864         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
865         {
866                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
867                 /* The multiple "Capture Source" controls confuse alsamixer
868                  * So call somewhat different..
869                  * FIXME: the controls appear in the "playback" view!
870                  */
871                 /* .name = "Capture Source", */
872                 .name = "Input Source",
873                 .count = 3,
874                 .info = alc_mux_enum_info,
875                 .get = alc_mux_enum_get,
876                 .put = alc_mux_enum_put,
877         },
878         { } /* end */
879 };
880
881 /* capture mixer elements (in case NID 0x07 not available) */
882 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
883         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
884         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
885         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
886         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
887         {
888                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
889                 /* The multiple "Capture Source" controls confuse alsamixer
890                  * So call somewhat different..
891                  * FIXME: the controls appear in the "playback" view!
892                  */
893                 /* .name = "Capture Source", */
894                 .name = "Input Source",
895                 .count = 2,
896                 .info = alc_mux_enum_info,
897                 .get = alc_mux_enum_get,
898                 .put = alc_mux_enum_put,
899         },
900         { } /* end */
901 };
902
903
904
905 /*
906  * ALC880 5-stack model
907  *
908  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
909  *      Side = 0x02 (0xd)
910  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
911  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
912  */
913
914 /* additional mixers to alc880_three_stack_mixer */
915 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
916         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
917         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
918         { } /* end */
919 };
920
921 /* channel source setting (6/8 channel selection for 5-stack) */
922 /* 6ch mode */
923 static struct hda_verb alc880_fivestack_ch6_init[] = {
924         /* set line-in to input, mute it */
925         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
926         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
927         { } /* end */
928 };
929
930 /* 8ch mode */
931 static struct hda_verb alc880_fivestack_ch8_init[] = {
932         /* set line-in to output, unmute it */
933         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
934         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
935         { } /* end */
936 };
937
938 static struct hda_channel_mode alc880_fivestack_modes[2] = {
939         { 6, alc880_fivestack_ch6_init },
940         { 8, alc880_fivestack_ch8_init },
941 };
942
943
944 /*
945  * ALC880 6-stack model
946  *
947  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
948  *      Side = 0x05 (0x0f)
949  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
950  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
951  */
952
953 static hda_nid_t alc880_6st_dac_nids[4] = {
954         /* front, rear, clfe, rear_surr */
955         0x02, 0x03, 0x04, 0x05
956 };
957
958 static struct hda_input_mux alc880_6stack_capture_source = {
959         .num_items = 4,
960         .items = {
961                 { "Mic", 0x0 },
962                 { "Front Mic", 0x1 },
963                 { "Line", 0x2 },
964                 { "CD", 0x4 },
965         },
966 };
967
968 /* fixed 8-channels */
969 static struct hda_channel_mode alc880_sixstack_modes[1] = {
970         { 8, NULL },
971 };
972
973 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
974         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
975         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
976         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
977         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
978         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
979         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
980         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
981         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
982         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
983         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
984         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
985         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
986         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
987         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
988         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
989         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
990         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
991         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
992         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
993         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
994         {
995                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
996                 .name = "Channel Mode",
997                 .info = alc_ch_mode_info,
998                 .get = alc_ch_mode_get,
999                 .put = alc_ch_mode_put,
1000         },
1001         { } /* end */
1002 };
1003
1004
1005 /*
1006  * ALC880 W810 model
1007  *
1008  * W810 has rear IO for:
1009  * Front (DAC 02)
1010  * Surround (DAC 03)
1011  * Center/LFE (DAC 04)
1012  * Digital out (06)
1013  *
1014  * The system also has a pair of internal speakers, and a headphone jack.
1015  * These are both connected to Line2 on the codec, hence to DAC 02.
1016  * 
1017  * There is a variable resistor to control the speaker or headphone
1018  * volume. This is a hardware-only device without a software API.
1019  *
1020  * Plugging headphones in will disable the internal speakers. This is
1021  * implemented in hardware, not via the driver using jack sense. In
1022  * a similar fashion, plugging into the rear socket marked "front" will
1023  * disable both the speakers and headphones.
1024  *
1025  * For input, there's a microphone jack, and an "audio in" jack.
1026  * These may not do anything useful with this driver yet, because I
1027  * haven't setup any initialization verbs for these yet...
1028  */
1029
1030 static hda_nid_t alc880_w810_dac_nids[3] = {
1031         /* front, rear/surround, clfe */
1032         0x02, 0x03, 0x04
1033 };
1034
1035 /* fixed 6 channels */
1036 static struct hda_channel_mode alc880_w810_modes[1] = {
1037         { 6, NULL }
1038 };
1039
1040 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1041 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1042         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1043         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1044         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1045         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1046         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1047         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1048         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1049         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1050         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1051         { } /* end */
1052 };
1053
1054
1055 /*
1056  * Z710V model
1057  *
1058  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1059  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1060  *                 Line = 0x1a
1061  */
1062
1063 static hda_nid_t alc880_z71v_dac_nids[1] = {
1064         0x02
1065 };
1066 #define ALC880_Z71V_HP_DAC      0x03
1067
1068 /* fixed 2 channels */
1069 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1070         { 2, NULL }
1071 };
1072
1073 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1074         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1075         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1076         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1077         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1078         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1079         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1080         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1081         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1082         { } /* end */
1083 };
1084
1085
1086 /* FIXME! */
1087 /*
1088  * ALC880 F1734 model
1089  *
1090  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1091  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1092  */
1093
1094 static hda_nid_t alc880_f1734_dac_nids[1] = {
1095         0x03
1096 };
1097 #define ALC880_F1734_HP_DAC     0x02
1098
1099 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1100         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1101         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1102         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1103         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1104         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1105         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1106         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1107         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1108         { } /* end */
1109 };
1110
1111
1112 /* FIXME! */
1113 /*
1114  * ALC880 ASUS 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
1119  */
1120
1121 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1122 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1123
1124 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1125         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1126         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1127         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1128         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1129         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1130         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1131         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1132         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1133         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1134         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1135         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1136         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1137         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1138         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1139         {
1140                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1141                 .name = "Channel Mode",
1142                 .info = alc_ch_mode_info,
1143                 .get = alc_ch_mode_get,
1144                 .put = alc_ch_mode_put,
1145         },
1146         { } /* end */
1147 };
1148
1149 /* FIXME! */
1150 /*
1151  * ALC880 ASUS W1V model
1152  *
1153  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1154  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1155  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1156  */
1157
1158 /* additional mixers to alc880_asus_mixer */
1159 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1160         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1161         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1162         { } /* end */
1163 };
1164
1165 /* additional mixers to alc880_asus_mixer */
1166 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1167         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1168         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1169         { } /* end */
1170 };
1171
1172 /* TCL S700 */
1173 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1174         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1175         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1176         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1177         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1178         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1179         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1180         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1181         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1182         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1183         {
1184                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1185                 /* The multiple "Capture Source" controls confuse alsamixer
1186                  * So call somewhat different..
1187                  * FIXME: the controls appear in the "playback" view!
1188                  */
1189                 /* .name = "Capture Source", */
1190                 .name = "Input Source",
1191                 .count = 1,
1192                 .info = alc_mux_enum_info,
1193                 .get = alc_mux_enum_get,
1194                 .put = alc_mux_enum_put,
1195         },
1196         { } /* end */
1197 };
1198
1199 /* Uniwill */
1200 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1201         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1202         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1203         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1204         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1205         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1206         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1207         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1208         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1209         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1210         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1211         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1212         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1213         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1214         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1215         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1216         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1217         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1218         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1219         {
1220                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1221                 .name = "Channel Mode",
1222                 .info = alc_ch_mode_info,
1223                 .get = alc_ch_mode_get,
1224                 .put = alc_ch_mode_put,
1225         },
1226         { } /* end */
1227 };
1228
1229 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1230         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1231         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1232         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1233         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1234         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1235         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1236         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1237         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1238         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1239         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1240         { } /* end */
1241 };
1242
1243 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1244         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1245         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1246         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1247         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1248         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1249         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1250         { } /* end */
1251 };
1252
1253 /*
1254  * build control elements
1255  */
1256 static int alc_build_controls(struct hda_codec *codec)
1257 {
1258         struct alc_spec *spec = codec->spec;
1259         int err;
1260         int i;
1261
1262         for (i = 0; i < spec->num_mixers; i++) {
1263                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1264                 if (err < 0)
1265                         return err;
1266         }
1267
1268         if (spec->multiout.dig_out_nid) {
1269                 err = snd_hda_create_spdif_out_ctls(codec,
1270                                                     spec->multiout.dig_out_nid);
1271                 if (err < 0)
1272                         return err;
1273         }
1274         if (spec->dig_in_nid) {
1275                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1276                 if (err < 0)
1277                         return err;
1278         }
1279         return 0;
1280 }
1281
1282
1283 /*
1284  * initialize the codec volumes, etc
1285  */
1286
1287 /*
1288  * generic initialization of ADC, input mixers and output mixers
1289  */
1290 static struct hda_verb alc880_volume_init_verbs[] = {
1291         /*
1292          * Unmute ADC0-2 and set the default input to mic-in
1293          */
1294         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1295         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1296         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1297         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1298         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1299         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1300
1301         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1302          * mixer widget
1303          * Note: PASD motherboards uses the Line In 2 as the input for front
1304          * panel mic (mic 2)
1305          */
1306         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1307         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1308         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1309         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1310         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1311         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1312
1313         /*
1314          * Set up output mixers (0x0c - 0x0f)
1315          */
1316         /* set vol=0 to output mixers */
1317         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1318         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1319         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1320         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1321         /* set up input amps for analog loopback */
1322         /* Amp Indices: DAC = 0, mixer = 1 */
1323         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1324         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1325         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1326         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1327         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1328         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1329         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1330         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1331
1332         { }
1333 };
1334
1335 /*
1336  * 3-stack pin configuration:
1337  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1338  */
1339 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1340         /*
1341          * preset connection lists of input pins
1342          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1343          */
1344         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1345         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1346         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1347
1348         /*
1349          * Set pin mode and muting
1350          */
1351         /* set front pin widgets 0x14 for output */
1352         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1353         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1354         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1355         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1356         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1357         /* Mic2 (as headphone out) for HP output */
1358         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1359         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1360         /* Line In pin widget for input */
1361         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1362         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1363         /* Line2 (as front mic) pin widget for input and vref at 80% */
1364         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1365         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1366         /* CD pin widget for input */
1367         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1368
1369         { }
1370 };
1371
1372 /*
1373  * 5-stack pin configuration:
1374  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1375  * line-in/side = 0x1a, f-mic = 0x1b
1376  */
1377 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1378         /*
1379          * preset connection lists of input pins
1380          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1381          */
1382         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1383         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1384
1385         /*
1386          * Set pin mode and muting
1387          */
1388         /* set pin widgets 0x14-0x17 for output */
1389         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1390         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1391         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1392         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1393         /* unmute pins for output (no gain on this amp) */
1394         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1395         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1396         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1397         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1398
1399         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1400         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1401         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1402         /* Mic2 (as headphone out) for HP output */
1403         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1404         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1405         /* Line In pin widget for input */
1406         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1407         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1408         /* Line2 (as front mic) pin widget for input and vref at 80% */
1409         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1410         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1411         /* CD pin widget for input */
1412         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1413
1414         { }
1415 };
1416
1417 /*
1418  * W810 pin configuration:
1419  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1420  */
1421 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1422         /* hphone/speaker input selector: front DAC */
1423         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1424
1425         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1426         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1427         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1428         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1429         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1430         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1431
1432         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1433         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1434
1435         { }
1436 };
1437
1438 /*
1439  * Z71V pin configuration:
1440  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1441  */
1442 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1443         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1444         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1445         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1446         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1447
1448         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1449         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1450         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1451         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1452
1453         { }
1454 };
1455
1456 /*
1457  * 6-stack pin configuration:
1458  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1459  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1460  */
1461 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1462         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1463
1464         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1465         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1466         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1467         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1468         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1469         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1470         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1471         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1472
1473         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1474         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1475         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1476         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1477         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1478         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1479         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1480         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1481         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1482         
1483         { }
1484 };
1485
1486 /*
1487  * Uniwill pin configuration:
1488  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1489  * line = 0x1a
1490  */
1491 static struct hda_verb alc880_uniwill_init_verbs[] = {
1492         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1493
1494         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1495         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1496         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1497         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1499         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1500         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1501         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1502         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1503         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1504         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1505         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1506         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1507         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1508
1509         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1510         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1511         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1512         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1513         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1514         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1515         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1516         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1517         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1518
1519         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1520         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1521
1522         { }
1523 };
1524
1525 /*
1526 * Uniwill P53
1527 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1528  */
1529 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1530         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1531
1532         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1533         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1534         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1535         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1536         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1537         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1538         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1539         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1540         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1541         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1542         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1543         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1544
1545         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1546         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1547         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1548         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1549         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1550         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1551
1552         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1553         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1554
1555         { }
1556 };
1557
1558 static struct hda_verb alc880_beep_init_verbs[] = {
1559         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1560         { }
1561 };
1562
1563 /* toggle speaker-output according to the hp-jack state */
1564 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1565 {
1566         unsigned int present;
1567         unsigned char bits;
1568
1569         present = snd_hda_codec_read(codec, 0x14, 0,
1570                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1571         bits = present ? 0x80 : 0;
1572         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1573                                  0x80, bits);
1574         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1575                                  0x80, bits);
1576         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1577                                  0x80, bits);
1578         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1579                                  0x80, bits);
1580 }
1581
1582 /* auto-toggle front mic */
1583 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1584 {
1585         unsigned int present;
1586         unsigned char bits;
1587
1588         present = snd_hda_codec_read(codec, 0x18, 0,
1589                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1590         bits = present ? 0x80 : 0;
1591         snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
1592                                  0x80, bits);
1593         snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
1594                                  0x80, bits);
1595 }
1596
1597 static void alc880_uniwill_automute(struct hda_codec *codec)
1598 {
1599         alc880_uniwill_hp_automute(codec);
1600         alc880_uniwill_mic_automute(codec);
1601 }
1602
1603 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1604                                        unsigned int res)
1605 {
1606         /* Looks like the unsol event is incompatible with the standard
1607          * definition.  4bit tag is placed at 28 bit!
1608          */
1609         switch (res >> 28) {
1610         case ALC880_HP_EVENT:
1611                 alc880_uniwill_hp_automute(codec);
1612                 break;
1613         case ALC880_MIC_EVENT:
1614                 alc880_uniwill_mic_automute(codec);
1615                 break;
1616         }
1617 }
1618
1619 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1620 {
1621         unsigned int present;
1622         unsigned char bits;
1623
1624         present = snd_hda_codec_read(codec, 0x14, 0,
1625                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1626         bits = present ? 0x80 : 0;
1627         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1628                                  0x80, bits);
1629         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1630                                  0x80, bits);
1631 }
1632
1633 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1634 {
1635         unsigned int present;
1636         
1637         present = snd_hda_codec_read(codec, 0x21, 0,
1638                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1639
1640         snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1641                                  0x7f, present);
1642         snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1643                                  0x7f,  present);
1644
1645         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1646                                  0x7f,  present);
1647         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1648                                  0x7f, present);
1649
1650 }
1651 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1652                                            unsigned int res)
1653 {
1654         /* Looks like the unsol event is incompatible with the standard
1655          * definition.  4bit tag is placed at 28 bit!
1656          */
1657         if ((res >> 28) == ALC880_HP_EVENT)
1658                 alc880_uniwill_p53_hp_automute(codec);
1659         if ((res >> 28) == ALC880_DCVOL_EVENT)
1660                 alc880_uniwill_p53_dcvol_automute(codec);
1661 }
1662
1663 /* FIXME! */
1664 /*
1665  * F1734 pin configuration:
1666  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1667  */
1668 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1669         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1670         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1671         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1672         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1673
1674         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1675         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1676         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1677         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1678
1679         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1680         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1681         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1682         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1683         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1684         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1685         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1686         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1687         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1688
1689         { }
1690 };
1691
1692 /* FIXME! */
1693 /*
1694  * ASUS pin configuration:
1695  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1696  */
1697 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1698         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1699         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1700         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1701         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1702
1703         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1704         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1705         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1706         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1707         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1708         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1709         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1710         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1711
1712         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1713         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1714         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1715         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1716         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1717         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1718         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1719         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1720         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1721         
1722         { }
1723 };
1724
1725 /* Enable GPIO mask and set output */
1726 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1727 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1728
1729 /* Clevo m520g init */
1730 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1731         /* headphone output */
1732         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1733         /* line-out */
1734         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1735         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1736         /* Line-in */
1737         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1738         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1739         /* CD */
1740         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1741         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1742         /* Mic1 (rear panel) */
1743         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1744         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1745         /* Mic2 (front panel) */
1746         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1747         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1748         /* headphone */
1749         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1750         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1751         /* change to EAPD mode */
1752         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1753         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1754
1755         { }
1756 };
1757
1758 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1759         /* change to EAPD mode */
1760         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1761         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1762
1763         /* Headphone output */
1764         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1765         /* Front output*/
1766         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1767         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1768
1769         /* Line In pin widget for input */
1770         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1771         /* CD pin widget for input */
1772         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1773         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1774         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1775
1776         /* change to EAPD mode */
1777         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1778         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1779
1780         { }
1781 };
1782
1783 /*
1784  * LG m1 express dual
1785  *
1786  * Pin assignment:
1787  *   Rear Line-In/Out (blue): 0x14
1788  *   Build-in Mic-In: 0x15
1789  *   Speaker-out: 0x17
1790  *   HP-Out (green): 0x1b
1791  *   Mic-In/Out (red): 0x19
1792  *   SPDIF-Out: 0x1e
1793  */
1794
1795 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1796 static hda_nid_t alc880_lg_dac_nids[3] = {
1797         0x05, 0x02, 0x03
1798 };
1799
1800 /* seems analog CD is not working */
1801 static struct hda_input_mux alc880_lg_capture_source = {
1802         .num_items = 3,
1803         .items = {
1804                 { "Mic", 0x1 },
1805                 { "Line", 0x5 },
1806                 { "Internal Mic", 0x6 },
1807         },
1808 };
1809
1810 /* 2,4,6 channel modes */
1811 static struct hda_verb alc880_lg_ch2_init[] = {
1812         /* set line-in and mic-in to input */
1813         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1814         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1815         { }
1816 };
1817
1818 static struct hda_verb alc880_lg_ch4_init[] = {
1819         /* set line-in to out and mic-in to input */
1820         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1821         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1822         { }
1823 };
1824
1825 static struct hda_verb alc880_lg_ch6_init[] = {
1826         /* set line-in and mic-in to output */
1827         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1828         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1829         { }
1830 };
1831
1832 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1833         { 2, alc880_lg_ch2_init },
1834         { 4, alc880_lg_ch4_init },
1835         { 6, alc880_lg_ch6_init },
1836 };
1837
1838 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1839         /* FIXME: it's not really "master" but front channels */
1840         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1841         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1842         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1843         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1844         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1845         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1846         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1847         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1848         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1849         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1850         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1851         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1852         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1853         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1854         {
1855                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1856                 .name = "Channel Mode",
1857                 .info = alc_ch_mode_info,
1858                 .get = alc_ch_mode_get,
1859                 .put = alc_ch_mode_put,
1860         },
1861         { } /* end */
1862 };
1863
1864 static struct hda_verb alc880_lg_init_verbs[] = {
1865         /* set capture source to mic-in */
1866         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1867         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1868         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1869         /* mute all amp mixer inputs */
1870         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1871         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1872         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1873         /* line-in to input */
1874         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1875         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1876         /* built-in mic */
1877         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1878         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1879         /* speaker-out */
1880         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1881         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1882         /* mic-in to input */
1883         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1884         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1885         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1886         /* HP-out */
1887         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1888         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1889         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1890         /* jack sense */
1891         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1892         { }
1893 };
1894
1895 /* toggle speaker-output according to the hp-jack state */
1896 static void alc880_lg_automute(struct hda_codec *codec)
1897 {
1898         unsigned int present;
1899         unsigned char bits;
1900
1901         present = snd_hda_codec_read(codec, 0x1b, 0,
1902                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1903         bits = present ? 0x80 : 0;
1904         snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1905                                  0x80, bits);
1906         snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1907                                  0x80, bits);
1908 }
1909
1910 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1911 {
1912         /* Looks like the unsol event is incompatible with the standard
1913          * definition.  4bit tag is placed at 28 bit!
1914          */
1915         if ((res >> 28) == 0x01)
1916                 alc880_lg_automute(codec);
1917 }
1918
1919 /*
1920  * LG LW20
1921  *
1922  * Pin assignment:
1923  *   Speaker-out: 0x14
1924  *   Mic-In: 0x18
1925  *   Built-in Mic-In: 0x19
1926  *   Line-In: 0x1b
1927  *   HP-Out: 0x1a
1928  *   SPDIF-Out: 0x1e
1929  */
1930
1931 static struct hda_input_mux alc880_lg_lw_capture_source = {
1932         .num_items = 3,
1933         .items = {
1934                 { "Mic", 0x0 },
1935                 { "Internal Mic", 0x1 },
1936                 { "Line In", 0x2 },
1937         },
1938 };
1939
1940 #define alc880_lg_lw_modes alc880_threestack_modes
1941
1942 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1943         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1944         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1945         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1946         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1947         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1948         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1949         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1950         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1951         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1952         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1953         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1954         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1955         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1956         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1957         {
1958                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1959                 .name = "Channel Mode",
1960                 .info = alc_ch_mode_info,
1961                 .get = alc_ch_mode_get,
1962                 .put = alc_ch_mode_put,
1963         },
1964         { } /* end */
1965 };
1966
1967 static struct hda_verb alc880_lg_lw_init_verbs[] = {
1968         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1969         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1970         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1971
1972         /* set capture source to mic-in */
1973         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1974         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1975         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1976         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1977         /* speaker-out */
1978         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1979         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1980         /* HP-out */
1981         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1982         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1983         /* mic-in to input */
1984         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1985         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1986         /* built-in mic */
1987         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1988         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1989         /* jack sense */
1990         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1991         { }
1992 };
1993
1994 /* toggle speaker-output according to the hp-jack state */
1995 static void alc880_lg_lw_automute(struct hda_codec *codec)
1996 {
1997         unsigned int present;
1998         unsigned char bits;
1999
2000         present = snd_hda_codec_read(codec, 0x1b, 0,
2001                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2002         bits = present ? 0x80 : 0;
2003         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
2004                                  0x80, bits);
2005         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
2006                                  0x80, bits);
2007 }
2008
2009 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2010 {
2011         /* Looks like the unsol event is incompatible with the standard
2012          * definition.  4bit tag is placed at 28 bit!
2013          */
2014         if ((res >> 28) == 0x01)
2015                 alc880_lg_lw_automute(codec);
2016 }
2017
2018 /*
2019  * Common callbacks
2020  */
2021
2022 static int alc_init(struct hda_codec *codec)
2023 {
2024         struct alc_spec *spec = codec->spec;
2025         unsigned int i;
2026
2027         for (i = 0; i < spec->num_init_verbs; i++)
2028                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2029
2030         if (spec->init_hook)
2031                 spec->init_hook(codec);
2032
2033         return 0;
2034 }
2035
2036 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2037 {
2038         struct alc_spec *spec = codec->spec;
2039
2040         if (spec->unsol_event)
2041                 spec->unsol_event(codec, res);
2042 }
2043
2044 #ifdef CONFIG_PM
2045 /*
2046  * resume
2047  */
2048 static int alc_resume(struct hda_codec *codec)
2049 {
2050         struct alc_spec *spec = codec->spec;
2051         int i;
2052
2053         alc_init(codec);
2054         for (i = 0; i < spec->num_mixers; i++)
2055                 snd_hda_resume_ctls(codec, spec->mixers[i]);
2056         if (spec->multiout.dig_out_nid)
2057                 snd_hda_resume_spdif_out(codec);
2058         if (spec->dig_in_nid)
2059                 snd_hda_resume_spdif_in(codec);
2060
2061         return 0;
2062 }
2063 #endif
2064
2065 /*
2066  * Analog playback callbacks
2067  */
2068 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2069                                     struct hda_codec *codec,
2070                                     struct snd_pcm_substream *substream)
2071 {
2072         struct alc_spec *spec = codec->spec;
2073         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2074 }
2075
2076 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2077                                        struct hda_codec *codec,
2078                                        unsigned int stream_tag,
2079                                        unsigned int format,
2080                                        struct snd_pcm_substream *substream)
2081 {
2082         struct alc_spec *spec = codec->spec;
2083         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2084                                                 stream_tag, format, substream);
2085 }
2086
2087 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2088                                        struct hda_codec *codec,
2089                                        struct snd_pcm_substream *substream)
2090 {
2091         struct alc_spec *spec = codec->spec;
2092         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2093 }
2094
2095 /*
2096  * Digital out
2097  */
2098 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2099                                         struct hda_codec *codec,
2100                                         struct snd_pcm_substream *substream)
2101 {
2102         struct alc_spec *spec = codec->spec;
2103         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2104 }
2105
2106 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2107                                            struct hda_codec *codec,
2108                                            unsigned int stream_tag,
2109                                            unsigned int format,
2110                                            struct snd_pcm_substream *substream)
2111 {
2112         struct alc_spec *spec = codec->spec;
2113         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2114                                              stream_tag, format, substream);
2115 }
2116
2117 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2118                                          struct hda_codec *codec,
2119                                          struct snd_pcm_substream *substream)
2120 {
2121         struct alc_spec *spec = codec->spec;
2122         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2123 }
2124
2125 /*
2126  * Analog capture
2127  */
2128 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2129                                       struct hda_codec *codec,
2130                                       unsigned int stream_tag,
2131                                       unsigned int format,
2132                                       struct snd_pcm_substream *substream)
2133 {
2134         struct alc_spec *spec = codec->spec;
2135
2136         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2137                                    stream_tag, 0, format);
2138         return 0;
2139 }
2140
2141 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2142                                       struct hda_codec *codec,
2143                                       struct snd_pcm_substream *substream)
2144 {
2145         struct alc_spec *spec = codec->spec;
2146
2147         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2148                                    0, 0, 0);
2149         return 0;
2150 }
2151
2152
2153 /*
2154  */
2155 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2156         .substreams = 1,
2157         .channels_min = 2,
2158         .channels_max = 8,
2159         /* NID is set in alc_build_pcms */
2160         .ops = {
2161                 .open = alc880_playback_pcm_open,
2162                 .prepare = alc880_playback_pcm_prepare,
2163                 .cleanup = alc880_playback_pcm_cleanup
2164         },
2165 };
2166
2167 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2168         .substreams = 2,
2169         .channels_min = 2,
2170         .channels_max = 2,
2171         /* NID is set in alc_build_pcms */
2172         .ops = {
2173                 .prepare = alc880_capture_pcm_prepare,
2174                 .cleanup = alc880_capture_pcm_cleanup
2175         },
2176 };
2177
2178 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2179         .substreams = 1,
2180         .channels_min = 2,
2181         .channels_max = 2,
2182         /* NID is set in alc_build_pcms */
2183         .ops = {
2184                 .open = alc880_dig_playback_pcm_open,
2185                 .close = alc880_dig_playback_pcm_close,
2186                 .prepare = alc880_dig_playback_pcm_prepare
2187         },
2188 };
2189
2190 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2191         .substreams = 1,
2192         .channels_min = 2,
2193         .channels_max = 2,
2194         /* NID is set in alc_build_pcms */
2195 };
2196
2197 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2198 static struct hda_pcm_stream alc_pcm_null_playback = {
2199         .substreams = 0,
2200         .channels_min = 0,
2201         .channels_max = 0,
2202 };
2203
2204 static int alc_build_pcms(struct hda_codec *codec)
2205 {
2206         struct alc_spec *spec = codec->spec;
2207         struct hda_pcm *info = spec->pcm_rec;
2208         int i;
2209
2210         codec->num_pcms = 1;
2211         codec->pcm_info = info;
2212
2213         info->name = spec->stream_name_analog;
2214         if (spec->stream_analog_playback) {
2215                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2216                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2217                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2218         }
2219         if (spec->stream_analog_capture) {
2220                 snd_assert(spec->adc_nids, return -EINVAL);
2221                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2222                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2223         }
2224
2225         if (spec->channel_mode) {
2226                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2227                 for (i = 0; i < spec->num_channel_mode; i++) {
2228                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2229                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2230                         }
2231                 }
2232         }
2233
2234         /* SPDIF for stream index #1 */
2235         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2236                 codec->num_pcms = 2;
2237                 info = spec->pcm_rec + 1;
2238                 info->name = spec->stream_name_digital;
2239                 if (spec->multiout.dig_out_nid &&
2240                     spec->stream_digital_playback) {
2241                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2242                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2243                 }
2244                 if (spec->dig_in_nid &&
2245                     spec->stream_digital_capture) {
2246                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2247                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2248                 }
2249         }
2250
2251         /* If the use of more than one ADC is requested for the current
2252          * model, configure a second analog capture-only PCM.
2253          */
2254         /* Additional Analaog capture for index #2 */
2255         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2256             spec->adc_nids) {
2257                 codec->num_pcms = 3;
2258                 info = spec->pcm_rec + 2;
2259                 info->name = spec->stream_name_analog;
2260                 /* No playback stream for second PCM */
2261                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2262                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2263                 if (spec->stream_analog_capture) {
2264                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2265                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2266                 }
2267         }
2268
2269         return 0;
2270 }
2271
2272 static void alc_free(struct hda_codec *codec)
2273 {
2274         struct alc_spec *spec = codec->spec;
2275         unsigned int i;
2276
2277         if (!spec)
2278                 return;
2279
2280         if (spec->kctl_alloc) {
2281                 for (i = 0; i < spec->num_kctl_used; i++)
2282                         kfree(spec->kctl_alloc[i].name);
2283                 kfree(spec->kctl_alloc);
2284         }
2285         kfree(spec);
2286 }
2287
2288 /*
2289  */
2290 static struct hda_codec_ops alc_patch_ops = {
2291         .build_controls = alc_build_controls,
2292         .build_pcms = alc_build_pcms,
2293         .init = alc_init,
2294         .free = alc_free,
2295         .unsol_event = alc_unsol_event,
2296 #ifdef CONFIG_PM
2297         .resume = alc_resume,
2298 #endif
2299 };
2300
2301
2302 /*
2303  * Test configuration for debugging
2304  *
2305  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2306  * enum controls.
2307  */
2308 #ifdef CONFIG_SND_DEBUG
2309 static hda_nid_t alc880_test_dac_nids[4] = {
2310         0x02, 0x03, 0x04, 0x05
2311 };
2312
2313 static struct hda_input_mux alc880_test_capture_source = {
2314         .num_items = 7,
2315         .items = {
2316                 { "In-1", 0x0 },
2317                 { "In-2", 0x1 },
2318                 { "In-3", 0x2 },
2319                 { "In-4", 0x3 },
2320                 { "CD", 0x4 },
2321                 { "Front", 0x5 },
2322                 { "Surround", 0x6 },
2323         },
2324 };
2325
2326 static struct hda_channel_mode alc880_test_modes[4] = {
2327         { 2, NULL },
2328         { 4, NULL },
2329         { 6, NULL },
2330         { 8, NULL },
2331 };
2332
2333 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2334                                  struct snd_ctl_elem_info *uinfo)
2335 {
2336         static char *texts[] = {
2337                 "N/A", "Line Out", "HP Out",
2338                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2339         };
2340         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2341         uinfo->count = 1;
2342         uinfo->value.enumerated.items = 8;
2343         if (uinfo->value.enumerated.item >= 8)
2344                 uinfo->value.enumerated.item = 7;
2345         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2346         return 0;
2347 }
2348
2349 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2350                                 struct snd_ctl_elem_value *ucontrol)
2351 {
2352         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2353         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2354         unsigned int pin_ctl, item = 0;
2355
2356         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2357                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2358         if (pin_ctl & AC_PINCTL_OUT_EN) {
2359                 if (pin_ctl & AC_PINCTL_HP_EN)
2360                         item = 2;
2361                 else
2362                         item = 1;
2363         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2364                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2365                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2366                 case AC_PINCTL_VREF_50:  item = 4; break;
2367                 case AC_PINCTL_VREF_GRD: item = 5; break;
2368                 case AC_PINCTL_VREF_80:  item = 6; break;
2369                 case AC_PINCTL_VREF_100: item = 7; break;
2370                 }
2371         }
2372         ucontrol->value.enumerated.item[0] = item;
2373         return 0;
2374 }
2375
2376 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2377                                 struct snd_ctl_elem_value *ucontrol)
2378 {
2379         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2380         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2381         static unsigned int ctls[] = {
2382                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2383                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2384                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2385                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2386                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2387                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2388         };
2389         unsigned int old_ctl, new_ctl;
2390
2391         old_ctl = snd_hda_codec_read(codec, nid, 0,
2392                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2393         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2394         if (old_ctl != new_ctl) {
2395                 snd_hda_codec_write(codec, nid, 0,
2396                                     AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2397                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2398                                     (ucontrol->value.enumerated.item[0] >= 3 ?
2399                                      0xb080 : 0xb000));
2400                 return 1;
2401         }
2402         return 0;
2403 }
2404
2405 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2406                                  struct snd_ctl_elem_info *uinfo)
2407 {
2408         static char *texts[] = {
2409                 "Front", "Surround", "CLFE", "Side"
2410         };
2411         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2412         uinfo->count = 1;
2413         uinfo->value.enumerated.items = 4;
2414         if (uinfo->value.enumerated.item >= 4)
2415                 uinfo->value.enumerated.item = 3;
2416         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2417         return 0;
2418 }
2419
2420 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2421                                 struct snd_ctl_elem_value *ucontrol)
2422 {
2423         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2424         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2425         unsigned int sel;
2426
2427         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2428         ucontrol->value.enumerated.item[0] = sel & 3;
2429         return 0;
2430 }
2431
2432 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2433                                 struct snd_ctl_elem_value *ucontrol)
2434 {
2435         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2436         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2437         unsigned int sel;
2438
2439         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2440         if (ucontrol->value.enumerated.item[0] != sel) {
2441                 sel = ucontrol->value.enumerated.item[0] & 3;
2442                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2443                 return 1;
2444         }
2445         return 0;
2446 }
2447
2448 #define PIN_CTL_TEST(xname,nid) {                       \
2449                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2450                         .name = xname,                 \
2451                         .info = alc_test_pin_ctl_info, \
2452                         .get = alc_test_pin_ctl_get,   \
2453                         .put = alc_test_pin_ctl_put,   \
2454                         .private_value = nid           \
2455                         }
2456
2457 #define PIN_SRC_TEST(xname,nid) {                       \
2458                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2459                         .name = xname,                 \
2460                         .info = alc_test_pin_src_info, \
2461                         .get = alc_test_pin_src_get,   \
2462                         .put = alc_test_pin_src_put,   \
2463                         .private_value = nid           \
2464                         }
2465
2466 static struct snd_kcontrol_new alc880_test_mixer[] = {
2467         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2468         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2469         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2470         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2471         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2472         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2473         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2474         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2475         PIN_CTL_TEST("Front Pin Mode", 0x14),
2476         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2477         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2478         PIN_CTL_TEST("Side Pin Mode", 0x17),
2479         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2480         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2481         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2482         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2483         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2484         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2485         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2486         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2487         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2488         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2489         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2490         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2491         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2492         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2493         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2494         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2495         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2496         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2497         {
2498                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2499                 .name = "Channel Mode",
2500                 .info = alc_ch_mode_info,
2501                 .get = alc_ch_mode_get,
2502                 .put = alc_ch_mode_put,
2503         },
2504         { } /* end */
2505 };
2506
2507 static struct hda_verb alc880_test_init_verbs[] = {
2508         /* Unmute inputs of 0x0c - 0x0f */
2509         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2510         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2511         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2512         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2513         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2514         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2515         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2516         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2517         /* Vol output for 0x0c-0x0f */
2518         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2519         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2520         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2521         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2522         /* Set output pins 0x14-0x17 */
2523         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2524         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2525         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2526         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2527         /* Unmute output pins 0x14-0x17 */
2528         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2529         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2530         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2531         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2532         /* Set input pins 0x18-0x1c */
2533         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2534         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2535         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2536         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2537         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2538         /* Mute input pins 0x18-0x1b */
2539         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2540         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2541         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2542         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2543         /* ADC set up */
2544         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2545         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2546         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2547         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2548         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2549         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2550         /* Analog input/passthru */
2551         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2552         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2553         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2554         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2555         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2556         { }
2557 };
2558 #endif
2559
2560 /*
2561  */
2562
2563 static const char *alc880_models[ALC880_MODEL_LAST] = {
2564         [ALC880_3ST]            = "3stack",
2565         [ALC880_TCL_S700]       = "tcl",
2566         [ALC880_3ST_DIG]        = "3stack-digout",
2567         [ALC880_CLEVO]          = "clevo",
2568         [ALC880_5ST]            = "5stack",
2569         [ALC880_5ST_DIG]        = "5stack-digout",
2570         [ALC880_W810]           = "w810",
2571         [ALC880_Z71V]           = "z71v",
2572         [ALC880_6ST]            = "6stack",
2573         [ALC880_6ST_DIG]        = "6stack-digout",
2574         [ALC880_ASUS]           = "asus",
2575         [ALC880_ASUS_W1V]       = "asus-w1v",
2576         [ALC880_ASUS_DIG]       = "asus-dig",
2577         [ALC880_ASUS_DIG2]      = "asus-dig2",
2578         [ALC880_UNIWILL_DIG]    = "uniwill",
2579         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2580         [ALC880_FUJITSU]        = "fujitsu",
2581         [ALC880_F1734]          = "F1734",
2582         [ALC880_LG]             = "lg",
2583         [ALC880_LG_LW]          = "lg-lw",
2584 #ifdef CONFIG_SND_DEBUG
2585         [ALC880_TEST]           = "test",
2586 #endif
2587         [ALC880_AUTO]           = "auto",
2588 };
2589
2590 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2591         /* Broken BIOS configuration */
2592         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2593         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2594
2595         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2596         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2597         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2598         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2599         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2600         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2601         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2602         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2603         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2604
2605         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2606         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2607
2608         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2609         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2610         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2611         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2612         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2613         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2614         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2615         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2616         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2617         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2618         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2619         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2620         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2621         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2622         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2623
2624         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2625         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2626         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2627         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2628         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2629         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2630         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2631         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2632         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2633         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2634         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2635         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2636         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2637         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2638         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2639         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2640         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2641         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2642
2643         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2644         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2645         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2646         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2647
2648         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2649         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2650         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2651         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2652
2653         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2654         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2655         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2656         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2657
2658         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2659         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2660         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2661         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2662         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2663         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2664         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2665         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2666         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2667         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2668         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2669
2670         {}
2671 };
2672
2673 /*
2674  * ALC880 codec presets
2675  */
2676 static struct alc_config_preset alc880_presets[] = {
2677         [ALC880_3ST] = {
2678                 .mixers = { alc880_three_stack_mixer },
2679                 .init_verbs = { alc880_volume_init_verbs,
2680                                 alc880_pin_3stack_init_verbs },
2681                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2682                 .dac_nids = alc880_dac_nids,
2683                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2684                 .channel_mode = alc880_threestack_modes,
2685                 .need_dac_fix = 1,
2686                 .input_mux = &alc880_capture_source,
2687         },
2688         [ALC880_3ST_DIG] = {
2689                 .mixers = { alc880_three_stack_mixer },
2690                 .init_verbs = { alc880_volume_init_verbs,
2691                                 alc880_pin_3stack_init_verbs },
2692                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2693                 .dac_nids = alc880_dac_nids,
2694                 .dig_out_nid = ALC880_DIGOUT_NID,
2695                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2696                 .channel_mode = alc880_threestack_modes,
2697                 .need_dac_fix = 1,
2698                 .input_mux = &alc880_capture_source,
2699         },
2700         [ALC880_TCL_S700] = {
2701                 .mixers = { alc880_tcl_s700_mixer },
2702                 .init_verbs = { alc880_volume_init_verbs,
2703                                 alc880_pin_tcl_S700_init_verbs,
2704                                 alc880_gpio2_init_verbs },
2705                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2706                 .dac_nids = alc880_dac_nids,
2707                 .hp_nid = 0x03,
2708                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2709                 .channel_mode = alc880_2_jack_modes,
2710                 .input_mux = &alc880_capture_source,
2711         },
2712         [ALC880_5ST] = {
2713                 .mixers = { alc880_three_stack_mixer,
2714                             alc880_five_stack_mixer},
2715                 .init_verbs = { alc880_volume_init_verbs,
2716                                 alc880_pin_5stack_init_verbs },
2717                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2718                 .dac_nids = alc880_dac_nids,
2719                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2720                 .channel_mode = alc880_fivestack_modes,
2721                 .input_mux = &alc880_capture_source,
2722         },
2723         [ALC880_5ST_DIG] = {
2724                 .mixers = { alc880_three_stack_mixer,
2725                             alc880_five_stack_mixer },
2726                 .init_verbs = { alc880_volume_init_verbs,
2727                                 alc880_pin_5stack_init_verbs },
2728                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2729                 .dac_nids = alc880_dac_nids,
2730                 .dig_out_nid = ALC880_DIGOUT_NID,
2731                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2732                 .channel_mode = alc880_fivestack_modes,
2733                 .input_mux = &alc880_capture_source,
2734         },
2735         [ALC880_6ST] = {
2736                 .mixers = { alc880_six_stack_mixer },
2737                 .init_verbs = { alc880_volume_init_verbs,
2738                                 alc880_pin_6stack_init_verbs },
2739                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2740                 .dac_nids = alc880_6st_dac_nids,
2741                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2742                 .channel_mode = alc880_sixstack_modes,
2743                 .input_mux = &alc880_6stack_capture_source,
2744         },
2745         [ALC880_6ST_DIG] = {
2746                 .mixers = { alc880_six_stack_mixer },
2747                 .init_verbs = { alc880_volume_init_verbs,
2748                                 alc880_pin_6stack_init_verbs },
2749                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2750                 .dac_nids = alc880_6st_dac_nids,
2751                 .dig_out_nid = ALC880_DIGOUT_NID,
2752                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2753                 .channel_mode = alc880_sixstack_modes,
2754                 .input_mux = &alc880_6stack_capture_source,
2755         },
2756         [ALC880_W810] = {
2757                 .mixers = { alc880_w810_base_mixer },
2758                 .init_verbs = { alc880_volume_init_verbs,
2759                                 alc880_pin_w810_init_verbs,
2760                                 alc880_gpio2_init_verbs },
2761                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2762                 .dac_nids = alc880_w810_dac_nids,
2763                 .dig_out_nid = ALC880_DIGOUT_NID,
2764                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2765                 .channel_mode = alc880_w810_modes,
2766                 .input_mux = &alc880_capture_source,
2767         },
2768         [ALC880_Z71V] = {
2769                 .mixers = { alc880_z71v_mixer },
2770                 .init_verbs = { alc880_volume_init_verbs,
2771                                 alc880_pin_z71v_init_verbs },
2772                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2773                 .dac_nids = alc880_z71v_dac_nids,
2774                 .dig_out_nid = ALC880_DIGOUT_NID,
2775                 .hp_nid = 0x03,
2776                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2777                 .channel_mode = alc880_2_jack_modes,
2778                 .input_mux = &alc880_capture_source,
2779         },
2780         [ALC880_F1734] = {
2781                 .mixers = { alc880_f1734_mixer },
2782                 .init_verbs = { alc880_volume_init_verbs,
2783                                 alc880_pin_f1734_init_verbs },
2784                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2785                 .dac_nids = alc880_f1734_dac_nids,
2786                 .hp_nid = 0x02,
2787                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2788                 .channel_mode = alc880_2_jack_modes,
2789                 .input_mux = &alc880_capture_source,
2790         },
2791         [ALC880_ASUS] = {
2792                 .mixers = { alc880_asus_mixer },
2793                 .init_verbs = { alc880_volume_init_verbs,
2794                                 alc880_pin_asus_init_verbs,
2795                                 alc880_gpio1_init_verbs },
2796                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2797                 .dac_nids = alc880_asus_dac_nids,
2798                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2799                 .channel_mode = alc880_asus_modes,
2800                 .need_dac_fix = 1,
2801                 .input_mux = &alc880_capture_source,
2802         },
2803         [ALC880_ASUS_DIG] = {
2804                 .mixers = { alc880_asus_mixer },
2805                 .init_verbs = { alc880_volume_init_verbs,
2806                                 alc880_pin_asus_init_verbs,
2807                                 alc880_gpio1_init_verbs },
2808                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2809                 .dac_nids = alc880_asus_dac_nids,
2810                 .dig_out_nid = ALC880_DIGOUT_NID,
2811                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2812                 .channel_mode = alc880_asus_modes,
2813                 .need_dac_fix = 1,
2814                 .input_mux = &alc880_capture_source,
2815         },
2816         [ALC880_ASUS_DIG2] = {
2817                 .mixers = { alc880_asus_mixer },
2818                 .init_verbs = { alc880_volume_init_verbs,
2819                                 alc880_pin_asus_init_verbs,
2820                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2821                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2822                 .dac_nids = alc880_asus_dac_nids,
2823                 .dig_out_nid = ALC880_DIGOUT_NID,
2824                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2825                 .channel_mode = alc880_asus_modes,
2826                 .need_dac_fix = 1,
2827                 .input_mux = &alc880_capture_source,
2828         },
2829         [ALC880_ASUS_W1V] = {
2830                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2831                 .init_verbs = { alc880_volume_init_verbs,
2832                                 alc880_pin_asus_init_verbs,
2833                                 alc880_gpio1_init_verbs },
2834                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2835                 .dac_nids = alc880_asus_dac_nids,
2836                 .dig_out_nid = ALC880_DIGOUT_NID,
2837                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2838                 .channel_mode = alc880_asus_modes,
2839                 .need_dac_fix = 1,
2840                 .input_mux = &alc880_capture_source,
2841         },
2842         [ALC880_UNIWILL_DIG] = {
2843                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2844                 .init_verbs = { alc880_volume_init_verbs,
2845                                 alc880_pin_asus_init_verbs },
2846                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2847                 .dac_nids = alc880_asus_dac_nids,
2848                 .dig_out_nid = ALC880_DIGOUT_NID,
2849                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2850                 .channel_mode = alc880_asus_modes,
2851                 .need_dac_fix = 1,
2852                 .input_mux = &alc880_capture_source,
2853         },
2854         [ALC880_UNIWILL] = {
2855                 .mixers = { alc880_uniwill_mixer },
2856                 .init_verbs = { alc880_volume_init_verbs,
2857                                 alc880_uniwill_init_verbs },
2858                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2859                 .dac_nids = alc880_asus_dac_nids,
2860                 .dig_out_nid = ALC880_DIGOUT_NID,
2861                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2862                 .channel_mode = alc880_threestack_modes,
2863                 .need_dac_fix = 1,
2864                 .input_mux = &alc880_capture_source,
2865                 .unsol_event = alc880_uniwill_unsol_event,
2866                 .init_hook = alc880_uniwill_automute,
2867         },
2868         [ALC880_UNIWILL_P53] = {
2869                 .mixers = { alc880_uniwill_p53_mixer },
2870                 .init_verbs = { alc880_volume_init_verbs,
2871                                 alc880_uniwill_p53_init_verbs },
2872                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2873                 .dac_nids = alc880_asus_dac_nids,
2874                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2875                 .channel_mode = alc880_threestack_modes,
2876                 .input_mux = &alc880_capture_source,
2877                 .unsol_event = alc880_uniwill_p53_unsol_event,
2878                 .init_hook = alc880_uniwill_p53_hp_automute,
2879         },
2880         [ALC880_FUJITSU] = {
2881                 .mixers = { alc880_fujitsu_mixer,
2882                             alc880_pcbeep_mixer, },
2883                 .init_verbs = { alc880_volume_init_verbs,
2884                                 alc880_uniwill_p53_init_verbs,
2885                                 alc880_beep_init_verbs },
2886                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2887                 .dac_nids = alc880_dac_nids,
2888                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2889                 .channel_mode = alc880_2_jack_modes,
2890                 .input_mux = &alc880_capture_source,
2891                 .unsol_event = alc880_uniwill_p53_unsol_event,
2892                 .init_hook = alc880_uniwill_p53_hp_automute,
2893         },
2894         [ALC880_CLEVO] = {
2895                 .mixers = { alc880_three_stack_mixer },
2896                 .init_verbs = { alc880_volume_init_verbs,
2897                                 alc880_pin_clevo_init_verbs },
2898                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2899                 .dac_nids = alc880_dac_nids,
2900                 .hp_nid = 0x03,
2901                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2902                 .channel_mode = alc880_threestack_modes,
2903                 .need_dac_fix = 1,
2904                 .input_mux = &alc880_capture_source,
2905         },
2906         [ALC880_LG] = {
2907                 .mixers = { alc880_lg_mixer },
2908                 .init_verbs = { alc880_volume_init_verbs,
2909                                 alc880_lg_init_verbs },
2910                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2911                 .dac_nids = alc880_lg_dac_nids,
2912                 .dig_out_nid = ALC880_DIGOUT_NID,
2913                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2914                 .channel_mode = alc880_lg_ch_modes,
2915                 .need_dac_fix = 1,
2916                 .input_mux = &alc880_lg_capture_source,
2917                 .unsol_event = alc880_lg_unsol_event,
2918                 .init_hook = alc880_lg_automute,
2919         },
2920         [ALC880_LG_LW] = {
2921                 .mixers = { alc880_lg_lw_mixer },
2922                 .init_verbs = { alc880_volume_init_verbs,
2923                                 alc880_lg_lw_init_verbs },
2924                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2925                 .dac_nids = alc880_dac_nids,
2926                 .dig_out_nid = ALC880_DIGOUT_NID,
2927                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2928                 .channel_mode = alc880_lg_lw_modes,
2929                 .input_mux = &alc880_lg_lw_capture_source,
2930                 .unsol_event = alc880_lg_lw_unsol_event,
2931                 .init_hook = alc880_lg_lw_automute,
2932         },
2933 #ifdef CONFIG_SND_DEBUG
2934         [ALC880_TEST] = {
2935                 .mixers = { alc880_test_mixer },
2936                 .init_verbs = { alc880_test_init_verbs },
2937                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2938                 .dac_nids = alc880_test_dac_nids,
2939                 .dig_out_nid = ALC880_DIGOUT_NID,
2940                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2941                 .channel_mode = alc880_test_modes,
2942                 .input_mux = &alc880_test_capture_source,
2943         },
2944 #endif
2945 };
2946
2947 /*
2948  * Automatic parse of I/O pins from the BIOS configuration
2949  */
2950
2951 #define NUM_CONTROL_ALLOC       32
2952 #define NUM_VERB_ALLOC          32
2953
2954 enum {
2955         ALC_CTL_WIDGET_VOL,
2956         ALC_CTL_WIDGET_MUTE,
2957         ALC_CTL_BIND_MUTE,
2958 };
2959 static struct snd_kcontrol_new alc880_control_templates[] = {
2960         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2961         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2962         HDA_BIND_MUTE(NULL, 0, 0, 0),
2963 };
2964
2965 /* add dynamic controls */
2966 static int add_control(struct alc_spec *spec, int type, const char *name,
2967                        unsigned long val)
2968 {
2969         struct snd_kcontrol_new *knew;
2970
2971         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2972                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2973
2974                 /* array + terminator */
2975                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2976                 if (!knew)
2977                         return -ENOMEM;
2978                 if (spec->kctl_alloc) {
2979                         memcpy(knew, spec->kctl_alloc,
2980                                sizeof(*knew) * spec->num_kctl_alloc);
2981                         kfree(spec->kctl_alloc);
2982                 }
2983                 spec->kctl_alloc = knew;
2984                 spec->num_kctl_alloc = num;
2985         }
2986
2987         knew = &spec->kctl_alloc[spec->num_kctl_used];
2988         *knew = alc880_control_templates[type];
2989         knew->name = kstrdup(name, GFP_KERNEL);
2990         if (!knew->name)
2991                 return -ENOMEM;
2992         knew->private_value = val;
2993         spec->num_kctl_used++;
2994         return 0;
2995 }
2996
2997 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
2998 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
2999 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
3000 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
3001 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
3002 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
3003 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
3004 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
3005 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
3006 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
3007 #define ALC880_PIN_CD_NID               0x1c
3008
3009 /* fill in the dac_nids table from the parsed pin configuration */
3010 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3011                                      const struct auto_pin_cfg *cfg)
3012 {
3013         hda_nid_t nid;
3014         int assigned[4];
3015         int i, j;
3016
3017         memset(assigned, 0, sizeof(assigned));
3018         spec->multiout.dac_nids = spec->private_dac_nids;
3019
3020         /* check the pins hardwired to audio widget */
3021         for (i = 0; i < cfg->line_outs; i++) {
3022                 nid = cfg->line_out_pins[i];
3023                 if (alc880_is_fixed_pin(nid)) {
3024                         int idx = alc880_fixed_pin_idx(nid);
3025                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3026                         assigned[idx] = 1;
3027                 }
3028         }
3029         /* left pins can be connect to any audio widget */
3030         for (i = 0; i < cfg->line_outs; i++) {
3031                 nid = cfg->line_out_pins[i];
3032                 if (alc880_is_fixed_pin(nid))
3033                         continue;
3034                 /* search for an empty channel */
3035                 for (j = 0; j < cfg->line_outs; j++) {
3036                         if (!assigned[j]) {
3037                                 spec->multiout.dac_nids[i] =
3038                                         alc880_idx_to_dac(j);
3039                                 assigned[j] = 1;
3040                                 break;
3041                         }
3042                 }
3043         }
3044         spec->multiout.num_dacs = cfg->line_outs;
3045         return 0;
3046 }
3047
3048 /* add playback controls from the parsed DAC table */
3049 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3050                                              const struct auto_pin_cfg *cfg)
3051 {
3052         char name[32];
3053         static const char *chname[4] = {
3054                 "Front", "Surround", NULL /*CLFE*/, "Side"
3055         };
3056         hda_nid_t nid;
3057         int i, err;
3058
3059         for (i = 0; i < cfg->line_outs; i++) {
3060                 if (!spec->multiout.dac_nids[i])
3061                         continue;
3062                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3063                 if (i == 2) {
3064                         /* Center/LFE */
3065                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3066                                           "Center Playback Volume",
3067                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3068                                                               HDA_OUTPUT));
3069                         if (err < 0)
3070                                 return err;
3071                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3072                                           "LFE Playback Volume",
3073                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3074                                                               HDA_OUTPUT));
3075                         if (err < 0)
3076                                 return err;
3077                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3078                                           "Center Playback Switch",
3079                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3080                                                               HDA_INPUT));
3081                         if (err < 0)
3082                                 return err;
3083                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3084                                           "LFE Playback Switch",
3085                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3086                                                               HDA_INPUT));
3087                         if (err < 0)
3088                                 return err;
3089                 } else {
3090                         sprintf(name, "%s Playback Volume", chname[i]);
3091                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3092                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3093                                                               HDA_OUTPUT));
3094                         if (err < 0)
3095                                 return err;
3096                         sprintf(name, "%s Playback Switch", chname[i]);
3097                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3098                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3099                                                               HDA_INPUT));
3100                         if (err < 0)
3101                                 return err;
3102                 }
3103         }
3104         return 0;
3105 }
3106
3107 /* add playback controls for speaker and HP outputs */
3108 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3109                                         const char *pfx)
3110 {
3111         hda_nid_t nid;
3112         int err;
3113         char name[32];
3114
3115         if (!pin)
3116                 return 0;
3117
3118         if (alc880_is_fixed_pin(pin)) {
3119                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3120                 /* specify the DAC as the extra output */
3121                 if (!spec->multiout.hp_nid)
3122                         spec->multiout.hp_nid = nid;
3123                 else
3124                         spec->multiout.extra_out_nid[0] = nid;
3125                 /* control HP volume/switch on the output mixer amp */
3126                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3127                 sprintf(name, "%s Playback Volume", pfx);
3128                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3129                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3130                 if (err < 0)
3131                         return err;
3132                 sprintf(name, "%s Playback Switch", pfx);
3133                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3134                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3135                 if (err < 0)
3136                         return err;
3137         } else if (alc880_is_multi_pin(pin)) {
3138                 /* set manual connection */
3139                 /* we have only a switch on HP-out PIN */
3140                 sprintf(name, "%s Playback Switch", pfx);
3141                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3142                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3143                 if (err < 0)
3144                         return err;
3145         }
3146         return 0;
3147 }
3148
3149 /* create input playback/capture controls for the given pin */
3150 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3151                             const char *ctlname,
3152                             int idx, hda_nid_t mix_nid)
3153 {
3154         char name[32];
3155         int err;
3156
3157         sprintf(name, "%s Playback Volume", ctlname);
3158         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3159                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3160         if (err < 0)
3161                 return err;
3162         sprintf(name, "%s Playback Switch", ctlname);
3163         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3164                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3165         if (err < 0)
3166                 return err;
3167         return 0;
3168 }
3169
3170 /* create playback/capture controls for input pins */
3171 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3172                                                 const struct auto_pin_cfg *cfg)
3173 {
3174         struct hda_input_mux *imux = &spec->private_imux;
3175         int i, err, idx;
3176
3177         for (i = 0; i < AUTO_PIN_LAST; i++) {
3178                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3179                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3180                         err = new_analog_input(spec, cfg->input_pins[i],
3181                                                auto_pin_cfg_labels[i],
3182                                                idx, 0x0b);
3183                         if (err < 0)
3184                                 return err;
3185                         imux->items[imux->num_items].label =
3186                                 auto_pin_cfg_labels[i];
3187                         imux->items[imux->num_items].index =
3188                                 alc880_input_pin_idx(cfg->input_pins[i]);
3189                         imux->num_items++;
3190                 }
3191         }
3192         return 0;
3193 }
3194
3195 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3196                                               hda_nid_t nid, int pin_type,
3197                                               int dac_idx)
3198 {
3199         /* set as output */
3200         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3201                             pin_type);
3202         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3203                             AMP_OUT_UNMUTE);
3204         /* need the manual connection? */
3205         if (alc880_is_multi_pin(nid)) {
3206                 struct alc_spec *spec = codec->spec;
3207                 int idx = alc880_multi_pin_idx(nid);
3208                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3209                                     AC_VERB_SET_CONNECT_SEL,
3210                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3211         }
3212 }
3213
3214 static int get_pin_type(int line_out_type)
3215 {
3216         if (line_out_type == AUTO_PIN_HP_OUT)
3217                 return PIN_HP;
3218         else
3219                 return PIN_OUT;
3220 }
3221
3222 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3223 {
3224         struct alc_spec *spec = codec->spec;
3225         int i;
3226         
3227         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3228         for (i = 0; i < spec->autocfg.line_outs; i++) {
3229                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3230                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3231                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3232         }
3233 }
3234
3235 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3236 {
3237         struct alc_spec *spec = codec->spec;
3238         hda_nid_t pin;
3239
3240         pin = spec->autocfg.speaker_pins[0];
3241         if (pin) /* connect to front */
3242                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3243         pin = spec->autocfg.hp_pins[0];
3244         if (pin) /* connect to front */
3245                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3246 }
3247
3248 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3249 {
3250         struct alc_spec *spec = codec->spec;
3251         int i;
3252
3253         for (i = 0; i < AUTO_PIN_LAST; i++) {
3254                 hda_nid_t nid = spec->autocfg.input_pins[i];
3255                 if (alc880_is_input_pin(nid)) {
3256                         snd_hda_codec_write(codec, nid, 0,
3257                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3258                                             i <= AUTO_PIN_FRONT_MIC ?
3259                                             PIN_VREF80 : PIN_IN);
3260                         if (nid != ALC880_PIN_CD_NID)
3261                                 snd_hda_codec_write(codec, nid, 0,
3262                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3263                                                     AMP_OUT_MUTE);
3264                 }
3265         }
3266 }
3267
3268 /* parse the BIOS configuration and set up the alc_spec */
3269 /* return 1 if successful, 0 if the proper config is not found,
3270  * or a negative error code
3271  */
3272 static int alc880_parse_auto_config(struct hda_codec *codec)
3273 {
3274         struct alc_spec *spec = codec->spec;
3275         int err;
3276         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3277
3278         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3279                                            alc880_ignore);
3280         if (err < 0)
3281                 return err;
3282         if (!spec->autocfg.line_outs)
3283                 return 0; /* can't find valid BIOS pin config */
3284
3285         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3286         if (err < 0)
3287                 return err;
3288         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3289         if (err < 0)
3290                 return err;
3291         err = alc880_auto_create_extra_out(spec,
3292                                            spec->autocfg.speaker_pins[0],
3293                                            "Speaker");
3294         if (err < 0)
3295                 return err;
3296         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3297                                            "Headphone");
3298         if (err < 0)
3299                 return err;
3300         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3301         if (err < 0)
3302                 return err;
3303
3304         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3305
3306         if (spec->autocfg.dig_out_pin)
3307                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3308         if (spec->autocfg.dig_in_pin)
3309                 spec->dig_in_nid = ALC880_DIGIN_NID;
3310
3311         if (spec->kctl_alloc)
3312                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3313
3314         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3315
3316         spec->num_mux_defs = 1;
3317         spec->input_mux = &spec->private_imux;
3318
3319         return 1;
3320 }
3321
3322 /* additional initialization for auto-configuration model */
3323 static void alc880_auto_init(struct hda_codec *codec)
3324 {
3325         alc880_auto_init_multi_out(codec);
3326         alc880_auto_init_extra_out(codec);
3327         alc880_auto_init_analog_input(codec);
3328 }
3329
3330 /*
3331  * OK, here we have finally the patch for ALC880
3332  */
3333
3334 static int patch_alc880(struct hda_codec *codec)
3335 {
3336         struct alc_spec *spec;
3337         int board_config;
3338         int err;
3339
3340         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3341         if (spec == NULL)
3342                 return -ENOMEM;
3343
3344         codec->spec = spec;
3345
3346         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3347                                                   alc880_models,
3348                                                   alc880_cfg_tbl);
3349         if (board_config < 0) {
3350                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3351                        "trying auto-probe from BIOS...\n");
3352                 board_config = ALC880_AUTO;
3353         }
3354
3355         if (board_config == ALC880_AUTO) {
3356                 /* automatic parse from the BIOS config */
3357                 err = alc880_parse_auto_config(codec);
3358                 if (err < 0) {
3359                         alc_free(codec);
3360                         return err;
3361                 } else if (!err) {
3362                         printk(KERN_INFO
3363                                "hda_codec: Cannot set up configuration "
3364                                "from BIOS.  Using 3-stack mode...\n");
3365                         board_config = ALC880_3ST;
3366                 }
3367         }
3368
3369         if (board_config != ALC880_AUTO)
3370                 setup_preset(spec, &alc880_presets[board_config]);
3371
3372         spec->stream_name_analog = "ALC880 Analog";
3373         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3374         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3375
3376         spec->stream_name_digital = "ALC880 Digital";
3377         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3378         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3379
3380         if (!spec->adc_nids && spec->input_mux) {
3381                 /* check whether NID 0x07 is valid */
3382                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3383                 /* get type */
3384                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3385                 if (wcap != AC_WID_AUD_IN) {
3386                         spec->adc_nids = alc880_adc_nids_alt;
3387                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3388                         spec->mixers[spec->num_mixers] =
3389                                 alc880_capture_alt_mixer;
3390                         spec->num_mixers++;
3391                 } else {
3392                         spec->adc_nids = alc880_adc_nids;
3393                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3394                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3395                         spec->num_mixers++;
3396                 }
3397         }
3398
3399         codec->patch_ops = alc_patch_ops;
3400         if (board_config == ALC880_AUTO)
3401                 spec->init_hook = alc880_auto_init;
3402
3403         return 0;
3404 }
3405
3406
3407 /*
3408  * ALC260 support
3409  */
3410
3411 static hda_nid_t alc260_dac_nids[1] = {
3412         /* front */
3413         0x02,
3414 };
3415
3416 static hda_nid_t alc260_adc_nids[1] = {
3417         /* ADC0 */
3418         0x04,
3419 };
3420
3421 static hda_nid_t alc260_adc_nids_alt[1] = {
3422         /* ADC1 */
3423         0x05,
3424 };
3425
3426 static hda_nid_t alc260_hp_adc_nids[2] = {
3427         /* ADC1, 0 */
3428         0x05, 0x04
3429 };
3430
3431 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3432  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3433  */
3434 static hda_nid_t alc260_dual_adc_nids[2] = {
3435         /* ADC0, ADC1 */
3436         0x04, 0x05
3437 };
3438
3439 #define ALC260_DIGOUT_NID       0x03
3440 #define ALC260_DIGIN_NID        0x06
3441
3442 static struct hda_input_mux alc260_capture_source = {
3443         .num_items = 4,
3444         .items = {
3445                 { "Mic", 0x0 },
3446                 { "Front Mic", 0x1 },
3447                 { "Line", 0x2 },
3448                 { "CD", 0x4 },
3449         },
3450 };
3451
3452 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3453  * headphone jack and the internal CD lines since these are the only pins at
3454  * which audio can appear.  For flexibility, also allow the option of
3455  * recording the mixer output on the second ADC (ADC0 doesn't have a
3456  * connection to the mixer output).
3457  */
3458 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3459         {
3460                 .num_items = 3,
3461                 .items = {
3462                         { "Mic/Line", 0x0 },
3463                         { "CD", 0x4 },
3464                         { "Headphone", 0x2 },
3465                 },
3466         },
3467         {
3468                 .num_items = 4,
3469                 .items = {
3470                         { "Mic/Line", 0x0 },
3471                         { "CD", 0x4 },
3472                         { "Headphone", 0x2 },
3473                         { "Mixer", 0x5 },
3474                 },
3475         },
3476
3477 };
3478
3479 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3480  * the Fujitsu S702x, but jacks are marked differently.
3481  */
3482 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3483         {
3484                 .num_items = 4,
3485                 .items = {
3486                         { "Mic", 0x0 },
3487                         { "Line", 0x2 },
3488                         { "CD", 0x4 },
3489                         { "Headphone", 0x5 },
3490                 },
3491         },
3492         {
3493                 .num_items = 5,
3494                 .items = {
3495                         { "Mic", 0x0 },
3496                         { "Line", 0x2 },
3497                         { "CD", 0x4 },
3498                         { "Headphone", 0x6 },
3499                         { "Mixer", 0x5 },
3500                 },
3501         },
3502 };
3503 /*
3504  * This is just place-holder, so there's something for alc_build_pcms to look
3505  * at when it calculates the maximum number of channels. ALC260 has no mixer
3506  * element which allows changing the channel mode, so the verb list is
3507  * never used.
3508  */
3509 static struct hda_channel_mode alc260_modes[1] = {
3510         { 2, NULL },
3511 };
3512
3513
3514 /* Mixer combinations
3515  *
3516  * basic: base_output + input + pc_beep + capture
3517  * HP: base_output + input + capture_alt
3518  * HP_3013: hp_3013 + input + capture
3519  * fujitsu: fujitsu + capture
3520  * acer: acer + capture
3521  */
3522
3523 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3524         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3525         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3526         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3527         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3528         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3529         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3530         { } /* end */
3531 };
3532
3533 static struct snd_kcontrol_new alc260_input_mixer[] = {
3534         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3535         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3536         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3537         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3538         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3539         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3540         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3541         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3542         { } /* end */
3543 };
3544
3545 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3546         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3547         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3548         { } /* end */
3549 };
3550
3551 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3552         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3553         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3554         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3555         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3556         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3557         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3558         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3559         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3560         { } /* end */
3561 };
3562
3563 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3564  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3565  */
3566 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3567         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3568         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3569         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3570         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3571         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3572         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3573         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3574         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3575         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3576         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3577         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3578         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3579         { } /* end */
3580 };
3581
3582 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3583  * versions of the ALC260 don't act on requests to enable mic bias from NID
3584  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3585  * datasheet doesn't mention this restriction.  At this stage it's not clear
3586  * whether this behaviour is intentional or is a hardware bug in chip
3587  * revisions available in early 2006.  Therefore for now allow the
3588  * "Headphone Jack Mode" control to span all choices, but if it turns out
3589  * that the lack of mic bias for this NID is intentional we could change the
3590  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3591  *
3592  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3593  * don't appear to make the mic bias available from the "line" jack, even
3594  * though the NID used for this jack (0x14) can supply it.  The theory is
3595  * that perhaps Acer have included blocking capacitors between the ALC260
3596  * and the output jack.  If this turns out to be the case for all such
3597  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3598  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3599  *
3600  * The C20x Tablet series have a mono internal speaker which is controlled
3601  * via the chip's Mono sum widget and pin complex, so include the necessary
3602  * controls for such models.  On models without a "mono speaker" the control
3603  * won't do anything.
3604  */
3605 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3606         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3607         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3608         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3609         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3610                               HDA_OUTPUT),
3611         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3612                            HDA_INPUT),
3613         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3614         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3615         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3616         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3617         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3618         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3619         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3620         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3621         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3622         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3623         { } /* end */
3624 };
3625
3626 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3627  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3628  */
3629 static struct snd_kcontrol_new alc260_will_mixer[] = {
3630         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3631         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3632         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3633         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3634         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3635         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3636         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3637         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3638         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3639         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3640         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3641         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3642         { } /* end */
3643 };
3644
3645 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3646  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3647  */
3648 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3649         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3650         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3651         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3652         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3653         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3654         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3655         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3656         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3657         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3658         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3659         { } /* end */
3660 };
3661
3662 /* capture mixer elements */
3663 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3664         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3665         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3666         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3667         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3668         {
3669                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3670                 /* The multiple "Capture Source" controls confuse alsamixer
3671                  * So call somewhat different..
3672                  * FIXME: the controls appear in the "playback" view!
3673                  */
3674                 /* .name = "Capture Source", */
3675                 .name = "Input Source",
3676                 .count = 2,
3677                 .info = alc_mux_enum_info,
3678                 .get = alc_mux_enum_get,
3679                 .put = alc_mux_enum_put,
3680         },
3681         { } /* end */
3682 };
3683
3684 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3685         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3686         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3687         {
3688                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3689                 /* The multiple "Capture Source" controls confuse alsamixer
3690                  * So call somewhat different..
3691                  * FIXME: the controls appear in the "playback" view!
3692                  */
3693                 /* .name = "Capture Source", */
3694                 .name = "Input Source",
3695                 .count = 1,
3696                 .info = alc_mux_enum_info,
3697                 .get = alc_mux_enum_get,
3698                 .put = alc_mux_enum_put,
3699         },
3700         { } /* end */
3701 };
3702
3703 /*
3704  * initialization verbs
3705  */
3706 static struct hda_verb alc260_init_verbs[] = {
3707         /* Line In pin widget for input */
3708         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3709         /* CD pin widget for input */
3710         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3711         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3712         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3713         /* Mic2 (front panel) pin widget for input and vref at 80% */
3714         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3715         /* LINE-2 is used for line-out in rear */
3716         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3717         /* select line-out */
3718         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3719         /* LINE-OUT pin */
3720         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3721         /* enable HP */
3722         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3723         /* enable Mono */
3724         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3725         /* mute capture amp left and right */
3726         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3727         /* set connection select to line in (default select for this ADC) */
3728         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3729         /* mute capture amp left and right */
3730         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3731         /* set connection select to line in (default select for this ADC) */
3732         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3733         /* set vol=0 Line-Out mixer amp left and right */
3734         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3735         /* unmute pin widget amp left and right (no gain on this amp) */
3736         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3737         /* set vol=0 HP mixer amp left and right */
3738         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3739         /* unmute pin widget amp left and right (no gain on this amp) */
3740         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3741         /* set vol=0 Mono mixer amp left and right */
3742         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3743         /* unmute pin widget amp left and right (no gain on this amp) */
3744         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3745         /* unmute LINE-2 out pin */
3746         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3747         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3748          * Line In 2 = 0x03
3749          */
3750         /* mute CD */
3751         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3752         /* mute Line In */
3753         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3754         /* mute Mic */
3755         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3756         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3757         /* mute Front out path */
3758         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3759         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3760         /* mute Headphone out path */
3761         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3762         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3763         /* mute Mono out path */
3764         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3765         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3766         { }
3767 };
3768
3769 #if 0 /* should be identical with alc260_init_verbs? */
3770 static struct hda_verb alc260_hp_init_verbs[] = {
3771         /* Headphone and output */
3772         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3773         /* mono output */
3774         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3775         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3776         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3777         /* Mic2 (front panel) pin widget for input and vref at 80% */
3778         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3779         /* Line In pin widget for input */
3780         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3781         /* Line-2 pin widget for output */
3782         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3783         /* CD pin widget for input */
3784         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3785         /* unmute amp left and right */
3786         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3787         /* set connection select to line in (default select for this ADC) */
3788         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3789         /* unmute Line-Out mixer amp left and right (volume = 0) */
3790         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3791         /* mute pin widget amp left and right (no gain on this amp) */
3792         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3793         /* unmute HP mixer amp left and right (volume = 0) */
3794         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3795         /* mute pin widget amp left and right (no gain on this amp) */
3796         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3797         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3798          * Line In 2 = 0x03
3799          */
3800         /* unmute CD */
3801         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3802         /* unmute Line In */
3803         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3804         /* unmute Mic */
3805         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3806         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3807         /* Unmute Front out path */
3808         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3809         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3810         /* Unmute Headphone out path */
3811         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3812         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3813         /* Unmute Mono out path */
3814         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3815         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3816         { }
3817 };
3818 #endif
3819
3820 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3821         /* Line out and output */
3822         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3823         /* mono output */
3824         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3825         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3826         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3827         /* Mic2 (front panel) pin widget for input and vref at 80% */
3828         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3829         /* Line In pin widget for input */
3830         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3831         /* Headphone pin widget for output */
3832         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3833         /* CD pin widget for input */
3834         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3835         /* unmute amp left and right */
3836         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3837         /* set connection select to line in (default select for this ADC) */
3838         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3839         /* unmute Line-Out mixer amp left and right (volume = 0) */
3840         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3841         /* mute pin widget amp left and right (no gain on this amp) */
3842         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3843         /* unmute HP mixer amp left and right (volume = 0) */
3844         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3845         /* mute pin widget amp left and right (no gain on this amp) */
3846         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3847         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3848          * Line In 2 = 0x03
3849          */
3850         /* unmute CD */
3851         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3852         /* unmute Line In */
3853         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3854         /* unmute Mic */
3855         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3856         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3857         /* Unmute Front out path */
3858         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3859         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3860         /* Unmute Headphone out path */
3861         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3862         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3863         /* Unmute Mono out path */
3864         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3865         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3866         { }
3867 };
3868
3869 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3870  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3871  * audio = 0x16, internal speaker = 0x10.
3872  */
3873 static struct hda_verb alc260_fujitsu_init_verbs[] = {
3874         /* Disable all GPIOs */
3875         {0x01, AC_VERB_SET_GPIO_MASK, 0},
3876         /* Internal speaker is connected to headphone pin */
3877         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3878         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3879         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3880         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3881         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3882         /* Ensure all other unused pins are disabled and muted. */
3883         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3884         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3885         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3886         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3887         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3888         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3889         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3890         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3891
3892         /* Disable digital (SPDIF) pins */
3893         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3894         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3895
3896         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
3897          * when acting as an output.
3898          */
3899         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3900
3901         /* Start with output sum widgets muted and their output gains at min */
3902         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3903         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3904         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3905         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3906         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3907         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3908         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3909         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3910         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3911
3912         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3913         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3914         /* Unmute Line1 pin widget output buffer since it starts as an output.
3915          * If the pin mode is changed by the user the pin mode control will
3916          * take care of enabling the pin's input/output buffers as needed.
3917          * Therefore there's no need to enable the input buffer at this
3918          * stage.
3919          */
3920         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3921         /* Unmute input buffer of pin widget used for Line-in (no equiv 
3922          * mixer ctrl)
3923          */
3924         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3925
3926         /* Mute capture amp left and right */
3927         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3928         /* Set ADC connection select to match default mixer setting - line 
3929          * in (on mic1 pin)
3930          */
3931         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3932
3933         /* Do the same for the second ADC: mute capture input amp and
3934          * set ADC connection to line in (on mic1 pin)
3935          */
3936         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3937         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3938
3939         /* Mute all inputs to mixer widget (even unconnected ones) */
3940         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3941         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3942         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3943         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3944         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3945         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3946         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3947         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3948
3949         { }
3950 };
3951
3952 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3953  * similar laptops (adapted from Fujitsu init verbs).
3954  */
3955 static struct hda_verb alc260_acer_init_verbs[] = {
3956         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3957          * the headphone jack.  Turn this on and rely on the standard mute
3958          * methods whenever the user wants to turn these outputs off.
3959          */
3960         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3961         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3962         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3963         /* Internal speaker/Headphone jack is connected to Line-out pin */
3964         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3965         /* Internal microphone/Mic jack is connected to Mic1 pin */
3966         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3967         /* Line In jack is connected to Line1 pin */
3968         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3969         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3970         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3971         /* Ensure all other unused pins are disabled and muted. */
3972         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3973         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3974         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3975         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3976         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3977         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3978         /* Disable digital (SPDIF) pins */
3979         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3980         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3981
3982         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
3983          * bus when acting as outputs.
3984          */
3985         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3986         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3987
3988         /* Start with output sum widgets muted and their output gains at min */
3989         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3990         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3991         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3992         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3993         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3994         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3995         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3996         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3997         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3998
3999         /* Unmute Line-out pin widget amp left and right
4000          * (no equiv mixer ctrl)
4001          */
4002         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4003         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4004         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4005         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4006          * inputs. If the pin mode is changed by the user the pin mode control
4007          * will take care of enabling the pin's input/output buffers as needed.
4008          * Therefore there's no need to enable the input buffer at this
4009          * stage.
4010          */
4011         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4012         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4013
4014         /* Mute capture amp left and right */
4015         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4016         /* Set ADC connection select to match default mixer setting - mic
4017          * (on mic1 pin)
4018          */
4019         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4020
4021         /* Do similar with the second ADC: mute capture input amp and
4022          * set ADC connection to mic to match ALSA's default state.
4023          */
4024         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4025         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4026
4027         /* Mute all inputs to mixer widget (even unconnected ones) */
4028         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4029         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4030         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4031         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4032         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4033         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4034         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4035         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4036
4037         { }
4038 };
4039
4040 static struct hda_verb alc260_will_verbs[] = {
4041         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4042         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4043         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4044         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4045         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4046         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4047         {}
4048 };
4049
4050 static struct hda_verb alc260_replacer_672v_verbs[] = {
4051         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4052         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4053         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4054
4055         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4056         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4057         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4058
4059         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4060         {}
4061 };
4062
4063 /* toggle speaker-output according to the hp-jack state */
4064 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4065 {
4066         unsigned int present;
4067
4068         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4069         present = snd_hda_codec_read(codec, 0x0f, 0,
4070                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4071         if (present) {
4072                 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
4073                 snd_hda_codec_write(codec, 0x0f, 0,
4074                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4075         } else {
4076                 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4077                 snd_hda_codec_write(codec, 0x0f, 0,
4078                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4079         }
4080 }
4081
4082 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4083                                        unsigned int res)
4084 {
4085         if ((res >> 26) == ALC880_HP_EVENT)
4086                 alc260_replacer_672v_automute(codec);
4087 }
4088
4089 /* Test configuration for debugging, modelled after the ALC880 test
4090  * configuration.
4091  */
4092 #ifdef CONFIG_SND_DEBUG
4093 static hda_nid_t alc260_test_dac_nids[1] = {
4094         0x02,
4095 };
4096 static hda_nid_t alc260_test_adc_nids[2] = {
4097         0x04, 0x05,
4098 };
4099 /* For testing the ALC260, each input MUX needs its own definition since
4100  * the signal assignments are different.  This assumes that the first ADC 
4101  * is NID 0x04.
4102  */
4103 static struct hda_input_mux alc260_test_capture_sources[2] = {
4104         {
4105                 .num_items = 7,
4106                 .items = {
4107                         { "MIC1 pin", 0x0 },
4108                         { "MIC2 pin", 0x1 },
4109                         { "LINE1 pin", 0x2 },
4110                         { "LINE2 pin", 0x3 },
4111                         { "CD pin", 0x4 },
4112                         { "LINE-OUT pin", 0x5 },
4113                         { "HP-OUT pin", 0x6 },
4114                 },
4115         },
4116         {
4117                 .num_items = 8,
4118                 .items = {
4119                         { "MIC1 pin", 0x0 },
4120                         { "MIC2 pin", 0x1 },
4121                         { "LINE1 pin", 0x2 },
4122                         { "LINE2 pin", 0x3 },
4123                         { "CD pin", 0x4 },
4124                         { "Mixer", 0x5 },
4125                         { "LINE-OUT pin", 0x6 },
4126                         { "HP-OUT pin", 0x7 },
4127                 },
4128         },
4129 };
4130 static struct snd_kcontrol_new alc260_test_mixer[] = {
4131         /* Output driver widgets */
4132         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4133         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4134         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4135         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4136         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4137         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4138
4139         /* Modes for retasking pin widgets
4140          * Note: the ALC260 doesn't seem to act on requests to enable mic
4141          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4142          * mention this restriction.  At this stage it's not clear whether
4143          * this behaviour is intentional or is a hardware bug in chip
4144          * revisions available at least up until early 2006.  Therefore for
4145          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4146          * choices, but if it turns out that the lack of mic bias for these
4147          * NIDs is intentional we could change their modes from
4148          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4149          */
4150         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4151         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4152         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4153         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4154         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4155         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4156
4157         /* Loopback mixer controls */
4158         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4159         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4160         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4161         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4162         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4163         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4164         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4165         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4166         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4167         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4168         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4169         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4170         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4171         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4172         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4173         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4174
4175         /* Controls for GPIO pins, assuming they are configured as outputs */
4176         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4177         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4178         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4179         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4180
4181         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4182          * is ambigious as to which NID is which; testing on laptops which
4183          * make this output available should provide clarification. 
4184          */
4185         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4186         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4187
4188         { } /* end */
4189 };
4190 static struct hda_verb alc260_test_init_verbs[] = {
4191         /* Enable all GPIOs as outputs with an initial value of 0 */
4192         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4193         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4194         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4195
4196         /* Enable retasking pins as output, initially without power amp */
4197         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4198         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4199         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4200         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4201         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4202         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4203
4204         /* Disable digital (SPDIF) pins initially, but users can enable
4205          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4206          * payload also sets the generation to 0, output to be in "consumer"
4207          * PCM format, copyright asserted, no pre-emphasis and no validity
4208          * control.
4209          */
4210         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4211         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4212
4213         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4214          * OUT1 sum bus when acting as an output.
4215          */
4216         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4217         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4218         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4219         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4220
4221         /* Start with output sum widgets muted and their output gains at min */
4222         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4223         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4224         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4225         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4226         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4227         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4228         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4229         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4230         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4231
4232         /* Unmute retasking pin widget output buffers since the default
4233          * state appears to be output.  As the pin mode is changed by the
4234          * user the pin mode control will take care of enabling the pin's
4235          * input/output buffers as needed.
4236          */
4237         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4238         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4239         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4240         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4241         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4242         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4243         /* Also unmute the mono-out pin widget */
4244         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4245
4246         /* Mute capture amp left and right */
4247         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4248         /* Set ADC connection select to match default mixer setting (mic1
4249          * pin)
4250          */
4251         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4252
4253         /* Do the same for the second ADC: mute capture input amp and
4254          * set ADC connection to mic1 pin
4255          */
4256         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4257         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4258
4259         /* Mute all inputs to mixer widget (even unconnected ones) */
4260         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4261         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4262         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4263         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4264         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4265         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4266         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4267         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4268
4269         { }
4270 };
4271 #endif
4272
4273 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4274         .substreams = 1,
4275         .channels_min = 2,
4276         .channels_max = 2,
4277 };
4278
4279 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4280         .substreams = 1,
4281         .channels_min = 2,
4282         .channels_max = 2,
4283 };
4284
4285 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4286 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4287
4288 /*
4289  * for BIOS auto-configuration
4290  */
4291
4292 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4293                                         const char *pfx)
4294 {
4295         hda_nid_t nid_vol;
4296         unsigned long vol_val, sw_val;
4297         char name[32];
4298         int err;
4299
4300         if (nid >= 0x0f && nid < 0x11) {
4301                 nid_vol = nid - 0x7;
4302                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4303                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4304         } else if (nid == 0x11) {
4305                 nid_vol = nid - 0x7;
4306                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4307                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4308         } else if (nid >= 0x12 && nid <= 0x15) {
4309                 nid_vol = 0x08;
4310                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4311                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4312         } else
4313                 return 0; /* N/A */
4314         
4315         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4316         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4317         if (err < 0)
4318                 return err;
4319         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4320         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4321         if (err < 0)
4322                 return err;
4323         return 1;
4324 }
4325
4326 /* add playback controls from the parsed DAC table */
4327 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4328                                              const struct auto_pin_cfg *cfg)
4329 {
4330         hda_nid_t nid;
4331         int err;
4332
4333         spec->multiout.num_dacs = 1;
4334         spec->multiout.dac_nids = spec->private_dac_nids;
4335         spec->multiout.dac_nids[0] = 0x02;
4336
4337         nid = cfg->line_out_pins[0];
4338         if (nid) {
4339                 err = alc260_add_playback_controls(spec, nid, "Front");
4340                 if (err < 0)
4341                         return err;
4342         }
4343
4344         nid = cfg->speaker_pins[0];
4345         if (nid) {
4346                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4347                 if (err < 0)
4348                         return err;
4349         }
4350
4351         nid = cfg->hp_pins[0];
4352         if (nid) {
4353                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4354                 if (err < 0)
4355                         return err;
4356         }
4357         return 0;
4358 }
4359
4360 /* create playback/capture controls for input pins */
4361 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4362                                                 const struct auto_pin_cfg *cfg)
4363 {
4364         struct hda_input_mux *imux = &spec->private_imux;
4365         int i, err, idx;
4366
4367         for (i = 0; i < AUTO_PIN_LAST; i++) {
4368                 if (cfg->input_pins[i] >= 0x12) {
4369                         idx = cfg->input_pins[i] - 0x12;
4370                         err = new_analog_input(spec, cfg->input_pins[i],
4371                                                auto_pin_cfg_labels[i], idx,
4372                                                0x07);
4373                         if (err < 0)
4374                                 return err;
4375                         imux->items[imux->num_items].label =
4376                                 auto_pin_cfg_labels[i];
4377                         imux->items[imux->num_items].index = idx;
4378                         imux->num_items++;
4379                 }
4380                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4381                         idx = cfg->input_pins[i] - 0x09;
4382                         err = new_analog_input(spec, cfg->input_pins[i],
4383                                                auto_pin_cfg_labels[i], idx,
4384                                                0x07);
4385                         if (err < 0)
4386                                 return err;
4387                         imux->items[imux->num_items].label =
4388                                 auto_pin_cfg_labels[i];
4389                         imux->items[imux->num_items].index = idx;
4390                         imux->num_items++;
4391                 }
4392         }
4393         return 0;
4394 }
4395
4396 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4397                                               hda_nid_t nid, int pin_type,
4398                                               int sel_idx)
4399 {
4400         /* set as output */
4401         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4402                             pin_type);
4403         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4404                             AMP_OUT_UNMUTE);
4405         /* need the manual connection? */
4406         if (nid >= 0x12) {
4407                 int idx = nid - 0x12;
4408                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4409                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4410         }
4411 }
4412
4413 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4414 {
4415         struct alc_spec *spec = codec->spec;
4416         hda_nid_t nid;
4417
4418         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4419         nid = spec->autocfg.line_out_pins[0];
4420         if (nid) {
4421                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4422                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4423         }
4424         
4425         nid = spec->autocfg.speaker_pins[0];
4426         if (nid)
4427                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4428
4429         nid = spec->autocfg.hp_pins[0];
4430         if (nid)
4431                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4432 }
4433
4434 #define ALC260_PIN_CD_NID               0x16
4435 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4436 {
4437         struct alc_spec *spec = codec->spec;
4438         int i;
4439
4440         for (i = 0; i < AUTO_PIN_LAST; i++) {
4441                 hda_nid_t nid = spec->autocfg.input_pins[i];
4442                 if (nid >= 0x12) {
4443                         snd_hda_codec_write(codec, nid, 0,
4444                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4445                                             i <= AUTO_PIN_FRONT_MIC ?
4446                                             PIN_VREF80 : PIN_IN);
4447                         if (nid != ALC260_PIN_CD_NID)
4448                                 snd_hda_codec_write(codec, nid, 0,
4449                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4450                                                     AMP_OUT_MUTE);
4451                 }
4452         }
4453 }
4454
4455 /*
4456  * generic initialization of ADC, input mixers and output mixers
4457  */
4458 static struct hda_verb alc260_volume_init_verbs[] = {
4459         /*
4460          * Unmute ADC0-1 and set the default input to mic-in
4461          */
4462         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4463         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4464         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4465         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4466         
4467         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4468          * mixer widget
4469          * Note: PASD motherboards uses the Line In 2 as the input for
4470          * front panel mic (mic 2)
4471          */
4472         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4473         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4474         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4475         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4476         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4477         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4478
4479         /*
4480          * Set up output mixers (0x08 - 0x0a)
4481          */
4482         /* set vol=0 to output mixers */
4483         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4484         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4485         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4486         /* set up input amps for analog loopback */
4487         /* Amp Indices: DAC = 0, mixer = 1 */
4488         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4489         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4490         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4491         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4492         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4493         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4494         
4495         { }
4496 };
4497
4498 static int alc260_parse_auto_config(struct hda_codec *codec)
4499 {
4500         struct alc_spec *spec = codec->spec;
4501         unsigned int wcap;
4502         int err;
4503         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4504
4505         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4506                                            alc260_ignore);
4507         if (err < 0)
4508                 return err;
4509         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4510         if (err < 0)
4511                 return err;
4512         if (!spec->kctl_alloc)
4513                 return 0; /* can't find valid BIOS pin config */
4514         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4515         if (err < 0)
4516                 return err;
4517
4518         spec->multiout.max_channels = 2;
4519
4520         if (spec->autocfg.dig_out_pin)
4521                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4522         if (spec->kctl_alloc)
4523                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4524
4525         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4526
4527         spec->num_mux_defs = 1;
4528         spec->input_mux = &spec->private_imux;
4529
4530         /* check whether NID 0x04 is valid */
4531         wcap = get_wcaps(codec, 0x04);
4532         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4533         if (wcap != AC_WID_AUD_IN) {
4534                 spec->adc_nids = alc260_adc_nids_alt;
4535                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4536                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4537         } else {
4538                 spec->adc_nids = alc260_adc_nids;
4539                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4540                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4541         }
4542         spec->num_mixers++;
4543
4544         return 1;
4545 }
4546
4547 /* additional initialization for auto-configuration model */
4548 static void alc260_auto_init(struct hda_codec *codec)
4549 {
4550         alc260_auto_init_multi_out(codec);
4551         alc260_auto_init_analog_input(codec);
4552 }
4553
4554 /*
4555  * ALC260 configurations
4556  */
4557 static const char *alc260_models[ALC260_MODEL_LAST] = {
4558         [ALC260_BASIC]          = "basic",
4559         [ALC260_HP]             = "hp",
4560         [ALC260_HP_3013]        = "hp-3013",
4561         [ALC260_FUJITSU_S702X]  = "fujitsu",
4562         [ALC260_ACER]           = "acer",
4563         [ALC260_WILL]           = "will",
4564         [ALC260_REPLACER_672V]  = "replacer",
4565 #ifdef CONFIG_SND_DEBUG
4566         [ALC260_TEST]           = "test",
4567 #endif
4568         [ALC260_AUTO]           = "auto",
4569 };
4570
4571 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4572         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4573         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4574         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4575         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4576         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4577         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4578         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4579         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4580         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4581         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4582         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4583         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4584         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4585         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4586         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4587         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4588         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4589         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4590         {}
4591 };
4592
4593 static struct alc_config_preset alc260_presets[] = {
4594         [ALC260_BASIC] = {
4595                 .mixers = { alc260_base_output_mixer,
4596                             alc260_input_mixer,
4597                             alc260_pc_beep_mixer,
4598                             alc260_capture_mixer },
4599                 .init_verbs = { alc260_init_verbs },
4600                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4601                 .dac_nids = alc260_dac_nids,
4602                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4603                 .adc_nids = alc260_adc_nids,
4604                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4605                 .channel_mode = alc260_modes,
4606                 .input_mux = &alc260_capture_source,
4607         },
4608         [ALC260_HP] = {
4609                 .mixers = { alc260_base_output_mixer,
4610                             alc260_input_mixer,
4611                             alc260_capture_alt_mixer },
4612                 .init_verbs = { alc260_init_verbs },
4613                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4614                 .dac_nids = alc260_dac_nids,
4615                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4616                 .adc_nids = alc260_hp_adc_nids,
4617                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4618                 .channel_mode = alc260_modes,
4619                 .input_mux = &alc260_capture_source,
4620         },
4621         [ALC260_HP_3013] = {
4622                 .mixers = { alc260_hp_3013_mixer,
4623                             alc260_input_mixer,
4624                             alc260_capture_alt_mixer },
4625                 .init_verbs = { alc260_hp_3013_init_verbs },
4626                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4627                 .dac_nids = alc260_dac_nids,
4628                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4629                 .adc_nids = alc260_hp_adc_nids,
4630                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4631                 .channel_mode = alc260_modes,
4632                 .input_mux = &alc260_capture_source,
4633         },
4634         [ALC260_FUJITSU_S702X] = {
4635                 .mixers = { alc260_fujitsu_mixer,
4636                             alc260_capture_mixer },
4637                 .init_verbs = { alc260_fujitsu_init_verbs },
4638                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4639                 .dac_nids = alc260_dac_nids,
4640                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4641                 .adc_nids = alc260_dual_adc_nids,
4642                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4643                 .channel_mode = alc260_modes,
4644                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4645                 .input_mux = alc260_fujitsu_capture_sources,
4646         },
4647         [ALC260_ACER] = {
4648                 .mixers = { alc260_acer_mixer,
4649                             alc260_capture_mixer },
4650                 .init_verbs = { alc260_acer_init_verbs },
4651                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4652                 .dac_nids = alc260_dac_nids,
4653                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4654                 .adc_nids = alc260_dual_adc_nids,
4655                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4656                 .channel_mode = alc260_modes,
4657                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4658                 .input_mux = alc260_acer_capture_sources,
4659         },
4660         [ALC260_WILL] = {
4661                 .mixers = { alc260_will_mixer,
4662                             alc260_capture_mixer },
4663                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4664                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4665                 .dac_nids = alc260_dac_nids,
4666                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4667                 .adc_nids = alc260_adc_nids,
4668                 .dig_out_nid = ALC260_DIGOUT_NID,
4669                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4670                 .channel_mode = alc260_modes,
4671                 .input_mux = &alc260_capture_source,
4672         },
4673         [ALC260_REPLACER_672V] = {
4674                 .mixers = { alc260_replacer_672v_mixer,
4675                             alc260_capture_mixer },
4676                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4677                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4678                 .dac_nids = alc260_dac_nids,
4679                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4680                 .adc_nids = alc260_adc_nids,
4681                 .dig_out_nid = ALC260_DIGOUT_NID,
4682                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4683                 .channel_mode = alc260_modes,
4684                 .input_mux = &alc260_capture_source,
4685                 .unsol_event = alc260_replacer_672v_unsol_event,
4686                 .init_hook = alc260_replacer_672v_automute,
4687         },
4688 #ifdef CONFIG_SND_DEBUG
4689         [ALC260_TEST] = {
4690                 .mixers = { alc260_test_mixer,
4691                             alc260_capture_mixer },
4692                 .init_verbs = { alc260_test_init_verbs },
4693                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4694                 .dac_nids = alc260_test_dac_nids,
4695                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4696                 .adc_nids = alc260_test_adc_nids,
4697                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4698                 .channel_mode = alc260_modes,
4699                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4700                 .input_mux = alc260_test_capture_sources,
4701         },
4702 #endif
4703 };
4704
4705 static int patch_alc260(struct hda_codec *codec)
4706 {
4707         struct alc_spec *spec;
4708         int err, board_config;
4709
4710         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4711         if (spec == NULL)
4712                 return -ENOMEM;
4713
4714         codec->spec = spec;
4715
4716         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4717                                                   alc260_models,
4718                                                   alc260_cfg_tbl);
4719         if (board_config < 0) {
4720                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4721                            "trying auto-probe from BIOS...\n");
4722                 board_config = ALC260_AUTO;
4723         }
4724
4725         if (board_config == ALC260_AUTO) {
4726                 /* automatic parse from the BIOS config */
4727                 err = alc260_parse_auto_config(codec);
4728                 if (err < 0) {
4729                         alc_free(codec);
4730                         return err;
4731                 } else if (!err) {
4732                         printk(KERN_INFO
4733                                "hda_codec: Cannot set up configuration "
4734                                "from BIOS.  Using base mode...\n");
4735                         board_config = ALC260_BASIC;
4736                 }
4737         }
4738
4739         if (board_config != ALC260_AUTO)
4740                 setup_preset(spec, &alc260_presets[board_config]);
4741
4742         spec->stream_name_analog = "ALC260 Analog";
4743         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4744         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4745
4746         spec->stream_name_digital = "ALC260 Digital";
4747         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4748         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4749
4750         codec->patch_ops = alc_patch_ops;
4751         if (board_config == ALC260_AUTO)
4752                 spec->init_hook = alc260_auto_init;
4753
4754         return 0;
4755 }
4756
4757
4758 /*
4759  * ALC882 support
4760  *
4761  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4762  * configuration.  Each pin widget can choose any input DACs and a mixer.
4763  * Each ADC is connected from a mixer of all inputs.  This makes possible
4764  * 6-channel independent captures.
4765  *
4766  * In addition, an independent DAC for the multi-playback (not used in this
4767  * driver yet).
4768  */
4769 #define ALC882_DIGOUT_NID       0x06
4770 #define ALC882_DIGIN_NID        0x0a
4771
4772 static struct hda_channel_mode alc882_ch_modes[1] = {
4773         { 8, NULL }
4774 };
4775
4776 static hda_nid_t alc882_dac_nids[4] = {
4777         /* front, rear, clfe, rear_surr */
4778         0x02, 0x03, 0x04, 0x05
4779 };
4780
4781 /* identical with ALC880 */
4782 #define alc882_adc_nids         alc880_adc_nids
4783 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4784
4785 /* input MUX */
4786 /* FIXME: should be a matrix-type input source selection */
4787
4788 static struct hda_input_mux alc882_capture_source = {
4789         .num_items = 4,
4790         .items = {
4791                 { "Mic", 0x0 },
4792                 { "Front Mic", 0x1 },
4793                 { "Line", 0x2 },
4794                 { "CD", 0x4 },
4795         },
4796 };
4797 #define alc882_mux_enum_info alc_mux_enum_info
4798 #define alc882_mux_enum_get alc_mux_enum_get
4799
4800 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4801                                struct snd_ctl_elem_value *ucontrol)
4802 {
4803         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4804         struct alc_spec *spec = codec->spec;
4805         const struct hda_input_mux *imux = spec->input_mux;
4806         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4807         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4808         hda_nid_t nid = capture_mixers[adc_idx];
4809         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4810         unsigned int i, idx;
4811
4812         idx = ucontrol->value.enumerated.item[0];
4813         if (idx >= imux->num_items)
4814                 idx = imux->num_items - 1;
4815         if (*cur_val == idx && !codec->in_resume)
4816                 return 0;
4817         for (i = 0; i < imux->num_items; i++) {
4818                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4819                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4820                                     v | (imux->items[i].index << 8));
4821         }
4822         *cur_val = idx;
4823         return 1;
4824 }
4825
4826 /*
4827  * 2ch mode
4828  */
4829 static struct hda_verb alc882_3ST_ch2_init[] = {
4830         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4831         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4832         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4833         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4834         { } /* end */
4835 };
4836
4837 /*
4838  * 6ch mode
4839  */
4840 static struct hda_verb alc882_3ST_ch6_init[] = {
4841         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4842         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4843         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4844         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4845         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4846         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4847         { } /* end */
4848 };
4849
4850 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4851         { 2, alc882_3ST_ch2_init },
4852         { 6, alc882_3ST_ch6_init },
4853 };
4854
4855 /*
4856  * 6ch mode
4857  */
4858 static struct hda_verb alc882_sixstack_ch6_init[] = {
4859         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4860         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4861         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4862         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4863         { } /* end */
4864 };
4865
4866 /*
4867  * 8ch mode
4868  */
4869 static struct hda_verb alc882_sixstack_ch8_init[] = {
4870         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4871         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4872         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4873         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4874         { } /* end */
4875 };
4876
4877 static struct hda_channel_mode alc882_sixstack_modes[2] = {
4878         { 6, alc882_sixstack_ch6_init },
4879         { 8, alc882_sixstack_ch8_init },
4880 };
4881
4882 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4883  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4884  */
4885 static struct snd_kcontrol_new alc882_base_mixer[] = {
4886         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4887         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4888         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4889         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4890         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4891         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4892         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4893         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4894         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4895         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4896         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4897         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4898         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4899         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4900         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4901         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4902         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4903         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4904         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4905         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4906         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4907         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4908         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4909         { } /* end */
4910 };
4911
4912 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4913         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4914         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4915         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4916         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4917         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4918         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4919         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4920         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4921         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4922         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4923         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4924         { } /* end */
4925 };
4926
4927 static struct snd_kcontrol_new alc882_targa_mixer[] = {
4928         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4929         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4930         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4931         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4932         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4933         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4934         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4935         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4936         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4937         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4938         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4939         { } /* end */
4940 };
4941
4942 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4943  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4944  */
4945 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4946         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4947         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4948         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4949         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4950         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4951         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4952         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4953         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4954         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4955         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4956         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4957         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4958         { } /* end */
4959 };
4960
4961 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4962         {
4963                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4964                 .name = "Channel Mode",
4965                 .info = alc_ch_mode_info,
4966                 .get = alc_ch_mode_get,
4967                 .put = alc_ch_mode_put,
4968         },
4969         { } /* end */
4970 };
4971
4972 static struct hda_verb alc882_init_verbs[] = {
4973         /* Front mixer: unmute input/output amp left and right (volume = 0) */
4974         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4975         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4976         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4977         /* Rear mixer */
4978         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4979         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4980         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4981         /* CLFE mixer */
4982         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4983         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4984         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4985         /* Side mixer */
4986         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4987         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4988         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4989
4990         /* Front Pin: output 0 (0x0c) */
4991         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4992         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4993         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4994         /* Rear Pin: output 1 (0x0d) */
4995         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4996         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4997         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4998         /* CLFE Pin: output 2 (0x0e) */
4999         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5000         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5001         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5002         /* Side Pin: output 3 (0x0f) */
5003         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5004         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5005         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5006         /* Mic (rear) pin: input vref at 80% */
5007         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5008         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5009         /* Front Mic pin: input vref at 80% */
5010         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5011         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5012         /* Line In pin: input */
5013         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5014         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5015         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5016         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5017         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5018         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5019         /* CD pin widget for input */
5020         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5021
5022         /* FIXME: use matrix-type input source selection */
5023         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5024         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5025         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5026         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5027         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5028         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5029         /* Input mixer2 */
5030         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5031         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5032         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5033         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5034         /* Input mixer3 */
5035         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5036         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5037         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5038         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5039         /* ADC1: mute amp left and right */
5040         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5041         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5042         /* ADC2: mute amp left and right */
5043         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5044         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5045         /* ADC3: mute amp left and right */
5046         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5047         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5048
5049         { }
5050 };
5051
5052 static struct hda_verb alc882_eapd_verbs[] = {
5053         /* change to EAPD mode */
5054         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5055         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5056         { }
5057 };
5058
5059 /* Mac Pro test */
5060 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5061         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5062         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5063         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5064         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5065         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5066         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5067         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5068         { } /* end */
5069 };
5070
5071 static struct hda_verb alc882_macpro_init_verbs[] = {
5072         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5073         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5074         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5075         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5076         /* Front Pin: output 0 (0x0c) */
5077         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5078         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5079         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5080         /* Front Mic pin: input vref at 80% */
5081         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5082         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5083         /* Speaker:  output */
5084         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5085         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5086         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5087         /* Headphone output (output 0 - 0x0c) */
5088         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5089         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5090         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5091
5092         /* FIXME: use matrix-type input source selection */
5093         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5094         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5095         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5096         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5097         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5098         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5099         /* Input mixer2 */
5100         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5101         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5102         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5103         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5104         /* Input mixer3 */
5105         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5106         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5107         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5108         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5109         /* ADC1: mute amp left and right */
5110         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5111         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5112         /* ADC2: mute amp left and right */
5113         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5114         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5115         /* ADC3: mute amp left and right */
5116         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5117         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5118
5119         { }
5120 };
5121
5122 /* iMac 24 mixer. */
5123 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5124         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5125         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5126         { } /* end */
5127 };
5128
5129 /* iMac 24 init verbs. */
5130 static struct hda_verb alc885_imac24_init_verbs[] = {
5131         /* Internal speakers: output 0 (0x0c) */
5132         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5133         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5134         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5135         /* Internal speakers: output 0 (0x0c) */
5136         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5137         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5138         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5139         /* Headphone: output 0 (0x0c) */
5140         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5141         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5142         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5143         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5144         /* Front Mic: input vref at 80% */
5145         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5146         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5147         { }
5148 };
5149
5150 /* Toggle speaker-output according to the hp-jack state */
5151 static void alc885_imac24_automute(struct hda_codec *codec)
5152 {
5153         unsigned int present;
5154
5155         present = snd_hda_codec_read(codec, 0x14, 0,
5156                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5157         snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0,
5158                                  0x80, present ? 0x80 : 0);
5159         snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0,
5160                                  0x80, present ? 0x80 : 0);
5161         snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
5162                                  0x80, present ? 0x80 : 0);
5163         snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
5164                                  0x80, present ? 0x80 : 0);
5165 }
5166
5167 /* Processes unsolicited events. */
5168 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5169                                       unsigned int res)
5170 {
5171         /* Headphone insertion or removal. */
5172         if ((res >> 26) == ALC880_HP_EVENT)
5173                 alc885_imac24_automute(codec);
5174 }
5175
5176 static struct hda_verb alc882_targa_verbs[] = {
5177         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5178         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5179
5180         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5181         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5182         
5183         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5184         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5185         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5186
5187         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5188         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5189         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5190         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5191         { } /* end */
5192 };
5193
5194 /* toggle speaker-output according to the hp-jack state */
5195 static void alc882_targa_automute(struct hda_codec *codec)
5196 {
5197         unsigned int present;
5198  
5199         present = snd_hda_codec_read(codec, 0x14, 0,
5200                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5201         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5202                                  0x80, present ? 0x80 : 0);
5203         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5204                                  0x80, present ? 0x80 : 0);
5205         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5206 }
5207
5208 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5209 {
5210         /* Looks like the unsol event is incompatible with the standard
5211          * definition.  4bit tag is placed at 26 bit!
5212          */
5213         if (((res >> 26) == ALC880_HP_EVENT)) {
5214                 alc882_targa_automute(codec);
5215         }
5216 }
5217
5218 static struct hda_verb alc882_asus_a7j_verbs[] = {
5219         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5220         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5221
5222         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5223         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5224         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5225         
5226         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5227         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5228         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5229
5230         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5231         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5232         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5233         { } /* end */
5234 };
5235
5236 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5237 {
5238         unsigned int gpiostate, gpiomask, gpiodir;
5239
5240         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5241                                        AC_VERB_GET_GPIO_DATA, 0);
5242
5243         if (!muted)
5244                 gpiostate |= (1 << pin);
5245         else
5246                 gpiostate &= ~(1 << pin);
5247
5248         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5249                                       AC_VERB_GET_GPIO_MASK, 0);
5250         gpiomask |= (1 << pin);
5251
5252         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5253                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5254         gpiodir |= (1 << pin);
5255
5256
5257         snd_hda_codec_write(codec, codec->afg, 0,
5258                             AC_VERB_SET_GPIO_MASK, gpiomask);
5259         snd_hda_codec_write(codec, codec->afg, 0,
5260                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5261
5262         msleep(1);
5263
5264         snd_hda_codec_write(codec, codec->afg, 0,
5265                             AC_VERB_SET_GPIO_DATA, gpiostate);
5266 }
5267
5268 /*
5269  * generic initialization of ADC, input mixers and output mixers
5270  */
5271 static struct hda_verb alc882_auto_init_verbs[] = {
5272         /*
5273          * Unmute ADC0-2 and set the default input to mic-in
5274          */
5275         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5276         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5277         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5278         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5279         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5280         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5281
5282         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5283          * mixer widget
5284          * Note: PASD motherboards uses the Line In 2 as the input for
5285          * front panel mic (mic 2)
5286          */
5287         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5288         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5289         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5290         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5291         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5292         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5293
5294         /*
5295          * Set up output mixers (0x0c - 0x0f)
5296          */
5297         /* set vol=0 to output mixers */
5298         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5299         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5300         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5301         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5302         /* set up input amps for analog loopback */
5303         /* Amp Indices: DAC = 0, mixer = 1 */
5304         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5305         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5306         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5307         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5308         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5309         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5310         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5311         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5312         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5313         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5314
5315         /* FIXME: use matrix-type input source selection */
5316         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5317         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5318         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5319         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5320         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5321         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5322         /* Input mixer2 */
5323         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5324         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5325         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5326         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5327         /* Input mixer3 */
5328         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5329         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5330         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5331         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5332
5333         { }
5334 };
5335
5336 /* capture mixer elements */
5337 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5338         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5339         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5340         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5341         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5342         {
5343                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5344                 /* The multiple "Capture Source" controls confuse alsamixer
5345                  * So call somewhat different..
5346                  * FIXME: the controls appear in the "playback" view!
5347                  */
5348                 /* .name = "Capture Source", */
5349                 .name = "Input Source",
5350                 .count = 2,
5351                 .info = alc882_mux_enum_info,
5352                 .get = alc882_mux_enum_get,
5353                 .put = alc882_mux_enum_put,
5354         },
5355         { } /* end */
5356 };
5357
5358 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5359         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5360         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5361         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5362         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5363         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5364         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5365         {
5366                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5367                 /* The multiple "Capture Source" controls confuse alsamixer
5368                  * So call somewhat different..
5369                  * FIXME: the controls appear in the "playback" view!
5370                  */
5371                 /* .name = "Capture Source", */
5372                 .name = "Input Source",
5373                 .count = 3,
5374                 .info = alc882_mux_enum_info,
5375                 .get = alc882_mux_enum_get,
5376                 .put = alc882_mux_enum_put,
5377         },
5378         { } /* end */
5379 };
5380
5381 /* pcm configuration: identiacal with ALC880 */
5382 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5383 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5384 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5385 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5386
5387 /*
5388  * configuration and preset
5389  */
5390 static const char *alc882_models[ALC882_MODEL_LAST] = {
5391         [ALC882_3ST_DIG]        = "3stack-dig",
5392         [ALC882_6ST_DIG]        = "6stack-dig",
5393         [ALC882_ARIMA]          = "arima",
5394         [ALC882_W2JC]           = "w2jc",
5395         [ALC885_MACPRO]         = "macpro",
5396         [ALC885_IMAC24]         = "imac24",
5397         [ALC882_AUTO]           = "auto",
5398 };
5399
5400 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5401         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5402         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5403         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5404         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5405         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5406         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5407         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5408         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5409         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5410         {}
5411 };
5412
5413 static struct alc_config_preset alc882_presets[] = {
5414         [ALC882_3ST_DIG] = {
5415                 .mixers = { alc882_base_mixer },
5416                 .init_verbs = { alc882_init_verbs },
5417                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5418                 .dac_nids = alc882_dac_nids,
5419                 .dig_out_nid = ALC882_DIGOUT_NID,
5420                 .dig_in_nid = ALC882_DIGIN_NID,
5421                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5422                 .channel_mode = alc882_ch_modes,
5423                 .need_dac_fix = 1,
5424                 .input_mux = &alc882_capture_source,
5425         },
5426         [ALC882_6ST_DIG] = {
5427                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5428                 .init_verbs = { alc882_init_verbs },
5429                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5430                 .dac_nids = alc882_dac_nids,
5431                 .dig_out_nid = ALC882_DIGOUT_NID,
5432                 .dig_in_nid = ALC882_DIGIN_NID,
5433                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5434                 .channel_mode = alc882_sixstack_modes,
5435                 .input_mux = &alc882_capture_source,
5436         },
5437         [ALC882_ARIMA] = {
5438                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5439                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5440                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5441                 .dac_nids = alc882_dac_nids,
5442                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5443                 .channel_mode = alc882_sixstack_modes,
5444                 .input_mux = &alc882_capture_source,
5445         },
5446         [ALC882_W2JC] = {
5447                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5448                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5449                                 alc880_gpio1_init_verbs },
5450                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5451                 .dac_nids = alc882_dac_nids,
5452                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5453                 .channel_mode = alc880_threestack_modes,
5454                 .need_dac_fix = 1,
5455                 .input_mux = &alc882_capture_source,
5456                 .dig_out_nid = ALC882_DIGOUT_NID,
5457         },
5458         [ALC885_MACPRO] = {
5459                 .mixers = { alc882_macpro_mixer },
5460                 .init_verbs = { alc882_macpro_init_verbs },
5461                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5462                 .dac_nids = alc882_dac_nids,
5463                 .dig_out_nid = ALC882_DIGOUT_NID,
5464                 .dig_in_nid = ALC882_DIGIN_NID,
5465                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5466                 .channel_mode = alc882_ch_modes,
5467                 .input_mux = &alc882_capture_source,
5468         },
5469         [ALC885_IMAC24] = {
5470                 .mixers = { alc885_imac24_mixer },
5471                 .init_verbs = { alc885_imac24_init_verbs },
5472                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5473                 .dac_nids = alc882_dac_nids,
5474                 .dig_out_nid = ALC882_DIGOUT_NID,
5475                 .dig_in_nid = ALC882_DIGIN_NID,
5476                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5477                 .channel_mode = alc882_ch_modes,
5478                 .input_mux = &alc882_capture_source,
5479                 .unsol_event = alc885_imac24_unsol_event,
5480                 .init_hook = alc885_imac24_automute,
5481         },
5482         [ALC882_TARGA] = {
5483                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5484                             alc882_capture_mixer },
5485                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5486                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5487                 .dac_nids = alc882_dac_nids,
5488                 .dig_out_nid = ALC882_DIGOUT_NID,
5489                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5490                 .adc_nids = alc882_adc_nids,
5491                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5492                 .channel_mode = alc882_3ST_6ch_modes,
5493                 .need_dac_fix = 1,
5494                 .input_mux = &alc882_capture_source,
5495                 .unsol_event = alc882_targa_unsol_event,
5496                 .init_hook = alc882_targa_automute,
5497         },
5498         [ALC882_ASUS_A7J] = {
5499                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5500                             alc882_capture_mixer },
5501                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5502                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5503                 .dac_nids = alc882_dac_nids,
5504                 .dig_out_nid = ALC882_DIGOUT_NID,
5505                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5506                 .adc_nids = alc882_adc_nids,
5507                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5508                 .channel_mode = alc882_3ST_6ch_modes,
5509                 .need_dac_fix = 1,
5510                 .input_mux = &alc882_capture_source,
5511         },      
5512 };
5513
5514
5515 /*
5516  * Pin config fixes
5517  */
5518 enum { 
5519         PINFIX_ABIT_AW9D_MAX
5520 };
5521
5522 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5523         { 0x15, 0x01080104 }, /* side */
5524         { 0x16, 0x01011012 }, /* rear */
5525         { 0x17, 0x01016011 }, /* clfe */
5526         { }
5527 };
5528
5529 static const struct alc_pincfg *alc882_pin_fixes[] = {
5530         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5531 };
5532
5533 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5534         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5535         {}
5536 };
5537
5538 /*
5539  * BIOS auto configuration
5540  */
5541 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5542                                               hda_nid_t nid, int pin_type,
5543                                               int dac_idx)
5544 {
5545         /* set as output */
5546         struct alc_spec *spec = codec->spec;
5547         int idx;
5548
5549         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5550                 idx = 4;
5551         else
5552                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5553
5554         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5555                             pin_type);
5556         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5557                             AMP_OUT_UNMUTE);
5558         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5559
5560 }
5561
5562 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5563 {
5564         struct alc_spec *spec = codec->spec;
5565         int i;
5566
5567         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5568         for (i = 0; i <= HDA_SIDE; i++) {
5569                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5570                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5571                 if (nid)
5572                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5573                                                           i);
5574         }
5575 }
5576
5577 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5578 {
5579         struct alc_spec *spec = codec->spec;
5580         hda_nid_t pin;
5581
5582         pin = spec->autocfg.hp_pins[0];
5583         if (pin) /* connect to front */
5584                 /* use dac 0 */
5585                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5586 }
5587
5588 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5589 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5590
5591 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5592 {
5593         struct alc_spec *spec = codec->spec;
5594         int i;
5595
5596         for (i = 0; i < AUTO_PIN_LAST; i++) {
5597                 hda_nid_t nid = spec->autocfg.input_pins[i];
5598                 if (alc882_is_input_pin(nid)) {
5599                         snd_hda_codec_write(codec, nid, 0,
5600                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5601                                             i <= AUTO_PIN_FRONT_MIC ?
5602                                             PIN_VREF80 : PIN_IN);
5603                         if (nid != ALC882_PIN_CD_NID)
5604                                 snd_hda_codec_write(codec, nid, 0,
5605                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5606                                                     AMP_OUT_MUTE);
5607                 }
5608         }
5609 }
5610
5611 /* almost identical with ALC880 parser... */
5612 static int alc882_parse_auto_config(struct hda_codec *codec)
5613 {
5614         struct alc_spec *spec = codec->spec;
5615         int err = alc880_parse_auto_config(codec);
5616
5617         if (err < 0)
5618                 return err;
5619         else if (err > 0)
5620                 /* hack - override the init verbs */
5621                 spec->init_verbs[0] = alc882_auto_init_verbs;
5622         return err;
5623 }
5624
5625 /* additional initialization for auto-configuration model */
5626 static void alc882_auto_init(struct hda_codec *codec)
5627 {
5628         alc882_auto_init_multi_out(codec);
5629         alc882_auto_init_hp_out(codec);
5630         alc882_auto_init_analog_input(codec);
5631 }
5632
5633 static int patch_alc882(struct hda_codec *codec)
5634 {
5635         struct alc_spec *spec;
5636         int err, board_config;
5637
5638         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5639         if (spec == NULL)
5640                 return -ENOMEM;
5641
5642         codec->spec = spec;
5643
5644         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5645                                                   alc882_models,
5646                                                   alc882_cfg_tbl);
5647
5648         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5649                 /* Pick up systems that don't supply PCI SSID */
5650                 switch (codec->subsystem_id) {
5651                 case 0x106b0c00: /* Mac Pro */
5652                         board_config = ALC885_MACPRO;
5653                         break;
5654                 case 0x106b1000: /* iMac 24 */
5655                         board_config = ALC885_IMAC24;
5656                         break;
5657                 default:
5658                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5659                                          "trying auto-probe from BIOS...\n");
5660                         board_config = ALC882_AUTO;
5661                 }
5662         }
5663
5664         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5665
5666         if (board_config == ALC882_AUTO) {
5667                 /* automatic parse from the BIOS config */
5668                 err = alc882_parse_auto_config(codec);
5669                 if (err < 0) {
5670                         alc_free(codec);
5671                         return err;
5672                 } else if (!err) {
5673                         printk(KERN_INFO
5674                                "hda_codec: Cannot set up configuration "
5675                                "from BIOS.  Using base mode...\n");
5676                         board_config = ALC882_3ST_DIG;
5677                 }
5678         }
5679
5680         if (board_config != ALC882_AUTO)
5681                 setup_preset(spec, &alc882_presets[board_config]);
5682
5683         if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
5684                 alc882_gpio_mute(codec, 0, 0);
5685                 alc882_gpio_mute(codec, 1, 0);
5686         }
5687
5688         spec->stream_name_analog = "ALC882 Analog";
5689         spec->stream_analog_playback = &alc882_pcm_analog_playback;
5690         spec->stream_analog_capture = &alc882_pcm_analog_capture;
5691
5692         spec->stream_name_digital = "ALC882 Digital";
5693         spec->stream_digital_playback = &alc882_pcm_digital_playback;
5694         spec->stream_digital_capture = &alc882_pcm_digital_capture;
5695
5696         if (!spec->adc_nids && spec->input_mux) {
5697                 /* check whether NID 0x07 is valid */
5698                 unsigned int wcap = get_wcaps(codec, 0x07);
5699                 /* get type */
5700                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5701                 if (wcap != AC_WID_AUD_IN) {
5702                         spec->adc_nids = alc882_adc_nids_alt;
5703                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5704                         spec->mixers[spec->num_mixers] =
5705                                 alc882_capture_alt_mixer;
5706                         spec->num_mixers++;
5707                 } else {
5708                         spec->adc_nids = alc882_adc_nids;
5709                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5710                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5711                         spec->num_mixers++;
5712                 }
5713         }
5714
5715         codec->patch_ops = alc_patch_ops;
5716         if (board_config == ALC882_AUTO)
5717                 spec->init_hook = alc882_auto_init;
5718
5719         return 0;
5720 }
5721
5722 /*
5723  * ALC883 support
5724  *
5725  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5726  * configuration.  Each pin widget can choose any input DACs and a mixer.
5727  * Each ADC is connected from a mixer of all inputs.  This makes possible
5728  * 6-channel independent captures.
5729  *
5730  * In addition, an independent DAC for the multi-playback (not used in this
5731  * driver yet).
5732  */
5733 #define ALC883_DIGOUT_NID       0x06
5734 #define ALC883_DIGIN_NID        0x0a
5735
5736 static hda_nid_t alc883_dac_nids[4] = {
5737         /* front, rear, clfe, rear_surr */
5738         0x02, 0x04, 0x03, 0x05
5739 };
5740
5741 static hda_nid_t alc883_adc_nids[2] = {
5742         /* ADC1-2 */
5743         0x08, 0x09,
5744 };
5745
5746 /* input MUX */
5747 /* FIXME: should be a matrix-type input source selection */
5748
5749 static struct hda_input_mux alc883_capture_source = {
5750         .num_items = 4,
5751         .items = {
5752                 { "Mic", 0x0 },
5753                 { "Front Mic", 0x1 },
5754                 { "Line", 0x2 },
5755                 { "CD", 0x4 },
5756         },
5757 };
5758
5759 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5760         .num_items = 2,
5761         .items = {
5762                 { "Mic", 0x1 },
5763                 { "Line", 0x2 },
5764         },
5765 };
5766
5767 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5768         .num_items = 4,
5769         .items = {
5770                 { "Mic", 0x0 },
5771                 { "iMic", 0x1 },
5772                 { "Line", 0x2 },
5773                 { "CD", 0x4 },
5774         },
5775 };
5776
5777 #define alc883_mux_enum_info alc_mux_enum_info
5778 #define alc883_mux_enum_get alc_mux_enum_get
5779
5780 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5781                                struct snd_ctl_elem_value *ucontrol)
5782 {
5783         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5784         struct alc_spec *spec = codec->spec;
5785         const struct hda_input_mux *imux = spec->input_mux;
5786         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5787         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5788         hda_nid_t nid = capture_mixers[adc_idx];
5789         unsigned int *cur_val = &spec->cur_mux[adc_idx];
5790         unsigned int i, idx;
5791
5792         idx = ucontrol->value.enumerated.item[0];
5793         if (idx >= imux->num_items)
5794                 idx = imux->num_items - 1;
5795         if (*cur_val == idx && !codec->in_resume)
5796                 return 0;
5797         for (i = 0; i < imux->num_items; i++) {
5798                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
5799                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5800                                     v | (imux->items[i].index << 8));
5801         }
5802         *cur_val = idx;
5803         return 1;
5804 }
5805
5806 /*
5807  * 2ch mode
5808  */
5809 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5810         { 2, NULL }
5811 };
5812
5813 /*
5814  * 2ch mode
5815  */
5816 static struct hda_verb alc883_3ST_ch2_init[] = {
5817         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5818         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5819         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5820         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5821         { } /* end */
5822 };
5823
5824 /*
5825  * 6ch mode
5826  */
5827 static struct hda_verb alc883_3ST_ch6_init[] = {
5828         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5829         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5830         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5831         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5832         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5833         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5834         { } /* end */
5835 };
5836
5837 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5838         { 2, alc883_3ST_ch2_init },
5839         { 6, alc883_3ST_ch6_init },
5840 };
5841
5842 /*
5843  * 6ch mode
5844  */
5845 static struct hda_verb alc883_sixstack_ch6_init[] = {
5846         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5847         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5848         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5849         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5850         { } /* end */
5851 };
5852
5853 /*
5854  * 8ch mode
5855  */
5856 static struct hda_verb alc883_sixstack_ch8_init[] = {
5857         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5858         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5859         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5860         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5861         { } /* end */
5862 };
5863
5864 static struct hda_channel_mode alc883_sixstack_modes[2] = {
5865         { 6, alc883_sixstack_ch6_init },
5866         { 8, alc883_sixstack_ch8_init },
5867 };
5868
5869 static struct hda_verb alc883_medion_eapd_verbs[] = {
5870         /* eanable EAPD on medion laptop */
5871         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5872         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5873         { }
5874 };
5875
5876 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5877  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5878  */
5879
5880 static struct snd_kcontrol_new alc883_base_mixer[] = {
5881         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5882         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5883         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5884         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5885         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5886         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5887         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5888         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5889         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5890         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5891         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5892         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5893         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5894         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5895         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5896         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5897         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5898         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5899         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5900         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5901         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5902         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5903         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5904         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5905         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5906         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5907         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5908         {
5909                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5910                 /* .name = "Capture Source", */
5911                 .name = "Input Source",
5912                 .count = 2,
5913                 .info = alc883_mux_enum_info,
5914                 .get = alc883_mux_enum_get,
5915                 .put = alc883_mux_enum_put,
5916         },
5917         { } /* end */
5918 };
5919
5920 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5921         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5922         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5923         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5924         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5925         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5926         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5927         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5928         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5929         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5930         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5931         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5932         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5933         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5934         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5935         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5936         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5937         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5938         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5939         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5940         {
5941                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5942                 /* .name = "Capture Source", */
5943                 .name = "Input Source",
5944                 .count = 2,
5945                 .info = alc883_mux_enum_info,
5946                 .get = alc883_mux_enum_get,
5947                 .put = alc883_mux_enum_put,
5948         },
5949         { } /* end */
5950 };
5951
5952 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5953         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5954         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5955         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5956         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5957         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5958         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5959         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5960         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5961         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5962         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5963         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5964         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5965         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5966         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5967         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5968         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5969         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5970         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5971         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5972         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5973         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5974         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5975         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5976         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5977         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5978         {
5979                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5980                 /* .name = "Capture Source", */
5981                 .name = "Input Source",
5982                 .count = 2,
5983                 .info = alc883_mux_enum_info,
5984                 .get = alc883_mux_enum_get,
5985                 .put = alc883_mux_enum_put,
5986         },
5987         { } /* end */
5988 };
5989
5990 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5991         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5992         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5993         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5994         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5995         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5996         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5997         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5998         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5999         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6000         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6001         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6002         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6003         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6004         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6005         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6006         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6007         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6008         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6009         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6010         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6011         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6012         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6013         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6014
6015         {
6016                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6017                 /* .name = "Capture Source", */
6018                 .name = "Input Source",
6019                 .count = 1,
6020                 .info = alc883_mux_enum_info,
6021                 .get = alc883_mux_enum_get,
6022                 .put = alc883_mux_enum_put,
6023         },
6024         { } /* end */
6025 };
6026
6027 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6028         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6029         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6030         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6031         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6032         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6033         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6034         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6035         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6036         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6037         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6038         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6039         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6040         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6041         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6042         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6043         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6044         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6045         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6046         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6047         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6048         {
6049                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6050                 /* .name = "Capture Source", */
6051                 .name = "Input Source",
6052                 .count = 2,
6053                 .info = alc883_mux_enum_info,
6054                 .get = alc883_mux_enum_get,
6055                 .put = alc883_mux_enum_put,
6056         },
6057         { } /* end */
6058 };
6059
6060 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6061         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6062         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6063         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6064         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6065         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6066         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6067         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6068         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6069         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6070         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6071         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6072         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6073         {
6074                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6075                 /* .name = "Capture Source", */
6076                 .name = "Input Source",
6077                 .count = 2,
6078                 .info = alc883_mux_enum_info,
6079                 .get = alc883_mux_enum_get,
6080                 .put = alc883_mux_enum_put,
6081         },
6082         { } /* end */
6083 };
6084
6085 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6086         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6087         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6088         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6089         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6090         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6091         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6092         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6093         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6094         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6095         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6096         {
6097                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6098                 /* .name = "Capture Source", */
6099                 .name = "Input Source",
6100                 .count = 1,
6101                 .info = alc883_mux_enum_info,
6102                 .get = alc883_mux_enum_get,
6103                 .put = alc883_mux_enum_put,
6104         },
6105         { } /* end */
6106 };
6107
6108 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6109         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6110         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6111         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6112         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6113         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6114         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6115         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6116         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6117         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6118         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6119         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6120         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6121         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6122         {
6123                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6124                 /* .name = "Capture Source", */
6125                 .name = "Input Source",
6126                 .count = 2,
6127                 .info = alc883_mux_enum_info,
6128                 .get = alc883_mux_enum_get,
6129                 .put = alc883_mux_enum_put,
6130         },
6131         { } /* end */
6132 };
6133
6134 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6135         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6136         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6137         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6138         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6139         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6140         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6141         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6142         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6143         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6144         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6145         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6146         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6147         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6148         {
6149                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6150                 /* .name = "Capture Source", */
6151                 .name = "Input Source",
6152                 .count = 2,
6153                 .info = alc883_mux_enum_info,
6154                 .get = alc883_mux_enum_get,
6155                 .put = alc883_mux_enum_put,
6156         },
6157         { } /* end */
6158 };      
6159
6160 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6161         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6162         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6163         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6164         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6165         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6166         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6167         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6168         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6169         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6170         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6171         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6172         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6173         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6174         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6175         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6176         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6177         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6178         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6179         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6180         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6181         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6182         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6183         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6184         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6185         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6186         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6187         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6188         {
6189                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6190                 /* .name = "Capture Source", */
6191                 .name = "Input Source",
6192                 .count = 2,
6193                 .info = alc883_mux_enum_info,
6194                 .get = alc883_mux_enum_get,
6195                 .put = alc883_mux_enum_put,
6196         },
6197         { } /* end */
6198 };
6199
6200 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6201         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6202         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6203         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6204         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6205         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6206         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6207         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6208         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6209         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6210         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6211         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6212         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6213         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6214         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6215         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6216         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6217         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6218         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6219         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6220         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6221         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6222         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6223         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6224         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6225         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6226         {
6227                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6228                 /* .name = "Capture Source", */
6229                 .name = "Input Source",
6230                 .count = 2,
6231                 .info = alc883_mux_enum_info,
6232                 .get = alc883_mux_enum_get,
6233                 .put = alc883_mux_enum_put,
6234         },
6235         { } /* end */
6236 };
6237
6238 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6239         {
6240                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6241                 .name = "Channel Mode",
6242                 .info = alc_ch_mode_info,
6243                 .get = alc_ch_mode_get,
6244                 .put = alc_ch_mode_put,
6245         },
6246         { } /* end */
6247 };
6248
6249 static struct hda_verb alc883_init_verbs[] = {
6250         /* ADC1: mute amp left and right */
6251         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6252         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6253         /* ADC2: mute amp left and right */
6254         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6255         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6256         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6257         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6258         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6259         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6260         /* Rear mixer */
6261         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6262         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6263         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6264         /* CLFE mixer */
6265         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6266         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6267         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6268         /* Side mixer */
6269         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6270         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6271         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6272
6273         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6274         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6275         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6276         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6277         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6278
6279         /* Front Pin: output 0 (0x0c) */
6280         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6281         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6282         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6283         /* Rear Pin: output 1 (0x0d) */
6284         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6285         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6286         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6287         /* CLFE Pin: output 2 (0x0e) */
6288         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6289         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6290         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6291         /* Side Pin: output 3 (0x0f) */
6292         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6293         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6294         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6295         /* Mic (rear) pin: input vref at 80% */
6296         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6297         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6298         /* Front Mic pin: input vref at 80% */
6299         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6300         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6301         /* Line In pin: input */
6302         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6303         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6304         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6305         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6306         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6307         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6308         /* CD pin widget for input */
6309         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6310
6311         /* FIXME: use matrix-type input source selection */
6312         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6313         /* Input mixer2 */
6314         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6315         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6316         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6317         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6318         /* Input mixer3 */
6319         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6320         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6321         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6322         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6323         { }
6324 };
6325
6326 static struct hda_verb alc883_tagra_verbs[] = {
6327         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6328         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6329
6330         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6331         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6332         
6333         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6334         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6335         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6336
6337         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6338         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6339         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6340         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6341
6342         { } /* end */
6343 };
6344
6345 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6346         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6347         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6348         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6349         { } /* end */
6350 };
6351
6352 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6353         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6354         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6355         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6356         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6357         { } /* end */
6358 };
6359
6360 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6361         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6362         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6363         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6364         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6365         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6366         { } /* end */
6367 };
6368
6369 static struct hda_verb alc888_6st_hp_verbs[] = {
6370         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6371         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6372         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6373         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6374         { }
6375 };
6376
6377 static struct hda_verb alc888_3st_hp_verbs[] = {
6378         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6379         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6380         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6381         { }
6382 };
6383
6384 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6385         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6386         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6387         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6388         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6389         { }
6390 };
6391
6392 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6393         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6394         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6395         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6396         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6397         { }
6398 };
6399
6400 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6401         { 2, alc888_3st_hp_2ch_init },
6402         { 6, alc888_3st_hp_6ch_init },
6403 };
6404
6405 /* toggle front-jack and RCA according to the hp-jack state */
6406 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6407 {
6408         unsigned int present;
6409  
6410         present = snd_hda_codec_read(codec, 0x1b, 0,
6411                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6412         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6413                                  0x80, present ? 0x80 : 0);
6414         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6415                                  0x80, present ? 0x80 : 0);
6416         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6417                                  0x80, present ? 0x80 : 0);
6418         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6419                                  0x80, present ? 0x80 : 0);
6420         
6421 }
6422
6423 /* toggle RCA according to the front-jack state */
6424 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6425 {
6426         unsigned int present;
6427  
6428         present = snd_hda_codec_read(codec, 0x14, 0,
6429                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6430         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6431                                  0x80, present ? 0x80 : 0);
6432         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6433                                  0x80, present ? 0x80 : 0);
6434         
6435 }
6436 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6437                                              unsigned int res)
6438 {
6439         if ((res >> 26) == ALC880_HP_EVENT)
6440                 alc888_lenovo_ms7195_front_automute(codec);
6441         if ((res >> 26) == ALC880_FRONT_EVENT)
6442                 alc888_lenovo_ms7195_rca_automute(codec);
6443 }
6444
6445 static struct hda_verb alc883_medion_md2_verbs[] = {
6446         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6447         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6448
6449         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6450
6451         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6452         { } /* end */
6453 };
6454
6455 /* toggle speaker-output according to the hp-jack state */
6456 static void alc883_medion_md2_automute(struct hda_codec *codec)
6457 {
6458         unsigned int present;
6459  
6460         present = snd_hda_codec_read(codec, 0x14, 0,
6461                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6462         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6463                                  0x80, present ? 0x80 : 0);
6464         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6465                                  0x80, present ? 0x80 : 0);
6466 }
6467
6468 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6469                                           unsigned int res)
6470 {
6471         if ((res >> 26) == ALC880_HP_EVENT)
6472                 alc883_medion_md2_automute(codec);
6473 }
6474
6475 /* toggle speaker-output according to the hp-jack state */
6476 static void alc883_tagra_automute(struct hda_codec *codec)
6477 {
6478         unsigned int present;
6479         unsigned char bits;
6480
6481         present = snd_hda_codec_read(codec, 0x14, 0,
6482                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6483         bits = present ? 0x80 : 0;
6484         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
6485                                  0x80, bits);
6486         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
6487                                  0x80, bits);
6488         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6489                             present ? 1 : 3);
6490 }
6491
6492 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6493 {
6494         if ((res >> 26) == ALC880_HP_EVENT)
6495                 alc883_tagra_automute(codec);
6496 }
6497
6498 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6499 {
6500         unsigned int present;
6501         unsigned char bits;
6502
6503         present = snd_hda_codec_read(codec, 0x14, 0,
6504                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6505         bits = present ? 0x80 : 0;
6506         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6507                                  0x80, bits);
6508         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6509                                  0x80, bits);
6510 }
6511
6512 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6513 {
6514         unsigned int present;
6515         unsigned char bits;
6516
6517         present = snd_hda_codec_read(codec, 0x1b, 0,
6518                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6519         bits = present ? 0x80 : 0;
6520         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6521                                  0x80, bits);
6522         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6523                                  0x80, bits);
6524         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6525                                  0x80, bits);
6526         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6527                                  0x80, bits);
6528 }
6529
6530 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6531                                            unsigned int res)
6532 {
6533         if ((res >> 26) == ALC880_HP_EVENT)
6534                 alc883_lenovo_101e_all_automute(codec);
6535         if ((res >> 26) == ALC880_FRONT_EVENT)
6536                 alc883_lenovo_101e_ispeaker_automute(codec);
6537 }
6538
6539 /*
6540  * generic initialization of ADC, input mixers and output mixers
6541  */
6542 static struct hda_verb alc883_auto_init_verbs[] = {
6543         /*
6544          * Unmute ADC0-2 and set the default input to mic-in
6545          */
6546         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6547         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6548         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6549         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6550
6551         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6552          * mixer widget
6553          * Note: PASD motherboards uses the Line In 2 as the input for
6554          * front panel mic (mic 2)
6555          */
6556         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6557         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6558         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6559         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6560         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6561         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6562
6563         /*
6564          * Set up output mixers (0x0c - 0x0f)
6565          */
6566         /* set vol=0 to output mixers */
6567         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6568         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6569         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6570         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6571         /* set up input amps for analog loopback */
6572         /* Amp Indices: DAC = 0, mixer = 1 */
6573         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6574         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6575         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6576         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6577         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6578         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6579         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6580         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6581         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6582         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6583
6584         /* FIXME: use matrix-type input source selection */
6585         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6586         /* Input mixer1 */
6587         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6588         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6589         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6590         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6591         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6592         /* Input mixer2 */
6593         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6594         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6595         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6596         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6597         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6598
6599         { }
6600 };
6601
6602 /* capture mixer elements */
6603 static struct snd_kcontrol_new alc883_capture_mixer[] = {
6604         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6605         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6606         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6607         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6608         {
6609                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6610                 /* The multiple "Capture Source" controls confuse alsamixer
6611                  * So call somewhat different..
6612                  * FIXME: the controls appear in the "playback" view!
6613                  */
6614                 /* .name = "Capture Source", */
6615                 .name = "Input Source",
6616                 .count = 2,
6617                 .info = alc882_mux_enum_info,
6618                 .get = alc882_mux_enum_get,
6619                 .put = alc882_mux_enum_put,
6620         },
6621         { } /* end */
6622 };
6623
6624 /* pcm configuration: identiacal with ALC880 */
6625 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
6626 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
6627 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
6628 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
6629
6630 /*
6631  * configuration and preset
6632  */
6633 static const char *alc883_models[ALC883_MODEL_LAST] = {
6634         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
6635         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
6636         [ALC883_3ST_6ch]        = "3stack-6ch",
6637         [ALC883_6ST_DIG]        = "6stack-dig",
6638         [ALC883_TARGA_DIG]      = "targa-dig",
6639         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
6640         [ALC883_ACER]           = "acer",
6641         [ALC883_MEDION]         = "medion",
6642         [ALC883_MEDION_MD2]     = "medion-md2",
6643         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
6644         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6645         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
6646         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6647         [ALC888_6ST_HP]         = "6stack-hp",
6648         [ALC888_3ST_HP]         = "3stack-hp",
6649         [ALC883_AUTO]           = "auto",
6650 };
6651
6652 static struct snd_pci_quirk alc883_cfg_tbl[] = {
6653         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6654         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6655         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6656         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6657         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6658         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6659         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6660         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6661         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6662         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6663         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6664         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6665         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6666         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6667         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6668         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6669         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6670         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6671         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6672         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6673         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6674         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6675         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6676         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6677         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6678         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6679         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6680         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6681         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6682         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6683         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6684         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6685         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6686         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6687         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6688         {}
6689 };
6690
6691 static struct alc_config_preset alc883_presets[] = {
6692         [ALC883_3ST_2ch_DIG] = {
6693                 .mixers = { alc883_3ST_2ch_mixer },
6694                 .init_verbs = { alc883_init_verbs },
6695                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6696                 .dac_nids = alc883_dac_nids,
6697                 .dig_out_nid = ALC883_DIGOUT_NID,
6698                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6699                 .adc_nids = alc883_adc_nids,
6700                 .dig_in_nid = ALC883_DIGIN_NID,
6701                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6702                 .channel_mode = alc883_3ST_2ch_modes,
6703                 .input_mux = &alc883_capture_source,
6704         },
6705         [ALC883_3ST_6ch_DIG] = {
6706                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6707                 .init_verbs = { alc883_init_verbs },
6708                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6709                 .dac_nids = alc883_dac_nids,
6710                 .dig_out_nid = ALC883_DIGOUT_NID,
6711                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6712                 .adc_nids = alc883_adc_nids,
6713                 .dig_in_nid = ALC883_DIGIN_NID,
6714                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6715                 .channel_mode = alc883_3ST_6ch_modes,
6716                 .need_dac_fix = 1,
6717                 .input_mux = &alc883_capture_source,
6718         },
6719         [ALC883_3ST_6ch] = {
6720                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6721                 .init_verbs = { alc883_init_verbs },
6722                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6723                 .dac_nids = alc883_dac_nids,
6724                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6725                 .adc_nids = alc883_adc_nids,
6726                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6727                 .channel_mode = alc883_3ST_6ch_modes,
6728                 .need_dac_fix = 1,
6729                 .input_mux = &alc883_capture_source,
6730         },
6731         [ALC883_6ST_DIG] = {
6732                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
6733                 .init_verbs = { alc883_init_verbs },
6734                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6735                 .dac_nids = alc883_dac_nids,
6736                 .dig_out_nid = ALC883_DIGOUT_NID,
6737                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6738                 .adc_nids = alc883_adc_nids,
6739                 .dig_in_nid = ALC883_DIGIN_NID,
6740                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6741                 .channel_mode = alc883_sixstack_modes,
6742                 .input_mux = &alc883_capture_source,
6743         },
6744         [ALC883_TARGA_DIG] = {
6745                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6746                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6747                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6748                 .dac_nids = alc883_dac_nids,
6749                 .dig_out_nid = ALC883_DIGOUT_NID,
6750                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6751                 .adc_nids = alc883_adc_nids,
6752                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6753                 .channel_mode = alc883_3ST_6ch_modes,
6754                 .need_dac_fix = 1,
6755                 .input_mux = &alc883_capture_source,
6756                 .unsol_event = alc883_tagra_unsol_event,
6757                 .init_hook = alc883_tagra_automute,
6758         },
6759         [ALC883_TARGA_2ch_DIG] = {
6760                 .mixers = { alc883_tagra_2ch_mixer},
6761                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6762                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6763                 .dac_nids = alc883_dac_nids,
6764                 .dig_out_nid = ALC883_DIGOUT_NID,
6765                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6766                 .adc_nids = alc883_adc_nids,
6767                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6768                 .channel_mode = alc883_3ST_2ch_modes,
6769                 .input_mux = &alc883_capture_source,
6770                 .unsol_event = alc883_tagra_unsol_event,
6771                 .init_hook = alc883_tagra_automute,
6772         },
6773         [ALC883_ACER] = {
6774                 .mixers = { alc883_base_mixer,
6775                             alc883_chmode_mixer },
6776                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
6777                  * and the headphone jack.  Turn this on and rely on the
6778                  * standard mute methods whenever the user wants to turn
6779                  * these outputs off.
6780                  */
6781                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6782                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6783                 .dac_nids = alc883_dac_nids,
6784                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6785                 .adc_nids = alc883_adc_nids,
6786                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6787                 .channel_mode = alc883_3ST_2ch_modes,
6788                 .input_mux = &alc883_capture_source,
6789         },
6790         [ALC883_MEDION] = {
6791                 .mixers = { alc883_fivestack_mixer,
6792                             alc883_chmode_mixer },
6793                 .init_verbs = { alc883_init_verbs,
6794                                 alc883_medion_eapd_verbs },
6795                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6796                 .dac_nids = alc883_dac_nids,
6797                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6798                 .adc_nids = alc883_adc_nids,
6799                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6800                 .channel_mode = alc883_sixstack_modes,
6801                 .input_mux = &alc883_capture_source,
6802         },
6803         [ALC883_MEDION_MD2] = {
6804                 .mixers = { alc883_medion_md2_mixer},
6805                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6806                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6807                 .dac_nids = alc883_dac_nids,
6808                 .dig_out_nid = ALC883_DIGOUT_NID,
6809                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6810                 .adc_nids = alc883_adc_nids,
6811                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6812                 .channel_mode = alc883_3ST_2ch_modes,
6813                 .input_mux = &alc883_capture_source,
6814                 .unsol_event = alc883_medion_md2_unsol_event,
6815                 .init_hook = alc883_medion_md2_automute,
6816         },      
6817         [ALC883_LAPTOP_EAPD] = {
6818                 .mixers = { alc883_base_mixer,
6819                             alc883_chmode_mixer },
6820                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6821                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6822                 .dac_nids = alc883_dac_nids,
6823                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6824                 .adc_nids = alc883_adc_nids,
6825                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6826                 .channel_mode = alc883_3ST_2ch_modes,
6827                 .input_mux = &alc883_capture_source,
6828         },
6829         [ALC883_LENOVO_101E_2ch] = {
6830                 .mixers = { alc883_lenovo_101e_2ch_mixer},
6831                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6832                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6833                 .dac_nids = alc883_dac_nids,
6834                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6835                 .adc_nids = alc883_adc_nids,
6836                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6837                 .channel_mode = alc883_3ST_2ch_modes,
6838                 .input_mux = &alc883_lenovo_101e_capture_source,
6839                 .unsol_event = alc883_lenovo_101e_unsol_event,
6840                 .init_hook = alc883_lenovo_101e_all_automute,
6841         },
6842         [ALC883_LENOVO_NB0763] = {
6843                 .mixers = { alc883_lenovo_nb0763_mixer },
6844                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6845                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6846                 .dac_nids = alc883_dac_nids,
6847                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6848                 .adc_nids = alc883_adc_nids,
6849                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6850                 .channel_mode = alc883_3ST_2ch_modes,
6851                 .need_dac_fix = 1,
6852                 .input_mux = &alc883_lenovo_nb0763_capture_source,
6853                 .unsol_event = alc883_medion_md2_unsol_event,
6854                 .init_hook = alc883_medion_md2_automute,
6855         },
6856         [ALC888_LENOVO_MS7195_DIG] = {
6857                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6858                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6859                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6860                 .dac_nids = alc883_dac_nids,
6861                 .dig_out_nid = ALC883_DIGOUT_NID,
6862                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6863                 .adc_nids = alc883_adc_nids,
6864                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6865                 .channel_mode = alc883_3ST_6ch_modes,
6866                 .need_dac_fix = 1,
6867                 .input_mux = &alc883_capture_source,
6868                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
6869                 .init_hook = alc888_lenovo_ms7195_front_automute,
6870         },      
6871         [ALC888_6ST_HP] = {
6872                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
6873                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
6874                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6875                 .dac_nids = alc883_dac_nids,
6876                 .dig_out_nid = ALC883_DIGOUT_NID,
6877                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6878                 .adc_nids = alc883_adc_nids,
6879                 .dig_in_nid = ALC883_DIGIN_NID,
6880                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6881                 .channel_mode = alc883_sixstack_modes,
6882                 .input_mux = &alc883_capture_source,
6883         },
6884         [ALC888_3ST_HP] = {
6885                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
6886                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
6887                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6888                 .dac_nids = alc883_dac_nids,
6889                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6890                 .adc_nids = alc883_adc_nids,
6891                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
6892                 .channel_mode = alc888_3st_hp_modes,
6893                 .need_dac_fix = 1,
6894                 .input_mux = &alc883_capture_source,
6895         },
6896 };
6897
6898
6899 /*
6900  * BIOS auto configuration
6901  */
6902 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6903                                               hda_nid_t nid, int pin_type,
6904                                               int dac_idx)
6905 {
6906         /* set as output */
6907         struct alc_spec *spec = codec->spec;
6908         int idx;
6909
6910         if (spec->multiout.dac_nids[dac_idx] == 0x25)
6911                 idx = 4;
6912         else
6913                 idx = spec->multiout.dac_nids[dac_idx] - 2;
6914
6915         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6916                             pin_type);
6917         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6918                             AMP_OUT_UNMUTE);
6919         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6920
6921 }
6922
6923 static void alc883_auto_init_multi_out(struct hda_codec *codec)
6924 {
6925         struct alc_spec *spec = codec->spec;
6926         int i;
6927
6928         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6929         for (i = 0; i <= HDA_SIDE; i++) {
6930                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6931                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6932                 if (nid)
6933                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6934                                                           i);
6935         }
6936 }
6937
6938 static void alc883_auto_init_hp_out(struct hda_codec *codec)
6939 {
6940         struct alc_spec *spec = codec->spec;
6941         hda_nid_t pin;
6942
6943         pin = spec->autocfg.hp_pins[0];
6944         if (pin) /* connect to front */
6945                 /* use dac 0 */
6946                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6947 }
6948
6949 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
6950 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
6951
6952 static void alc883_auto_init_analog_input(struct hda_codec *codec)
6953 {
6954         struct alc_spec *spec = codec->spec;
6955         int i;
6956
6957         for (i = 0; i < AUTO_PIN_LAST; i++) {
6958                 hda_nid_t nid = spec->autocfg.input_pins[i];
6959                 if (alc883_is_input_pin(nid)) {
6960                         snd_hda_codec_write(codec, nid, 0,
6961                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
6962                                             (i <= AUTO_PIN_FRONT_MIC ?
6963                                              PIN_VREF80 : PIN_IN));
6964                         if (nid != ALC883_PIN_CD_NID)
6965                                 snd_hda_codec_write(codec, nid, 0,
6966                                                     AC_VERB_SET_AMP_GAIN_MUTE,
6967                                                     AMP_OUT_MUTE);
6968                 }
6969         }
6970 }
6971
6972 /* almost identical with ALC880 parser... */
6973 static int alc883_parse_auto_config(struct hda_codec *codec)
6974 {
6975         struct alc_spec *spec = codec->spec;
6976         int err = alc880_parse_auto_config(codec);
6977
6978         if (err < 0)
6979                 return err;
6980         else if (err > 0)
6981                 /* hack - override the init verbs */
6982                 spec->init_verbs[0] = alc883_auto_init_verbs;
6983         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
6984         spec->num_mixers++;
6985         return err;
6986 }
6987
6988 /* additional initialization for auto-configuration model */
6989 static void alc883_auto_init(struct hda_codec *codec)
6990 {
6991         alc883_auto_init_multi_out(codec);
6992         alc883_auto_init_hp_out(codec);
6993         alc883_auto_init_analog_input(codec);
6994 }
6995
6996 static int patch_alc883(struct hda_codec *codec)
6997 {
6998         struct alc_spec *spec;
6999         int err, board_config;
7000
7001         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7002         if (spec == NULL)
7003                 return -ENOMEM;
7004
7005         codec->spec = spec;
7006
7007         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7008                                                   alc883_models,
7009                                                   alc883_cfg_tbl);
7010         if (board_config < 0) {
7011                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7012                        "trying auto-probe from BIOS...\n");
7013                 board_config = ALC883_AUTO;
7014         }
7015
7016         if (board_config == ALC883_AUTO) {
7017                 /* automatic parse from the BIOS config */
7018                 err = alc883_parse_auto_config(codec);
7019                 if (err < 0) {
7020                         alc_free(codec);
7021                         return err;
7022                 } else if (!err) {
7023                         printk(KERN_INFO
7024                                "hda_codec: Cannot set up configuration "
7025                                "from BIOS.  Using base mode...\n");
7026                         board_config = ALC883_3ST_2ch_DIG;
7027                 }
7028         }
7029
7030         if (board_config != ALC883_AUTO)
7031                 setup_preset(spec, &alc883_presets[board_config]);
7032
7033         spec->stream_name_analog = "ALC883 Analog";
7034         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7035         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7036
7037         spec->stream_name_digital = "ALC883 Digital";
7038         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7039         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7040
7041         if (!spec->adc_nids && spec->input_mux) {
7042                 spec->adc_nids = alc883_adc_nids;
7043                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7044         }
7045
7046         codec->patch_ops = alc_patch_ops;
7047         if (board_config == ALC883_AUTO)
7048                 spec->init_hook = alc883_auto_init;
7049
7050         return 0;
7051 }
7052
7053 /*
7054  * ALC262 support
7055  */
7056
7057 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7058 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7059
7060 #define alc262_dac_nids         alc260_dac_nids
7061 #define alc262_adc_nids         alc882_adc_nids
7062 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7063
7064 #define alc262_modes            alc260_modes
7065 #define alc262_capture_source   alc882_capture_source
7066
7067 static struct snd_kcontrol_new alc262_base_mixer[] = {
7068         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7069         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7070         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7071         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7072         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7073         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7074         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7075         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7076         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7077         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7078         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7079         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7080         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7081            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7082         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7083         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7084         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7085         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7086         { } /* end */
7087 };
7088
7089 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7090         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7091         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7092         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7093         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7094         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7095         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7096         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7097         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7098         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7099         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7100         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7101         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7102         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7103            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7104         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7105         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7106         { } /* end */
7107 };
7108
7109 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7110         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7111         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7112         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7113         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7114         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7115
7116         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7117         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7118         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7119         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7120         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7121         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7122         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7123         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7124         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7125         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7126         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7127         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7128         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7129         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7130         { } /* end */
7131 };
7132
7133 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7134         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7135         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7136         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7137         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7138         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7139         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7140         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7141         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7142         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7143         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7144         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7145         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7146         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7147         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7148         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7149         { } /* end */
7150 };
7151
7152 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7153         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7154         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7155         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7156         { } /* end */
7157 };
7158
7159 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7160         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7161         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7162         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7163         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7164         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7165         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7166         { } /* end */
7167 };
7168
7169 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7170         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7171         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7172         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7173         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7174         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7175         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7176         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7177         { } /* end */
7178 };
7179
7180 #define alc262_capture_mixer            alc882_capture_mixer
7181 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7182
7183 /*
7184  * generic initialization of ADC, input mixers and output mixers
7185  */
7186 static struct hda_verb alc262_init_verbs[] = {
7187         /*
7188          * Unmute ADC0-2 and set the default input to mic-in
7189          */
7190         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7191         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7192         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7193         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7194         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7195         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7196
7197         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7198          * mixer widget
7199          * Note: PASD motherboards uses the Line In 2 as the input for
7200          * front panel mic (mic 2)
7201          */
7202         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7203         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7204         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7205         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7206         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7207         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7208
7209         /*
7210          * Set up output mixers (0x0c - 0x0e)
7211          */
7212         /* set vol=0 to output mixers */
7213         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7214         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7215         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7216         /* set up input amps for analog loopback */
7217         /* Amp Indices: DAC = 0, mixer = 1 */
7218         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7219         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7220         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7221         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7222         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7223         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7224
7225         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7226         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7227         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7228         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7229         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7230         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7231
7232         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7233         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7234         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7235         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7236         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7237         
7238         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7239         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7240         
7241         /* FIXME: use matrix-type input source selection */
7242         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7243         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7244         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7245         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7246         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7247         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7248         /* Input mixer2 */
7249         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7250         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7251         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7252         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7253         /* Input mixer3 */
7254         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7255         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7256         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7257         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7258
7259         { }
7260 };
7261
7262 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7263         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7264         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7265         {}
7266 };
7267
7268 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7269         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7270         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7271         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7272
7273         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7274         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7275         {}
7276 };
7277
7278 static struct hda_verb alc262_sony_unsol_verbs[] = {
7279         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7280         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7281         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7282
7283         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7284         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7285 };
7286
7287 /* mute/unmute internal speaker according to the hp jack and mute state */
7288 static void alc262_hippo_automute(struct hda_codec *codec, int force)
7289 {
7290         struct alc_spec *spec = codec->spec;
7291         unsigned int mute;
7292
7293         if (force || !spec->sense_updated) {
7294                 unsigned int present;
7295                 /* need to execute and sync at first */
7296                 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7297                 present = snd_hda_codec_read(codec, 0x15, 0,
7298                                          AC_VERB_GET_PIN_SENSE, 0);
7299                 spec->jack_present = (present & 0x80000000) != 0;
7300                 spec->sense_updated = 1;
7301         }
7302         if (spec->jack_present) {
7303                 /* mute internal speaker */
7304                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7305                                          0x80, 0x80);
7306                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7307                                          0x80, 0x80);
7308         } else {
7309                 /* unmute internal speaker if necessary */
7310                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7311                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7312                                          0x80, mute & 0x80);
7313                 mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
7314                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7315                                          0x80, mute & 0x80);
7316         }
7317 }
7318
7319 /* unsolicited event for HP jack sensing */
7320 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7321                                        unsigned int res)
7322 {
7323         if ((res >> 26) != ALC880_HP_EVENT)
7324                 return;
7325         alc262_hippo_automute(codec, 1);
7326 }
7327
7328 static void alc262_hippo1_automute(struct hda_codec *codec, int force)
7329 {
7330         struct alc_spec *spec = codec->spec;
7331         unsigned int mute;
7332
7333         if (force || !spec->sense_updated) {
7334                 unsigned int present;
7335                 /* need to execute and sync at first */
7336                 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7337                 present = snd_hda_codec_read(codec, 0x1b, 0,
7338                                          AC_VERB_GET_PIN_SENSE, 0);
7339                 spec->jack_present = (present & 0x80000000) != 0;
7340                 spec->sense_updated = 1;
7341         }
7342         if (spec->jack_present) {
7343                 /* mute internal speaker */
7344                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7345                                          0x80, 0x80);
7346                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7347                                          0x80, 0x80);
7348         } else {
7349                 /* unmute internal speaker if necessary */
7350                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7351                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7352                                          0x80, mute & 0x80);
7353                 mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
7354                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7355                                          0x80, mute & 0x80);
7356         }
7357 }
7358
7359 /* unsolicited event for HP jack sensing */
7360 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7361                                        unsigned int res)
7362 {
7363         if ((res >> 26) != ALC880_HP_EVENT)
7364                 return;
7365         alc262_hippo1_automute(codec, 1);
7366 }
7367
7368 /*
7369  * fujitsu model
7370  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7371  */
7372
7373 #define ALC_HP_EVENT    0x37
7374
7375 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7376         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7377         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7378         {}
7379 };
7380
7381 static struct hda_input_mux alc262_fujitsu_capture_source = {
7382         .num_items = 2,
7383         .items = {
7384                 { "Mic", 0x0 },
7385                 { "CD", 0x4 },
7386         },
7387 };
7388
7389 static struct hda_input_mux alc262_HP_capture_source = {
7390         .num_items = 5,
7391         .items = {
7392                 { "Mic", 0x0 },
7393                 { "Front Mic", 0x3 },
7394                 { "Line", 0x2 },
7395                 { "CD", 0x4 },
7396                 { "AUX IN", 0x6 },
7397         },
7398 };
7399
7400 /* mute/unmute internal speaker according to the hp jack and mute state */
7401 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7402 {
7403         struct alc_spec *spec = codec->spec;
7404         unsigned int mute;
7405
7406         if (force || !spec->sense_updated) {
7407                 unsigned int present;
7408                 /* need to execute and sync at first */
7409                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7410                 present = snd_hda_codec_read(codec, 0x14, 0,
7411                                          AC_VERB_GET_PIN_SENSE, 0);
7412                 spec->jack_present = (present & 0x80000000) != 0;
7413                 spec->sense_updated = 1;
7414         }
7415         if (spec->jack_present) {
7416                 /* mute internal speaker */
7417                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7418                                          0x80, 0x80);
7419                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7420                                          0x80, 0x80);
7421         } else {
7422                 /* unmute internal speaker if necessary */
7423                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7424                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7425                                          0x80, mute & 0x80);
7426                 mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
7427                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7428                                          0x80, mute & 0x80);
7429         }
7430 }
7431
7432 /* unsolicited event for HP jack sensing */
7433 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7434                                        unsigned int res)
7435 {
7436         if ((res >> 26) != ALC_HP_EVENT)
7437                 return;
7438         alc262_fujitsu_automute(codec, 1);
7439 }
7440
7441 /* bind volumes of both NID 0x0c and 0x0d */
7442 static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
7443                                          struct snd_ctl_elem_value *ucontrol)
7444 {
7445         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7446         long *valp = ucontrol->value.integer.value;
7447         int change;
7448
7449         change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
7450                                           0x7f, valp[0] & 0x7f);
7451         change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
7452                                            0x7f, valp[1] & 0x7f);
7453         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
7454                                  0x7f, valp[0] & 0x7f);
7455         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
7456                                  0x7f, valp[1] & 0x7f);
7457         return change;
7458 }
7459
7460 /* bind hp and internal speaker mute (with plug check) */
7461 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7462                                          struct snd_ctl_elem_value *ucontrol)
7463 {
7464         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7465         long *valp = ucontrol->value.integer.value;
7466         int change;
7467
7468         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7469                                           0x80, valp[0] ? 0 : 0x80);
7470         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7471                                            0x80, valp[1] ? 0 : 0x80);
7472         if (change || codec->in_resume)
7473                 alc262_fujitsu_automute(codec, codec->in_resume);
7474         return change;
7475 }
7476
7477 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7478         {
7479                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7480                 .name = "Master Playback Volume",
7481                 .info = snd_hda_mixer_amp_volume_info,
7482                 .get = snd_hda_mixer_amp_volume_get,
7483                 .put = alc262_fujitsu_master_vol_put,
7484                 .tlv = { .c = snd_hda_mixer_amp_tlv },
7485                 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7486         },
7487         {
7488                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7489                 .name = "Master Playback Switch",
7490                 .info = snd_hda_mixer_amp_switch_info,
7491                 .get = snd_hda_mixer_amp_switch_get,
7492                 .put = alc262_fujitsu_master_sw_put,
7493                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7494         },
7495         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7496         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7497         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7498         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7499         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7500         { } /* end */
7501 };
7502
7503 /* additional init verbs for Benq laptops */
7504 static struct hda_verb alc262_EAPD_verbs[] = {
7505         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7506         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7507         {}
7508 };
7509
7510 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7511         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7512         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7513
7514         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7515         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7516         {}
7517 };
7518
7519 /* add playback controls from the parsed DAC table */
7520 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7521                                              const struct auto_pin_cfg *cfg)
7522 {
7523         hda_nid_t nid;
7524         int err;
7525
7526         spec->multiout.num_dacs = 1;    /* only use one dac */
7527         spec->multiout.dac_nids = spec->private_dac_nids;
7528         spec->multiout.dac_nids[0] = 2;
7529
7530         nid = cfg->line_out_pins[0];
7531         if (nid) {
7532                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7533                                   "Front Playback Volume",
7534                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7535                 if (err < 0)
7536                         return err;
7537                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7538                                   "Front Playback Switch",
7539                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7540                 if (err < 0)
7541                         return err;
7542         }
7543
7544         nid = cfg->speaker_pins[0];
7545         if (nid) {
7546                 if (nid == 0x16) {
7547                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7548                                           "Speaker Playback Volume",
7549                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7550                                                               HDA_OUTPUT));
7551                         if (err < 0)
7552                                 return err;
7553                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7554                                           "Speaker Playback Switch",
7555                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7556                                                               HDA_OUTPUT));
7557                         if (err < 0)
7558                                 return err;
7559                 } else {
7560                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7561                                           "Speaker Playback Switch",
7562                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7563                                                               HDA_OUTPUT));
7564                         if (err < 0)
7565                                 return err;
7566                 }
7567         }
7568         nid = cfg->hp_pins[0];
7569         if (nid) {
7570                 /* spec->multiout.hp_nid = 2; */
7571                 if (nid == 0x16) {
7572                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7573                                           "Headphone Playback Volume",
7574                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7575                                                               HDA_OUTPUT));
7576                         if (err < 0)
7577                                 return err;
7578                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7579                                           "Headphone Playback Switch",
7580                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7581                                                               HDA_OUTPUT));
7582                         if (err < 0)
7583                                 return err;
7584                 } else {
7585                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7586                                           "Headphone Playback Switch",
7587                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7588                                                               HDA_OUTPUT));
7589                         if (err < 0)
7590                                 return err;
7591                 }
7592         }
7593         return 0;
7594 }
7595
7596 /* identical with ALC880 */
7597 #define alc262_auto_create_analog_input_ctls \
7598         alc880_auto_create_analog_input_ctls
7599
7600 /*
7601  * generic initialization of ADC, input mixers and output mixers
7602  */
7603 static struct hda_verb alc262_volume_init_verbs[] = {
7604         /*
7605          * Unmute ADC0-2 and set the default input to mic-in
7606          */
7607         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7608         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7609         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7610         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7611         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7612         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7613
7614         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7615          * mixer widget
7616          * Note: PASD motherboards uses the Line In 2 as the input for
7617          * front panel mic (mic 2)
7618          */
7619         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7620         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7621         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7622         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7623         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7624         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7625
7626         /*
7627          * Set up output mixers (0x0c - 0x0f)
7628          */
7629         /* set vol=0 to output mixers */
7630         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7631         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7632         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7633         
7634         /* set up input amps for analog loopback */
7635         /* Amp Indices: DAC = 0, mixer = 1 */
7636         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7637         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7638         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7639         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7640         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7641         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7642
7643         /* FIXME: use matrix-type input source selection */
7644         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7645         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7646         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7647         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7648         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7649         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7650         /* Input mixer2 */
7651         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7652         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7653         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7654         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7655         /* Input mixer3 */
7656         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7657         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7658         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7659         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7660
7661         { }
7662 };
7663
7664 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7665         /*
7666          * Unmute ADC0-2 and set the default input to mic-in
7667          */
7668         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7669         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7670         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7671         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7672         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7673         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7674
7675         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7676          * mixer widget
7677          * Note: PASD motherboards uses the Line In 2 as the input for
7678          * front panel mic (mic 2)
7679          */
7680         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7681         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7682         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7683         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7684         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7685         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7686         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7687         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7688         
7689         /*
7690          * Set up output mixers (0x0c - 0x0e)
7691          */
7692         /* set vol=0 to output mixers */
7693         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7694         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7695         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7696
7697         /* set up input amps for analog loopback */
7698         /* Amp Indices: DAC = 0, mixer = 1 */
7699         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7700         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7701         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7702         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7703         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7704         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7705
7706         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7707         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7708         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7709
7710         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7711         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7712
7713         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7714         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7715
7716         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7717         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7718         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7719         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7720         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7721
7722         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7723         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7724         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7725         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7726         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7727         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7728
7729
7730         /* FIXME: use matrix-type input source selection */
7731         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7732         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7733         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7734         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7735         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7736         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7737         /* Input mixer2 */
7738         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7739         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7740         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7741         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7742         /* Input mixer3 */
7743         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7744         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7745         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7746         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7747
7748         { }
7749 };
7750
7751 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7752         /*
7753          * Unmute ADC0-2 and set the default input to mic-in
7754          */
7755         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7756         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7757         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7758         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7759         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7760         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7761
7762         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7763          * mixer widget
7764          * Note: PASD motherboards uses the Line In 2 as the input for front
7765          * panel mic (mic 2)
7766          */
7767         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7768         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7769         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7770         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7771         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7772         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7773         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7774         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7775         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
7776         /*
7777          * Set up output mixers (0x0c - 0x0e)
7778          */
7779         /* set vol=0 to output mixers */
7780         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7781         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7782         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7783
7784         /* set up input amps for analog loopback */
7785         /* Amp Indices: DAC = 0, mixer = 1 */
7786         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7787         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7788         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7789         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7790         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7791         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7792
7793
7794         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
7795         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
7796         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
7797         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
7798         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
7799         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
7800         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
7801
7802         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7803         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7804
7805         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7806         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7807
7808         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7809         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7810         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7811         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7812         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7813         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7814
7815         /* FIXME: use matrix-type input source selection */
7816         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7817         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7818         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7819         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7820         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7821         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7822         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7823         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7824         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7825         /* Input mixer2 */
7826         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7827         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7828         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7829         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7830         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7831         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7832         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7833         /* Input mixer3 */
7834         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7835         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7836         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7837         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7838         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7839         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7840         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7841
7842         { }
7843 };
7844
7845 /* pcm configuration: identiacal with ALC880 */
7846 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
7847 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
7848 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
7849 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
7850
7851 /*
7852  * BIOS auto configuration
7853  */
7854 static int alc262_parse_auto_config(struct hda_codec *codec)
7855 {
7856         struct alc_spec *spec = codec->spec;
7857         int err;
7858         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7859
7860         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7861                                            alc262_ignore);
7862         if (err < 0)
7863                 return err;
7864         if (!spec->autocfg.line_outs)
7865                 return 0; /* can't find valid BIOS pin config */
7866         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7867         if (err < 0)
7868                 return err;
7869         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7870         if (err < 0)
7871                 return err;
7872
7873         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7874
7875         if (spec->autocfg.dig_out_pin)
7876                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7877         if (spec->autocfg.dig_in_pin)
7878                 spec->dig_in_nid = ALC262_DIGIN_NID;
7879
7880         if (spec->kctl_alloc)
7881                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7882
7883         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7884         spec->num_mux_defs = 1;
7885         spec->input_mux = &spec->private_imux;
7886
7887         return 1;
7888 }
7889
7890 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
7891 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
7892 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
7893
7894
7895 /* init callback for auto-configuration model -- overriding the default init */
7896 static void alc262_auto_init(struct hda_codec *codec)
7897 {
7898         alc262_auto_init_multi_out(codec);
7899         alc262_auto_init_hp_out(codec);
7900         alc262_auto_init_analog_input(codec);
7901 }
7902
7903 /*
7904  * configuration and preset
7905  */
7906 static const char *alc262_models[ALC262_MODEL_LAST] = {
7907         [ALC262_BASIC]          = "basic",
7908         [ALC262_HIPPO]          = "hippo",
7909         [ALC262_HIPPO_1]        = "hippo_1",
7910         [ALC262_FUJITSU]        = "fujitsu",
7911         [ALC262_HP_BPC]         = "hp-bpc",
7912         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7913         [ALC262_BENQ_ED8]       = "benq",
7914         [ALC262_BENQ_T31]       = "benq-t31",
7915         [ALC262_SONY_ASSAMD]    = "sony-assamd",
7916         [ALC262_AUTO]           = "auto",
7917 };
7918
7919 static struct snd_pci_quirk alc262_cfg_tbl[] = {
7920         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7921         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7922         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7923         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7924         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7925         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7926         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7927         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7928         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7929         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7930         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7931         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7932         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7933         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7934         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7935         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7936         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7937         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7938         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7939         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7940         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7941         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7942         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7943         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7944         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7945         {}
7946 };
7947
7948 static struct alc_config_preset alc262_presets[] = {
7949         [ALC262_BASIC] = {
7950                 .mixers = { alc262_base_mixer },
7951                 .init_verbs = { alc262_init_verbs },
7952                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7953                 .dac_nids = alc262_dac_nids,
7954                 .hp_nid = 0x03,
7955                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7956                 .channel_mode = alc262_modes,
7957                 .input_mux = &alc262_capture_source,
7958         },
7959         [ALC262_HIPPO] = {
7960                 .mixers = { alc262_base_mixer },
7961                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
7962                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7963                 .dac_nids = alc262_dac_nids,
7964                 .hp_nid = 0x03,
7965                 .dig_out_nid = ALC262_DIGOUT_NID,
7966                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7967                 .channel_mode = alc262_modes,
7968                 .input_mux = &alc262_capture_source,
7969                 .unsol_event = alc262_hippo_unsol_event,
7970         },
7971         [ALC262_HIPPO_1] = {
7972                 .mixers = { alc262_hippo1_mixer },
7973                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
7974                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7975                 .dac_nids = alc262_dac_nids,
7976                 .hp_nid = 0x02,
7977                 .dig_out_nid = ALC262_DIGOUT_NID,
7978                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7979                 .channel_mode = alc262_modes,
7980                 .input_mux = &alc262_capture_source,
7981                 .unsol_event = alc262_hippo1_unsol_event,
7982         },
7983         [ALC262_FUJITSU] = {
7984                 .mixers = { alc262_fujitsu_mixer },
7985                 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
7986                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7987                 .dac_nids = alc262_dac_nids,
7988                 .hp_nid = 0x03,
7989                 .dig_out_nid = ALC262_DIGOUT_NID,
7990                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7991                 .channel_mode = alc262_modes,
7992                 .input_mux = &alc262_fujitsu_capture_source,
7993                 .unsol_event = alc262_fujitsu_unsol_event,
7994         },
7995         [ALC262_HP_BPC] = {
7996                 .mixers = { alc262_HP_BPC_mixer },
7997                 .init_verbs = { alc262_HP_BPC_init_verbs },
7998                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7999                 .dac_nids = alc262_dac_nids,
8000                 .hp_nid = 0x03,
8001                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8002                 .channel_mode = alc262_modes,
8003                 .input_mux = &alc262_HP_capture_source,
8004         },
8005         [ALC262_HP_BPC_D7000_WF] = {
8006                 .mixers = { alc262_HP_BPC_WildWest_mixer },
8007                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8008                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8009                 .dac_nids = alc262_dac_nids,
8010                 .hp_nid = 0x03,
8011                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8012                 .channel_mode = alc262_modes,
8013                 .input_mux = &alc262_HP_capture_source,
8014         },
8015         [ALC262_HP_BPC_D7000_WL] = {
8016                 .mixers = { alc262_HP_BPC_WildWest_mixer,
8017                             alc262_HP_BPC_WildWest_option_mixer },
8018                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8019                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8020                 .dac_nids = alc262_dac_nids,
8021                 .hp_nid = 0x03,
8022                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8023                 .channel_mode = alc262_modes,
8024                 .input_mux = &alc262_HP_capture_source,
8025         },
8026         [ALC262_BENQ_ED8] = {
8027                 .mixers = { alc262_base_mixer },
8028                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8029                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8030                 .dac_nids = alc262_dac_nids,
8031                 .hp_nid = 0x03,
8032                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8033                 .channel_mode = alc262_modes,
8034                 .input_mux = &alc262_capture_source,
8035         },
8036         [ALC262_SONY_ASSAMD] = {
8037                 .mixers = { alc262_sony_mixer },
8038                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8039                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8040                 .dac_nids = alc262_dac_nids,
8041                 .hp_nid = 0x02,
8042                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8043                 .channel_mode = alc262_modes,
8044                 .input_mux = &alc262_capture_source,
8045                 .unsol_event = alc262_hippo_unsol_event,
8046         },
8047         [ALC262_BENQ_T31] = {
8048                 .mixers = { alc262_benq_t31_mixer },
8049                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8050                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8051                 .dac_nids = alc262_dac_nids,
8052                 .hp_nid = 0x03,
8053                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8054                 .channel_mode = alc262_modes,
8055                 .input_mux = &alc262_capture_source,
8056                 .unsol_event = alc262_hippo_unsol_event,
8057         },      
8058 };
8059
8060 static int patch_alc262(struct hda_codec *codec)
8061 {
8062         struct alc_spec *spec;
8063         int board_config;
8064         int err;
8065
8066         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8067         if (spec == NULL)
8068                 return -ENOMEM;
8069
8070         codec->spec = spec;
8071 #if 0
8072         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8073          * under-run
8074          */
8075         {
8076         int tmp;
8077         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8078         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8079         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8080         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8081         }
8082 #endif
8083
8084         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8085                                                   alc262_models,
8086                                                   alc262_cfg_tbl);
8087
8088         if (board_config < 0) {
8089                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8090                        "trying auto-probe from BIOS...\n");
8091                 board_config = ALC262_AUTO;
8092         }
8093
8094         if (board_config == ALC262_AUTO) {
8095                 /* automatic parse from the BIOS config */
8096                 err = alc262_parse_auto_config(codec);
8097                 if (err < 0) {
8098                         alc_free(codec);
8099                         return err;
8100                 } else if (!err) {
8101                         printk(KERN_INFO
8102                                "hda_codec: Cannot set up configuration "
8103                                "from BIOS.  Using base mode...\n");
8104                         board_config = ALC262_BASIC;
8105                 }
8106         }
8107
8108         if (board_config != ALC262_AUTO)
8109                 setup_preset(spec, &alc262_presets[board_config]);
8110
8111         spec->stream_name_analog = "ALC262 Analog";
8112         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8113         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8114                 
8115         spec->stream_name_digital = "ALC262 Digital";
8116         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8117         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8118
8119         if (!spec->adc_nids && spec->input_mux) {
8120                 /* check whether NID 0x07 is valid */
8121                 unsigned int wcap = get_wcaps(codec, 0x07);
8122
8123                 /* get type */
8124                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8125                 if (wcap != AC_WID_AUD_IN) {
8126                         spec->adc_nids = alc262_adc_nids_alt;
8127                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8128                         spec->mixers[spec->num_mixers] =
8129                                 alc262_capture_alt_mixer;
8130                         spec->num_mixers++;
8131                 } else {
8132                         spec->adc_nids = alc262_adc_nids;
8133                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8134                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8135                         spec->num_mixers++;
8136                 }
8137         }
8138
8139         codec->patch_ops = alc_patch_ops;
8140         if (board_config == ALC262_AUTO)
8141                 spec->init_hook = alc262_auto_init;
8142                 
8143         return 0;
8144 }
8145
8146 /*
8147  *  ALC268 channel source setting (2 channel)
8148  */
8149 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8150 #define alc268_modes            alc260_modes
8151         
8152 static hda_nid_t alc268_dac_nids[2] = {
8153         /* front, hp */
8154         0x02, 0x03
8155 };
8156
8157 static hda_nid_t alc268_adc_nids[2] = {
8158         /* ADC0-1 */
8159         0x08, 0x07
8160 };
8161
8162 static hda_nid_t alc268_adc_nids_alt[1] = {
8163         /* ADC0 */
8164         0x08
8165 };
8166
8167 static struct snd_kcontrol_new alc268_base_mixer[] = {
8168         /* output mixer control */
8169         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8170         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8171         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8172         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8173         { }
8174 };
8175
8176 /*
8177  * generic initialization of ADC, input mixers and output mixers
8178  */
8179 static struct hda_verb alc268_base_init_verbs[] = {
8180         /* Unmute DAC0-1 and set vol = 0 */
8181         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8182         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8183         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8184         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8185         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8186         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8187
8188         /*
8189          * Set up output mixers (0x0c - 0x0e)
8190          */
8191         /* set vol=0 to output mixers */
8192         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8193         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8194         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8195         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8196
8197         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8198         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8199
8200         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8201         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8202         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8203         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8204         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8205         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8206         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8207         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8208
8209         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8210         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8211         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8212         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8213         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8214         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8215         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8216         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8217
8218         /* FIXME: use matrix-type input source selection */
8219         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8220         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8221         /* Input mixer2 */
8222         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8223         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8224         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8225         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8226
8227         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8228         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8229         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8230         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8231         { }
8232 };
8233
8234 /*
8235  * generic initialization of ADC, input mixers and output mixers
8236  */
8237 static struct hda_verb alc268_volume_init_verbs[] = {
8238         /* set output DAC */
8239         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8240         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8241         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8242         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8243
8244         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8245         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8246         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8247         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8248         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8249
8250         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8251         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8252         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8253         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8254         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8255
8256         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8257         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8258         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8259         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8260
8261         /* set PCBEEP vol = 0 */
8262         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8263
8264         { }
8265 };
8266
8267 #define alc268_mux_enum_info alc_mux_enum_info
8268 #define alc268_mux_enum_get alc_mux_enum_get
8269
8270 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8271                                struct snd_ctl_elem_value *ucontrol)
8272 {
8273         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8274         struct alc_spec *spec = codec->spec;
8275         const struct hda_input_mux *imux = spec->input_mux;
8276         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8277         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8278         hda_nid_t nid = capture_mixers[adc_idx];
8279         unsigned int *cur_val = &spec->cur_mux[adc_idx];
8280         unsigned int i, idx;
8281
8282         idx = ucontrol->value.enumerated.item[0];
8283         if (idx >= imux->num_items)
8284                 idx = imux->num_items - 1;
8285         if (*cur_val == idx && !codec->in_resume)
8286                 return 0;
8287         for (i = 0; i < imux->num_items; i++) {
8288                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8289                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8290                                     v | (imux->items[i].index << 8));
8291                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
8292                                     idx );
8293         }
8294         *cur_val = idx;
8295         return 1;
8296 }
8297
8298 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8299         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8300         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8301         {
8302                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8303                 /* The multiple "Capture Source" controls confuse alsamixer
8304                  * So call somewhat different..
8305                  * FIXME: the controls appear in the "playback" view!
8306                  */
8307                 /* .name = "Capture Source", */
8308                 .name = "Input Source",
8309                 .count = 1,
8310                 .info = alc268_mux_enum_info,
8311                 .get = alc268_mux_enum_get,
8312                 .put = alc268_mux_enum_put,
8313         },
8314         { } /* end */
8315 };
8316
8317 static struct snd_kcontrol_new alc268_capture_mixer[] = {
8318         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8319         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8320         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8321         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8322         {
8323                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8324                 /* The multiple "Capture Source" controls confuse alsamixer
8325                  * So call somewhat different..
8326                  * FIXME: the controls appear in the "playback" view!
8327                  */
8328                 /* .name = "Capture Source", */
8329                 .name = "Input Source",
8330                 .count = 2,
8331                 .info = alc268_mux_enum_info,
8332                 .get = alc268_mux_enum_get,
8333                 .put = alc268_mux_enum_put,
8334         },
8335         { } /* end */
8336 };
8337
8338 static struct hda_input_mux alc268_capture_source = {
8339         .num_items = 4,
8340         .items = {
8341                 { "Mic", 0x0 },
8342                 { "Front Mic", 0x1 },
8343                 { "Line", 0x2 },
8344                 { "CD", 0x3 },
8345         },
8346 };
8347
8348 /* create input playback/capture controls for the given pin */
8349 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8350                                     const char *ctlname, int idx)
8351 {
8352         char name[32];
8353         int err;
8354
8355         sprintf(name, "%s Playback Volume", ctlname);
8356         if (nid == 0x14) {
8357                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8358                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8359                                                       HDA_OUTPUT));
8360                 if (err < 0)
8361                         return err;
8362         } else if (nid == 0x15) {
8363                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8364                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8365                                                       HDA_OUTPUT));
8366                 if (err < 0)
8367                         return err;
8368         } else
8369                 return -1;
8370         sprintf(name, "%s Playback Switch", ctlname);
8371         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8372                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8373         if (err < 0)
8374                 return err;
8375         return 0;
8376 }
8377
8378 /* add playback controls from the parsed DAC table */
8379 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8380                                              const struct auto_pin_cfg *cfg)
8381 {
8382         hda_nid_t nid;
8383         int err;
8384
8385         spec->multiout.num_dacs = 2;    /* only use one dac */
8386         spec->multiout.dac_nids = spec->private_dac_nids;
8387         spec->multiout.dac_nids[0] = 2;
8388         spec->multiout.dac_nids[1] = 3;
8389
8390         nid = cfg->line_out_pins[0];
8391         if (nid)
8392                 alc268_new_analog_output(spec, nid, "Front", 0);        
8393
8394         nid = cfg->speaker_pins[0];
8395         if (nid == 0x1d) {
8396                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8397                                   "Speaker Playback Volume",
8398                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8399                 if (err < 0)
8400                         return err;
8401         }
8402         nid = cfg->hp_pins[0];
8403         if (nid)
8404                 alc268_new_analog_output(spec, nid, "Headphone", 0);
8405
8406         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8407         if (nid == 0x16) {
8408                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8409                                   "Mono Playback Switch",
8410                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8411                 if (err < 0)
8412                         return err;
8413         }
8414         return 0;       
8415 }
8416
8417 /* create playback/capture controls for input pins */
8418 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8419                                                 const struct auto_pin_cfg *cfg)
8420 {
8421         struct hda_input_mux *imux = &spec->private_imux;
8422         int i, idx1;
8423
8424         for (i = 0; i < AUTO_PIN_LAST; i++) {
8425                 switch(cfg->input_pins[i]) {
8426                 case 0x18:
8427                         idx1 = 0;       /* Mic 1 */
8428                         break;
8429                 case 0x19:
8430                         idx1 = 1;       /* Mic 2 */
8431                         break;
8432                 case 0x1a:
8433                         idx1 = 2;       /* Line In */
8434                         break;
8435                 case 0x1c:      
8436                         idx1 = 3;       /* CD */
8437                         break;
8438                 default:
8439                         continue;
8440                 }
8441                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8442                 imux->items[imux->num_items].index = idx1;
8443                 imux->num_items++;      
8444         }
8445         return 0;
8446 }
8447
8448 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8449 {
8450         struct alc_spec *spec = codec->spec;
8451         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8452         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8453         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8454         unsigned int    dac_vol1, dac_vol2;
8455
8456         if (speaker_nid) {
8457                 snd_hda_codec_write(codec, speaker_nid, 0,
8458                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8459                 snd_hda_codec_write(codec, 0x0f, 0,
8460                                     AC_VERB_SET_AMP_GAIN_MUTE,
8461                                     AMP_IN_UNMUTE(1));
8462                 snd_hda_codec_write(codec, 0x10, 0,
8463                                     AC_VERB_SET_AMP_GAIN_MUTE,
8464                                     AMP_IN_UNMUTE(1));
8465         } else {
8466                 snd_hda_codec_write(codec, 0x0f, 0,
8467                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8468                 snd_hda_codec_write(codec, 0x10, 0,
8469                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8470         }
8471
8472         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
8473         if (line_nid == 0x14)   
8474                 dac_vol2 = AMP_OUT_ZERO;
8475         else if (line_nid == 0x15)
8476                 dac_vol1 = AMP_OUT_ZERO;
8477         if (hp_nid == 0x14)     
8478                 dac_vol2 = AMP_OUT_ZERO;
8479         else if (hp_nid == 0x15)
8480                 dac_vol1 = AMP_OUT_ZERO;
8481         if (line_nid != 0x16 || hp_nid != 0x16 ||
8482             spec->autocfg.line_out_pins[1] != 0x16 ||
8483             spec->autocfg.line_out_pins[2] != 0x16)
8484                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8485
8486         snd_hda_codec_write(codec, 0x02, 0,
8487                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8488         snd_hda_codec_write(codec, 0x03, 0,
8489                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8490 }
8491
8492 /* pcm configuration: identiacal with ALC880 */
8493 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
8494 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
8495 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
8496
8497 /*
8498  * BIOS auto configuration
8499  */
8500 static int alc268_parse_auto_config(struct hda_codec *codec)
8501 {
8502         struct alc_spec *spec = codec->spec;
8503         int err;
8504         static hda_nid_t alc268_ignore[] = { 0 };
8505
8506         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8507                                            alc268_ignore);
8508         if (err < 0)
8509                 return err;
8510         if (!spec->autocfg.line_outs)
8511                 return 0; /* can't find valid BIOS pin config */
8512
8513         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8514         if (err < 0)
8515                 return err;
8516         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8517         if (err < 0)
8518                 return err;
8519
8520         spec->multiout.max_channels = 2;
8521
8522         /* digital only support output */
8523         if (spec->autocfg.dig_out_pin)
8524                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8525
8526         if (spec->kctl_alloc)
8527                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8528
8529         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8530         spec->num_mux_defs = 1;
8531         spec->input_mux = &spec->private_imux;
8532
8533         return 1;
8534 }
8535
8536 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
8537 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
8538 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
8539
8540 /* init callback for auto-configuration model -- overriding the default init */
8541 static void alc268_auto_init(struct hda_codec *codec)
8542 {
8543         alc268_auto_init_multi_out(codec);
8544         alc268_auto_init_hp_out(codec);
8545         alc268_auto_init_mono_speaker_out(codec);
8546         alc268_auto_init_analog_input(codec);
8547 }
8548
8549 /*
8550  * configuration and preset
8551  */
8552 static const char *alc268_models[ALC268_MODEL_LAST] = {
8553         [ALC268_3ST]            = "3stack",
8554         [ALC268_AUTO]           = "auto",
8555 };
8556
8557 static struct snd_pci_quirk alc268_cfg_tbl[] = {
8558         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8559         {}
8560 };
8561
8562 static struct alc_config_preset alc268_presets[] = {
8563         [ALC268_3ST] = {
8564                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8565                 .init_verbs = { alc268_base_init_verbs },
8566                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8567                 .dac_nids = alc268_dac_nids,
8568                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8569                 .adc_nids = alc268_adc_nids_alt,
8570                 .hp_nid = 0x03,
8571                 .dig_out_nid = ALC268_DIGOUT_NID,
8572                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8573                 .channel_mode = alc268_modes,
8574                 .input_mux = &alc268_capture_source,
8575         },
8576 };
8577
8578 static int patch_alc268(struct hda_codec *codec)
8579 {
8580         struct alc_spec *spec;
8581         int board_config;
8582         int err;
8583
8584         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8585         if (spec == NULL)
8586                 return -ENOMEM;
8587
8588         codec->spec = spec;
8589
8590         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8591                                                   alc268_models,
8592                                                   alc268_cfg_tbl);
8593
8594         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8595                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8596                        "trying auto-probe from BIOS...\n");
8597                 board_config = ALC268_AUTO;
8598         }
8599
8600         if (board_config == ALC268_AUTO) {
8601                 /* automatic parse from the BIOS config */
8602                 err = alc268_parse_auto_config(codec);
8603                 if (err < 0) {
8604                         alc_free(codec);
8605                         return err;
8606                 } else if (!err) {
8607                         printk(KERN_INFO
8608                                "hda_codec: Cannot set up configuration "
8609                                "from BIOS.  Using base mode...\n");
8610                         board_config = ALC268_3ST;
8611                 }
8612         }
8613
8614         if (board_config != ALC268_AUTO)
8615                 setup_preset(spec, &alc268_presets[board_config]);
8616
8617         spec->stream_name_analog = "ALC268 Analog";
8618         spec->stream_analog_playback = &alc268_pcm_analog_playback;
8619         spec->stream_analog_capture = &alc268_pcm_analog_capture;
8620
8621         spec->stream_name_digital = "ALC268 Digital";
8622         spec->stream_digital_playback = &alc268_pcm_digital_playback;
8623
8624         if (board_config == ALC268_AUTO) {
8625                 if (!spec->adc_nids && spec->input_mux) {
8626                         /* check whether NID 0x07 is valid */
8627                         unsigned int wcap = get_wcaps(codec, 0x07);
8628
8629                         /* get type */
8630                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8631                         if (wcap != AC_WID_AUD_IN) {
8632                                 spec->adc_nids = alc268_adc_nids_alt;
8633                                 spec->num_adc_nids =
8634                                         ARRAY_SIZE(alc268_adc_nids_alt);
8635                                 spec->mixers[spec->num_mixers] =
8636                                         alc268_capture_alt_mixer;
8637                                 spec->num_mixers++;
8638                         } else {
8639                                 spec->adc_nids = alc268_adc_nids;
8640                                 spec->num_adc_nids =
8641                                         ARRAY_SIZE(alc268_adc_nids);
8642                                 spec->mixers[spec->num_mixers] =
8643                                         alc268_capture_mixer;
8644                                 spec->num_mixers++;
8645                         }
8646                 }
8647         }
8648         codec->patch_ops = alc_patch_ops;
8649         if (board_config == ALC268_AUTO)
8650                 spec->init_hook = alc268_auto_init;
8651                 
8652         return 0;
8653 }
8654
8655 /*
8656  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8657  */
8658
8659 /*
8660  * set the path ways for 2 channel output
8661  * need to set the codec line out and mic 1 pin widgets to inputs
8662  */
8663 static struct hda_verb alc861_threestack_ch2_init[] = {
8664         /* set pin widget 1Ah (line in) for input */
8665         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8666         /* set pin widget 18h (mic1/2) for input, for mic also enable
8667          * the vref
8668          */
8669         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8670
8671         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8672 #if 0
8673         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8674         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8675 #endif
8676         { } /* end */
8677 };
8678 /*
8679  * 6ch mode
8680  * need to set the codec line out and mic 1 pin widgets to outputs
8681  */
8682 static struct hda_verb alc861_threestack_ch6_init[] = {
8683         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8684         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8685         /* set pin widget 18h (mic1) for output (CLFE)*/
8686         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8687
8688         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8689         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8690
8691         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8692 #if 0
8693         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8694         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8695 #endif
8696         { } /* end */
8697 };
8698
8699 static struct hda_channel_mode alc861_threestack_modes[2] = {
8700         { 2, alc861_threestack_ch2_init },
8701         { 6, alc861_threestack_ch6_init },
8702 };
8703 /* Set mic1 as input and unmute the mixer */
8704 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8705         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8706         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8707         { } /* end */
8708 };
8709 /* Set mic1 as output and mute mixer */
8710 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8711         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8712         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8713         { } /* end */
8714 };
8715
8716 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8717         { 2, alc861_uniwill_m31_ch2_init },
8718         { 4, alc861_uniwill_m31_ch4_init },
8719 };
8720
8721 /* Set mic1 and line-in as input and unmute the mixer */
8722 static struct hda_verb alc861_asus_ch2_init[] = {
8723         /* set pin widget 1Ah (line in) for input */
8724         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8725         /* set pin widget 18h (mic1/2) for input, for mic also enable
8726          * the vref
8727          */
8728         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8729
8730         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8731 #if 0
8732         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8733         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8734 #endif
8735         { } /* end */
8736 };
8737 /* Set mic1 nad line-in as output and mute mixer */
8738 static struct hda_verb alc861_asus_ch6_init[] = {
8739         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8740         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8741         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8742         /* set pin widget 18h (mic1) for output (CLFE)*/
8743         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8744         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8745         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8746         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8747
8748         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8749 #if 0
8750         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8751         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8752 #endif
8753         { } /* end */
8754 };
8755
8756 static struct hda_channel_mode alc861_asus_modes[2] = {
8757         { 2, alc861_asus_ch2_init },
8758         { 6, alc861_asus_ch6_init },
8759 };
8760
8761 /* patch-ALC861 */
8762
8763 static struct snd_kcontrol_new alc861_base_mixer[] = {
8764         /* output mixer control */
8765         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8766         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8767         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8768         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8769         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8770
8771         /*Input mixer control */
8772         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8773            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8774         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8775         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8776         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8777         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8778         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8779         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8780         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8781         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8782
8783         /* Capture mixer control */
8784         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8785         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8786         {
8787                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8788                 .name = "Capture Source",
8789                 .count = 1,
8790                 .info = alc_mux_enum_info,
8791                 .get = alc_mux_enum_get,
8792                 .put = alc_mux_enum_put,
8793         },
8794         { } /* end */
8795 };
8796
8797 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8798         /* output mixer control */
8799         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8800         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8801         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8802         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8803         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8804
8805         /* Input mixer control */
8806         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8807            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8808         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8809         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8810         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8811         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8812         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8813         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8814         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8815         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8816
8817         /* Capture mixer control */
8818         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8819         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8820         {
8821                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8822                 .name = "Capture Source",
8823                 .count = 1,
8824                 .info = alc_mux_enum_info,
8825                 .get = alc_mux_enum_get,
8826                 .put = alc_mux_enum_put,
8827         },
8828         {
8829                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8830                 .name = "Channel Mode",
8831                 .info = alc_ch_mode_info,
8832                 .get = alc_ch_mode_get,
8833                 .put = alc_ch_mode_put,
8834                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
8835         },
8836         { } /* end */
8837 };
8838
8839 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8840         /* output mixer control */
8841         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8842         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8843         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8844         
8845         /*Capture mixer control */
8846         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8847         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8848         {
8849                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8850                 .name = "Capture Source",
8851                 .count = 1,
8852                 .info = alc_mux_enum_info,
8853                 .get = alc_mux_enum_get,
8854                 .put = alc_mux_enum_put,
8855         },
8856
8857         { } /* end */
8858 };
8859
8860 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8861         /* output mixer control */
8862         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8863         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8864         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8865         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8866         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8867
8868         /* Input mixer control */
8869         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8870            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8871         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8872         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8873         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8874         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8875         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8876         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8877         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8878         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8879
8880         /* Capture mixer control */
8881         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8882         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8883         {
8884                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8885                 .name = "Capture Source",
8886                 .count = 1,
8887                 .info = alc_mux_enum_info,
8888                 .get = alc_mux_enum_get,
8889                 .put = alc_mux_enum_put,
8890         },
8891         {
8892                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8893                 .name = "Channel Mode",
8894                 .info = alc_ch_mode_info,
8895                 .get = alc_ch_mode_get,
8896                 .put = alc_ch_mode_put,
8897                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8898         },
8899         { } /* end */
8900 };
8901
8902 static struct snd_kcontrol_new alc861_asus_mixer[] = {
8903         /* output mixer control */
8904         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8905         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8906         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8907         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8908         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8909
8910         /* Input mixer control */
8911         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8912         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8913         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8914         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8915         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8916         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8917         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8918         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8919         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8920         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
8921
8922         /* Capture mixer control */
8923         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8924         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8925         {
8926                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8927                 .name = "Capture Source",
8928                 .count = 1,
8929                 .info = alc_mux_enum_info,
8930                 .get = alc_mux_enum_get,
8931                 .put = alc_mux_enum_put,
8932         },
8933         {
8934                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8935                 .name = "Channel Mode",
8936                 .info = alc_ch_mode_info,
8937                 .get = alc_ch_mode_get,
8938                 .put = alc_ch_mode_put,
8939                 .private_value = ARRAY_SIZE(alc861_asus_modes),
8940         },
8941         { }
8942 };
8943
8944 /* additional mixer */
8945 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
8946         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8947         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8948         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
8949         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
8950         { }
8951 };
8952
8953 /*
8954  * generic initialization of ADC, input mixers and output mixers
8955  */
8956 static struct hda_verb alc861_base_init_verbs[] = {
8957         /*
8958          * Unmute ADC0 and set the default input to mic-in
8959          */
8960         /* port-A for surround (rear panel) */
8961         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8962         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
8963         /* port-B for mic-in (rear panel) with vref */
8964         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8965         /* port-C for line-in (rear panel) */
8966         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8967         /* port-D for Front */
8968         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8969         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8970         /* port-E for HP out (front panel) */
8971         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8972         /* route front PCM to HP */
8973         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8974         /* port-F for mic-in (front panel) with vref */
8975         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8976         /* port-G for CLFE (rear panel) */
8977         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8978         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8979         /* port-H for side (rear panel) */
8980         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8981         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
8982         /* CD-in */
8983         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8984         /* route front mic to ADC1*/
8985         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8986         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8987         
8988         /* Unmute DAC0~3 & spdif out*/
8989         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8990         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8991         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8992         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8993         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8994         
8995         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8996         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8997         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8998         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8999         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9000         
9001         /* Unmute Stereo Mixer 15 */
9002         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9003         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9004         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9005         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9006
9007         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9008         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9009         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9010         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9011         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9012         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9013         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9014         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9015         /* hp used DAC 3 (Front) */
9016         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9017         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9018
9019         { }
9020 };
9021
9022 static struct hda_verb alc861_threestack_init_verbs[] = {
9023         /*
9024          * Unmute ADC0 and set the default input to mic-in
9025          */
9026         /* port-A for surround (rear panel) */
9027         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9028         /* port-B for mic-in (rear panel) with vref */
9029         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9030         /* port-C for line-in (rear panel) */
9031         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9032         /* port-D for Front */
9033         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9034         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9035         /* port-E for HP out (front panel) */
9036         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9037         /* route front PCM to HP */
9038         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9039         /* port-F for mic-in (front panel) with vref */
9040         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9041         /* port-G for CLFE (rear panel) */
9042         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9043         /* port-H for side (rear panel) */
9044         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9045         /* CD-in */
9046         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9047         /* route front mic to ADC1*/
9048         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9049         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9050         /* Unmute DAC0~3 & spdif out*/
9051         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9052         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9053         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9054         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9055         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9056         
9057         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9058         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9059         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9060         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9061         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9062         
9063         /* Unmute Stereo Mixer 15 */
9064         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9066         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9067         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9068
9069         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9070         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9071         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9072         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9073         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9074         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9075         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9076         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9077         /* hp used DAC 3 (Front) */
9078         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9079         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9080         { }
9081 };
9082
9083 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9084         /*
9085          * Unmute ADC0 and set the default input to mic-in
9086          */
9087         /* port-A for surround (rear panel) */
9088         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9089         /* port-B for mic-in (rear panel) with vref */
9090         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9091         /* port-C for line-in (rear panel) */
9092         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9093         /* port-D for Front */
9094         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9095         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9096         /* port-E for HP out (front panel) */
9097         /* this has to be set to VREF80 */
9098         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9099         /* route front PCM to HP */
9100         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9101         /* port-F for mic-in (front panel) with vref */
9102         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9103         /* port-G for CLFE (rear panel) */
9104         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9105         /* port-H for side (rear panel) */
9106         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9107         /* CD-in */
9108         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9109         /* route front mic to ADC1*/
9110         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9111         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9112         /* Unmute DAC0~3 & spdif out*/
9113         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9114         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9115         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9116         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9117         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9118         
9119         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9120         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9121         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9122         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9123         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9124         
9125         /* Unmute Stereo Mixer 15 */
9126         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9127         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9128         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9129         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9130
9131         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9132         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9133         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9134         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9135         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9136         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9137         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9138         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9139         /* hp used DAC 3 (Front) */
9140         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9141         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9142         { }
9143 };
9144
9145 static struct hda_verb alc861_asus_init_verbs[] = {
9146         /*
9147          * Unmute ADC0 and set the default input to mic-in
9148          */
9149         /* port-A for surround (rear panel)
9150          * according to codec#0 this is the HP jack
9151          */
9152         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9153         /* route front PCM to HP */
9154         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9155         /* port-B for mic-in (rear panel) with vref */
9156         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9157         /* port-C for line-in (rear panel) */
9158         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9159         /* port-D for Front */
9160         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9161         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9162         /* port-E for HP out (front panel) */
9163         /* this has to be set to VREF80 */
9164         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9165         /* route front PCM to HP */
9166         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9167         /* port-F for mic-in (front panel) with vref */
9168         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9169         /* port-G for CLFE (rear panel) */
9170         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9171         /* port-H for side (rear panel) */
9172         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9173         /* CD-in */
9174         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9175         /* route front mic to ADC1*/
9176         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9177         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9178         /* Unmute DAC0~3 & spdif out*/
9179         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9180         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9181         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9182         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9183         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9184         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9185         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9186         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9187         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9188         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9189         
9190         /* Unmute Stereo Mixer 15 */
9191         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9192         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9193         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9194         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9195
9196         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9197         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9198         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9199         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9200         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9201         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9202         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9203         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9204         /* hp used DAC 3 (Front) */
9205         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9206         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9207         { }
9208 };
9209
9210 /* additional init verbs for ASUS laptops */
9211 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9212         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9213         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9214         { }
9215 };
9216
9217 /*
9218  * generic initialization of ADC, input mixers and output mixers
9219  */
9220 static struct hda_verb alc861_auto_init_verbs[] = {
9221         /*
9222          * Unmute ADC0 and set the default input to mic-in
9223          */
9224         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9225         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9226         
9227         /* Unmute DAC0~3 & spdif out*/
9228         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9229         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9230         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9231         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9232         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9233         
9234         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9235         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9236         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9237         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9238         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9239         
9240         /* Unmute Stereo Mixer 15 */
9241         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9242         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9243         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9244         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9245
9246         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9247         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9248         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9249         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9250         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9251         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9252         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9253         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9254
9255         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9256         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9257         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9258         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9259         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9260         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9261         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9262         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9263
9264         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
9265
9266         { }
9267 };
9268
9269 static struct hda_verb alc861_toshiba_init_verbs[] = {
9270         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9271
9272         { }
9273 };
9274
9275 /* toggle speaker-output according to the hp-jack state */
9276 static void alc861_toshiba_automute(struct hda_codec *codec)
9277 {
9278         unsigned int present;
9279
9280         present = snd_hda_codec_read(codec, 0x0f, 0,
9281                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9282         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
9283                                  0x80, present ? 0x80 : 0);
9284         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
9285                                  0x80, present ? 0x80 : 0);
9286         snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
9287                                  0x80, present ? 0 : 0x80);
9288         snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
9289                                  0x80, present ? 0 : 0x80);
9290 }
9291
9292 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9293                                        unsigned int res)
9294 {
9295         if ((res >> 26) == ALC880_HP_EVENT)
9296                 alc861_toshiba_automute(codec);
9297 }
9298
9299 /* pcm configuration: identiacal with ALC880 */
9300 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
9301 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
9302 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
9303 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
9304
9305
9306 #define ALC861_DIGOUT_NID       0x07
9307
9308 static struct hda_channel_mode alc861_8ch_modes[1] = {
9309         { 8, NULL }
9310 };
9311
9312 static hda_nid_t alc861_dac_nids[4] = {
9313         /* front, surround, clfe, side */
9314         0x03, 0x06, 0x05, 0x04
9315 };
9316
9317 static hda_nid_t alc660_dac_nids[3] = {
9318         /* front, clfe, surround */
9319         0x03, 0x05, 0x06
9320 };
9321
9322 static hda_nid_t alc861_adc_nids[1] = {
9323         /* ADC0-2 */
9324         0x08,
9325 };
9326
9327 static struct hda_input_mux alc861_capture_source = {
9328         .num_items = 5,
9329         .items = {
9330                 { "Mic", 0x0 },
9331                 { "Front Mic", 0x3 },
9332                 { "Line", 0x1 },
9333                 { "CD", 0x4 },
9334                 { "Mixer", 0x5 },
9335         },
9336 };
9337
9338 /* fill in the dac_nids table from the parsed pin configuration */
9339 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9340                                      const struct auto_pin_cfg *cfg)
9341 {
9342         int i;
9343         hda_nid_t nid;
9344
9345         spec->multiout.dac_nids = spec->private_dac_nids;
9346         for (i = 0; i < cfg->line_outs; i++) {
9347                 nid = cfg->line_out_pins[i];
9348                 if (nid) {
9349                         if (i >= ARRAY_SIZE(alc861_dac_nids))
9350                                 continue;
9351                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9352                 }
9353         }
9354         spec->multiout.num_dacs = cfg->line_outs;
9355         return 0;
9356 }
9357
9358 /* add playback controls from the parsed DAC table */
9359 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9360                                              const struct auto_pin_cfg *cfg)
9361 {
9362         char name[32];
9363         static const char *chname[4] = {
9364                 "Front", "Surround", NULL /*CLFE*/, "Side"
9365         };
9366         hda_nid_t nid;
9367         int i, idx, err;
9368
9369         for (i = 0; i < cfg->line_outs; i++) {
9370                 nid = spec->multiout.dac_nids[i];
9371                 if (!nid)
9372                         continue;
9373                 if (nid == 0x05) {
9374                         /* Center/LFE */
9375                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9376                                           "Center Playback Switch",
9377                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9378                                                               HDA_OUTPUT));
9379                         if (err < 0)
9380                                 return err;
9381                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9382                                           "LFE Playback Switch",
9383                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9384                                                               HDA_OUTPUT));
9385                         if (err < 0)
9386                                 return err;
9387                 } else {
9388                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9389                              idx++)
9390                                 if (nid == alc861_dac_nids[idx])
9391                                         break;
9392                         sprintf(name, "%s Playback Switch", chname[idx]);
9393                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9394                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9395                                                               HDA_OUTPUT));
9396                         if (err < 0)
9397                                 return err;
9398                 }
9399         }
9400         return 0;
9401 }
9402
9403 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9404 {
9405         int err;
9406         hda_nid_t nid;
9407
9408         if (!pin)
9409                 return 0;
9410
9411         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9412                 nid = 0x03;
9413                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9414                                   "Headphone Playback Switch",
9415                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9416                 if (err < 0)
9417                         return err;
9418                 spec->multiout.hp_nid = nid;
9419         }
9420         return 0;
9421 }
9422
9423 /* create playback/capture controls for input pins */
9424 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9425                                                 const struct auto_pin_cfg *cfg)
9426 {
9427         struct hda_input_mux *imux = &spec->private_imux;
9428         int i, err, idx, idx1;
9429
9430         for (i = 0; i < AUTO_PIN_LAST; i++) {
9431                 switch (cfg->input_pins[i]) {
9432                 case 0x0c:
9433                         idx1 = 1;
9434                         idx = 2;        /* Line In */
9435                         break;
9436                 case 0x0f:
9437                         idx1 = 2;
9438                         idx = 2;        /* Line In */
9439                         break;
9440                 case 0x0d:
9441                         idx1 = 0;
9442                         idx = 1;        /* Mic In */
9443                         break;
9444                 case 0x10:
9445                         idx1 = 3;
9446                         idx = 1;        /* Mic In */
9447                         break;
9448                 case 0x11:
9449                         idx1 = 4;
9450                         idx = 0;        /* CD */
9451                         break;
9452                 default:
9453                         continue;
9454                 }
9455
9456                 err = new_analog_input(spec, cfg->input_pins[i],
9457                                        auto_pin_cfg_labels[i], idx, 0x15);
9458                 if (err < 0)
9459                         return err;
9460
9461                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9462                 imux->items[imux->num_items].index = idx1;
9463                 imux->num_items++;
9464         }
9465         return 0;
9466 }
9467
9468 static struct snd_kcontrol_new alc861_capture_mixer[] = {
9469         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9470         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9471
9472         {
9473                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9474                 /* The multiple "Capture Source" controls confuse alsamixer
9475                  * So call somewhat different..
9476                  *FIXME: the controls appear in the "playback" view!
9477                  */
9478                 /* .name = "Capture Source", */
9479                 .name = "Input Source",
9480                 .count = 1,
9481                 .info = alc_mux_enum_info,
9482                 .get = alc_mux_enum_get,
9483                 .put = alc_mux_enum_put,
9484         },
9485         { } /* end */
9486 };
9487
9488 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9489                                               hda_nid_t nid,
9490                                               int pin_type, int dac_idx)
9491 {
9492         /* set as output */
9493
9494         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9495                             pin_type);
9496         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9497                             AMP_OUT_UNMUTE);
9498
9499 }
9500
9501 static void alc861_auto_init_multi_out(struct hda_codec *codec)
9502 {
9503         struct alc_spec *spec = codec->spec;
9504         int i;
9505
9506         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9507         for (i = 0; i < spec->autocfg.line_outs; i++) {
9508                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9509                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9510                 if (nid)
9511                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9512                                                           spec->multiout.dac_nids[i]);
9513         }
9514 }
9515
9516 static void alc861_auto_init_hp_out(struct hda_codec *codec)
9517 {
9518         struct alc_spec *spec = codec->spec;
9519         hda_nid_t pin;
9520
9521         pin = spec->autocfg.hp_pins[0];
9522         if (pin) /* connect to front */
9523                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9524                                                   spec->multiout.dac_nids[0]);
9525 }
9526
9527 static void alc861_auto_init_analog_input(struct hda_codec *codec)
9528 {
9529         struct alc_spec *spec = codec->spec;
9530         int i;
9531
9532         for (i = 0; i < AUTO_PIN_LAST; i++) {
9533                 hda_nid_t nid = spec->autocfg.input_pins[i];
9534                 if (nid >= 0x0c && nid <= 0x11) {
9535                         snd_hda_codec_write(codec, nid, 0,
9536                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
9537                                             i <= AUTO_PIN_FRONT_MIC ?
9538                                             PIN_VREF80 : PIN_IN);
9539                 }
9540         }
9541 }
9542
9543 /* parse the BIOS configuration and set up the alc_spec */
9544 /* return 1 if successful, 0 if the proper config is not found,
9545  * or a negative error code
9546  */
9547 static int alc861_parse_auto_config(struct hda_codec *codec)
9548 {
9549         struct alc_spec *spec = codec->spec;
9550         int err;
9551         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9552
9553         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9554                                            alc861_ignore);
9555         if (err < 0)
9556                 return err;
9557         if (!spec->autocfg.line_outs)
9558                 return 0; /* can't find valid BIOS pin config */
9559
9560         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9561         if (err < 0)
9562                 return err;
9563         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9564         if (err < 0)
9565                 return err;
9566         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9567         if (err < 0)
9568                 return err;
9569         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9570         if (err < 0)
9571                 return err;
9572
9573         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9574
9575         if (spec->autocfg.dig_out_pin)
9576                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9577
9578         if (spec->kctl_alloc)
9579                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9580
9581         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9582
9583         spec->num_mux_defs = 1;
9584         spec->input_mux = &spec->private_imux;
9585
9586         spec->adc_nids = alc861_adc_nids;
9587         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9588         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9589         spec->num_mixers++;
9590
9591         return 1;
9592 }
9593
9594 /* additional initialization for auto-configuration model */
9595 static void alc861_auto_init(struct hda_codec *codec)
9596 {
9597         alc861_auto_init_multi_out(codec);
9598         alc861_auto_init_hp_out(codec);
9599         alc861_auto_init_analog_input(codec);
9600 }
9601
9602
9603 /*
9604  * configuration and preset
9605  */
9606 static const char *alc861_models[ALC861_MODEL_LAST] = {
9607         [ALC861_3ST]            = "3stack",
9608         [ALC660_3ST]            = "3stack-660",
9609         [ALC861_3ST_DIG]        = "3stack-dig",
9610         [ALC861_6ST_DIG]        = "6stack-dig",
9611         [ALC861_UNIWILL_M31]    = "uniwill-m31",
9612         [ALC861_TOSHIBA]        = "toshiba",
9613         [ALC861_ASUS]           = "asus",
9614         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
9615         [ALC861_AUTO]           = "auto",
9616 };
9617
9618 static struct snd_pci_quirk alc861_cfg_tbl[] = {
9619         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9620         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9621         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9622         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9623         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9624         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9625         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9626         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9627         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9628          *        Any other models that need this preset?
9629          */
9630         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9631         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9632         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9633         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9634         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9635         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9636         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9637         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9638         {}
9639 };
9640
9641 static struct alc_config_preset alc861_presets[] = {
9642         [ALC861_3ST] = {
9643                 .mixers = { alc861_3ST_mixer },
9644                 .init_verbs = { alc861_threestack_init_verbs },
9645                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9646                 .dac_nids = alc861_dac_nids,
9647                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9648                 .channel_mode = alc861_threestack_modes,
9649                 .need_dac_fix = 1,
9650                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9651                 .adc_nids = alc861_adc_nids,
9652                 .input_mux = &alc861_capture_source,
9653         },
9654         [ALC861_3ST_DIG] = {
9655                 .mixers = { alc861_base_mixer },
9656                 .init_verbs = { alc861_threestack_init_verbs },
9657                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9658                 .dac_nids = alc861_dac_nids,
9659                 .dig_out_nid = ALC861_DIGOUT_NID,
9660                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9661                 .channel_mode = alc861_threestack_modes,
9662                 .need_dac_fix = 1,
9663                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9664                 .adc_nids = alc861_adc_nids,
9665                 .input_mux = &alc861_capture_source,
9666         },
9667         [ALC861_6ST_DIG] = {
9668                 .mixers = { alc861_base_mixer },
9669                 .init_verbs = { alc861_base_init_verbs },
9670                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9671                 .dac_nids = alc861_dac_nids,
9672                 .dig_out_nid = ALC861_DIGOUT_NID,
9673                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9674                 .channel_mode = alc861_8ch_modes,
9675                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9676                 .adc_nids = alc861_adc_nids,
9677                 .input_mux = &alc861_capture_source,
9678         },
9679         [ALC660_3ST] = {
9680                 .mixers = { alc861_3ST_mixer },
9681                 .init_verbs = { alc861_threestack_init_verbs },
9682                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
9683                 .dac_nids = alc660_dac_nids,
9684                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9685                 .channel_mode = alc861_threestack_modes,
9686                 .need_dac_fix = 1,
9687                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9688                 .adc_nids = alc861_adc_nids,
9689                 .input_mux = &alc861_capture_source,
9690         },
9691         [ALC861_UNIWILL_M31] = {
9692                 .mixers = { alc861_uniwill_m31_mixer },
9693                 .init_verbs = { alc861_uniwill_m31_init_verbs },
9694                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9695                 .dac_nids = alc861_dac_nids,
9696                 .dig_out_nid = ALC861_DIGOUT_NID,
9697                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9698                 .channel_mode = alc861_uniwill_m31_modes,
9699                 .need_dac_fix = 1,
9700                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9701                 .adc_nids = alc861_adc_nids,
9702                 .input_mux = &alc861_capture_source,
9703         },
9704         [ALC861_TOSHIBA] = {
9705                 .mixers = { alc861_toshiba_mixer },
9706                 .init_verbs = { alc861_base_init_verbs,
9707                                 alc861_toshiba_init_verbs },
9708                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9709                 .dac_nids = alc861_dac_nids,
9710                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9711                 .channel_mode = alc883_3ST_2ch_modes,
9712                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9713                 .adc_nids = alc861_adc_nids,
9714                 .input_mux = &alc861_capture_source,
9715                 .unsol_event = alc861_toshiba_unsol_event,
9716                 .init_hook = alc861_toshiba_automute,
9717         },
9718         [ALC861_ASUS] = {
9719                 .mixers = { alc861_asus_mixer },
9720                 .init_verbs = { alc861_asus_init_verbs },
9721                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9722                 .dac_nids = alc861_dac_nids,
9723                 .dig_out_nid = ALC861_DIGOUT_NID,
9724                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9725                 .channel_mode = alc861_asus_modes,
9726                 .need_dac_fix = 1,
9727                 .hp_nid = 0x06,
9728                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9729                 .adc_nids = alc861_adc_nids,
9730                 .input_mux = &alc861_capture_source,
9731         },
9732         [ALC861_ASUS_LAPTOP] = {
9733                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9734                 .init_verbs = { alc861_asus_init_verbs,
9735                                 alc861_asus_laptop_init_verbs },
9736                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9737                 .dac_nids = alc861_dac_nids,
9738                 .dig_out_nid = ALC861_DIGOUT_NID,
9739                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9740                 .channel_mode = alc883_3ST_2ch_modes,
9741                 .need_dac_fix = 1,
9742                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9743                 .adc_nids = alc861_adc_nids,
9744                 .input_mux = &alc861_capture_source,
9745         },
9746 };
9747
9748
9749 static int patch_alc861(struct hda_codec *codec)
9750 {
9751         struct alc_spec *spec;
9752         int board_config;
9753         int err;
9754
9755         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9756         if (spec == NULL)
9757                 return -ENOMEM;
9758
9759         codec->spec = spec;
9760
9761         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9762                                                   alc861_models,
9763                                                   alc861_cfg_tbl);
9764
9765         if (board_config < 0) {
9766                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9767                        "trying auto-probe from BIOS...\n");
9768                 board_config = ALC861_AUTO;
9769         }
9770
9771         if (board_config == ALC861_AUTO) {
9772                 /* automatic parse from the BIOS config */
9773                 err = alc861_parse_auto_config(codec);
9774                 if (err < 0) {
9775                         alc_free(codec);
9776                         return err;
9777                 } else if (!err) {
9778                         printk(KERN_INFO
9779                                "hda_codec: Cannot set up configuration "
9780                                "from BIOS.  Using base mode...\n");
9781                    board_config = ALC861_3ST_DIG;
9782                 }
9783         }
9784
9785         if (board_config != ALC861_AUTO)
9786                 setup_preset(spec, &alc861_presets[board_config]);
9787
9788         spec->stream_name_analog = "ALC861 Analog";
9789         spec->stream_analog_playback = &alc861_pcm_analog_playback;
9790         spec->stream_analog_capture = &alc861_pcm_analog_capture;
9791
9792         spec->stream_name_digital = "ALC861 Digital";
9793         spec->stream_digital_playback = &alc861_pcm_digital_playback;
9794         spec->stream_digital_capture = &alc861_pcm_digital_capture;
9795
9796         codec->patch_ops = alc_patch_ops;
9797         if (board_config == ALC861_AUTO)
9798                 spec->init_hook = alc861_auto_init;
9799                 
9800         return 0;
9801 }
9802
9803 /*
9804  * ALC861-VD support
9805  *
9806  * Based on ALC882
9807  *
9808  * In addition, an independent DAC
9809  */
9810 #define ALC861VD_DIGOUT_NID     0x06
9811
9812 static hda_nid_t alc861vd_dac_nids[4] = {
9813         /* front, surr, clfe, side surr */
9814         0x02, 0x03, 0x04, 0x05
9815 };
9816
9817 /* dac_nids for ALC660vd are in a different order - according to
9818  * Realtek's driver.
9819  * This should probably tesult in a different mixer for 6stack models
9820  * of ALC660vd codecs, but for now there is only 3stack mixer
9821  * - and it is the same as in 861vd.
9822  * adc_nids in ALC660vd are (is) the same as in 861vd
9823  */
9824 static hda_nid_t alc660vd_dac_nids[3] = {
9825         /* front, rear, clfe, rear_surr */
9826         0x02, 0x04, 0x03
9827 };
9828
9829 static hda_nid_t alc861vd_adc_nids[1] = {
9830         /* ADC0 */
9831         0x09,
9832 };
9833
9834 /* input MUX */
9835 /* FIXME: should be a matrix-type input source selection */
9836 static struct hda_input_mux alc861vd_capture_source = {
9837         .num_items = 4,
9838         .items = {
9839                 { "Mic", 0x0 },
9840                 { "Front Mic", 0x1 },
9841                 { "Line", 0x2 },
9842                 { "CD", 0x4 },
9843         },
9844 };
9845
9846 static struct hda_input_mux alc861vd_dallas_capture_source = {
9847         .num_items = 3,
9848         .items = {
9849                 { "Front Mic", 0x0 },
9850                 { "ATAPI Mic", 0x1 },
9851                 { "Line In", 0x5 },
9852         },
9853 };
9854
9855 #define alc861vd_mux_enum_info alc_mux_enum_info
9856 #define alc861vd_mux_enum_get alc_mux_enum_get
9857
9858 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9859                                 struct snd_ctl_elem_value *ucontrol)
9860 {
9861         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9862         struct alc_spec *spec = codec->spec;
9863         const struct hda_input_mux *imux = spec->input_mux;
9864         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9865         static hda_nid_t capture_mixers[1] = { 0x22 };
9866         hda_nid_t nid = capture_mixers[adc_idx];
9867         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9868         unsigned int i, idx;
9869
9870         idx = ucontrol->value.enumerated.item[0];
9871         if (idx >= imux->num_items)
9872                 idx = imux->num_items - 1;
9873         if (*cur_val == idx && !codec->in_resume)
9874                 return 0;
9875         for (i = 0; i < imux->num_items; i++) {
9876                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
9877                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9878                                     v | (imux->items[i].index << 8));
9879         }
9880         *cur_val = idx;
9881         return 1;
9882 }
9883
9884 /*
9885  * 2ch mode
9886  */
9887 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9888         { 2, NULL }
9889 };
9890
9891 /*
9892  * 6ch mode
9893  */
9894 static struct hda_verb alc861vd_6stack_ch6_init[] = {
9895         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9896         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9897         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9898         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9899         { } /* end */
9900 };
9901
9902 /*
9903  * 8ch mode
9904  */
9905 static struct hda_verb alc861vd_6stack_ch8_init[] = {
9906         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9907         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9908         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9909         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9910         { } /* end */
9911 };
9912
9913 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
9914         { 6, alc861vd_6stack_ch6_init },
9915         { 8, alc861vd_6stack_ch8_init },
9916 };
9917
9918 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
9919         {
9920                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9921                 .name = "Channel Mode",
9922                 .info = alc_ch_mode_info,
9923                 .get = alc_ch_mode_get,
9924                 .put = alc_ch_mode_put,
9925         },
9926         { } /* end */
9927 };
9928
9929 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
9930         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9931         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9932
9933         {
9934                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9935                 /* The multiple "Capture Source" controls confuse alsamixer
9936                  * So call somewhat different..
9937                  *FIXME: the controls appear in the "playback" view!
9938                  */
9939                 /* .name = "Capture Source", */
9940                 .name = "Input Source",
9941                 .count = 1,
9942                 .info = alc861vd_mux_enum_info,
9943                 .get = alc861vd_mux_enum_get,
9944                 .put = alc861vd_mux_enum_put,
9945         },
9946         { } /* end */
9947 };
9948
9949 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9950  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9951  */
9952 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
9953         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9954         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9955
9956         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9957         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9958
9959         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
9960                                 HDA_OUTPUT),
9961         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
9962                                 HDA_OUTPUT),
9963         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9964         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9965
9966         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
9967         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9968
9969         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9970
9971         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9972         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9973         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9974
9975         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9976         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9977         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9978
9979         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9980         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9981
9982         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9983         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9984
9985         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9986         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9987
9988         { } /* end */
9989 };
9990
9991 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
9992         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9993         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9994
9995         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9996
9997         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9998         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9999         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10000
10001         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10002         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10003         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10004
10005         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10006         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10007
10008         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10009         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10010
10011         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10012         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10013
10014         { } /* end */
10015 };
10016
10017 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10018         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10019         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10020         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10021
10022         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10023
10024         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10025         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10026         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10027
10028         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10029         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10030         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10031
10032         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10033         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10034
10035         { } /* end */
10036 };
10037
10038 /* Pin assignment: Front=0x14, HP = 0x15,
10039  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10040  */
10041 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10042         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10043         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10044         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10045         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10046         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10047         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10048         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10049         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10050         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10051         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10052         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10053         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10054         {
10055                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10056                 /* .name = "Capture Source", */
10057                 .name = "Input Source",
10058                 .count = 1,
10059                 .info = alc882_mux_enum_info,
10060                 .get = alc882_mux_enum_get,
10061                 .put = alc882_mux_enum_put,
10062         },
10063         { } /* end */
10064 };
10065
10066 /*
10067  * generic initialization of ADC, input mixers and output mixers
10068  */
10069 static struct hda_verb alc861vd_volume_init_verbs[] = {
10070         /*
10071          * Unmute ADC0 and set the default input to mic-in
10072          */
10073         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10074         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10075
10076         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10077          * the analog-loopback mixer widget
10078          */
10079         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10080         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10081         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10082         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10083         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10084         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10085
10086         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10087         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10089         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10090         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10091
10092         /*
10093          * Set up output mixers (0x02 - 0x05)
10094          */
10095         /* set vol=0 to output mixers */
10096         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10097         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10098         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10099         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10100
10101         /* set up input amps for analog loopback */
10102         /* Amp Indices: DAC = 0, mixer = 1 */
10103         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10104         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10105         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10106         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10107         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10108         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10109         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10110         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10111
10112         { }
10113 };
10114
10115 /*
10116  * 3-stack pin configuration:
10117  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10118  */
10119 static struct hda_verb alc861vd_3stack_init_verbs[] = {
10120         /*
10121          * Set pin mode and muting
10122          */
10123         /* set front pin widgets 0x14 for output */
10124         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10125         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10126         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10127
10128         /* Mic (rear) pin: input vref at 80% */
10129         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10130         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10131         /* Front Mic pin: input vref at 80% */
10132         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10133         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10134         /* Line In pin: input */
10135         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10136         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10137         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10138         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10139         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10140         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10141         /* CD pin widget for input */
10142         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10143
10144         { }
10145 };
10146
10147 /*
10148  * 6-stack pin configuration:
10149  */
10150 static struct hda_verb alc861vd_6stack_init_verbs[] = {
10151         /*
10152          * Set pin mode and muting
10153          */
10154         /* set front pin widgets 0x14 for output */
10155         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10156         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10157         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10158
10159         /* Rear Pin: output 1 (0x0d) */
10160         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10161         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10162         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10163         /* CLFE Pin: output 2 (0x0e) */
10164         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10165         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10166         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10167         /* Side Pin: output 3 (0x0f) */
10168         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10169         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10170         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10171
10172         /* Mic (rear) pin: input vref at 80% */
10173         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10174         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10175         /* Front Mic pin: input vref at 80% */
10176         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10177         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10178         /* Line In pin: input */
10179         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10180         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10181         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10182         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10183         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10184         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10185         /* CD pin widget for input */
10186         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10187
10188         { }
10189 };
10190
10191 static struct hda_verb alc861vd_eapd_verbs[] = {
10192         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10193         { }
10194 };
10195
10196 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10197         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10198         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10199         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10200         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10201         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
10202         {}
10203 };
10204
10205 /* toggle speaker-output according to the hp-jack state */
10206 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10207 {
10208         unsigned int present;
10209         unsigned char bits;
10210
10211         present = snd_hda_codec_read(codec, 0x1b, 0,
10212                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10213         bits = present ? 0x80 : 0;
10214         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10215                                  0x80, bits);
10216         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10217                                  0x80, bits);
10218 }
10219
10220 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10221 {
10222         unsigned int present;
10223         unsigned char bits;
10224
10225         present = snd_hda_codec_read(codec, 0x18, 0,
10226                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10227         bits = present ? 0x80 : 0;
10228         snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
10229                                  0x80, bits);
10230         snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
10231                                  0x80, bits);
10232 }
10233
10234 static void alc861vd_lenovo_automute(struct hda_codec *codec)
10235 {
10236         alc861vd_lenovo_hp_automute(codec);
10237         alc861vd_lenovo_mic_automute(codec);
10238 }
10239
10240 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10241                                         unsigned int res)
10242 {
10243         switch (res >> 26) {
10244         case ALC880_HP_EVENT:
10245                 alc861vd_lenovo_hp_automute(codec);
10246                 break;
10247         case ALC880_MIC_EVENT:
10248                 alc861vd_lenovo_mic_automute(codec);
10249                 break;
10250         }
10251 }
10252
10253 static struct hda_verb alc861vd_dallas_verbs[] = {
10254         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10255         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10256         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10257         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10258
10259         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10260         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10261         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10262         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10263         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10264         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10265         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10266         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10267         
10268         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10269         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10270         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10271         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10272         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10273         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10274         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10275         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10276
10277         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10278         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10279         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10280         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10281         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10282         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10283         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10284         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10285
10286         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10287         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10288         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10289         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10290
10291         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10292         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
10293         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10294
10295         { } /* end */
10296 };
10297
10298 /* toggle speaker-output according to the hp-jack state */
10299 static void alc861vd_dallas_automute(struct hda_codec *codec)
10300 {
10301         unsigned int present;
10302
10303         present = snd_hda_codec_read(codec, 0x15, 0,
10304                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10305         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10306                                  0x80, present ? 0x80 : 0);
10307         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10308                                  0x80, present ? 0x80 : 0);
10309 }
10310
10311 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10312 {
10313         if ((res >> 26) == ALC880_HP_EVENT)
10314                 alc861vd_dallas_automute(codec);
10315 }
10316
10317 /* pcm configuration: identiacal with ALC880 */
10318 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
10319 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
10320 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
10321 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
10322
10323 /*
10324  * configuration and preset
10325  */
10326 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10327         [ALC660VD_3ST]          = "3stack-660",
10328         [ALC660VD_3ST_DIG]= "3stack-660-digout",
10329         [ALC861VD_3ST]          = "3stack",
10330         [ALC861VD_3ST_DIG]      = "3stack-digout",
10331         [ALC861VD_6ST_DIG]      = "6stack-digout",
10332         [ALC861VD_LENOVO]       = "lenovo",
10333         [ALC861VD_DALLAS]       = "dallas",
10334         [ALC861VD_AUTO]         = "auto",
10335 };
10336
10337 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10338         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10339         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10340         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10341         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10342         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10343
10344         SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10345         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10346         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10347         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10348         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10349         {}
10350 };
10351
10352 static struct alc_config_preset alc861vd_presets[] = {
10353         [ALC660VD_3ST] = {
10354                 .mixers = { alc861vd_3st_mixer },
10355                 .init_verbs = { alc861vd_volume_init_verbs,
10356                                  alc861vd_3stack_init_verbs },
10357                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10358                 .dac_nids = alc660vd_dac_nids,
10359                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10360                 .adc_nids = alc861vd_adc_nids,
10361                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10362                 .channel_mode = alc861vd_3stack_2ch_modes,
10363                 .input_mux = &alc861vd_capture_source,
10364         },
10365         [ALC660VD_3ST_DIG] = {
10366                 .mixers = { alc861vd_3st_mixer },
10367                 .init_verbs = { alc861vd_volume_init_verbs,
10368                                  alc861vd_3stack_init_verbs },
10369                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10370                 .dac_nids = alc660vd_dac_nids,
10371                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10372                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10373                 .adc_nids = alc861vd_adc_nids,
10374                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10375                 .channel_mode = alc861vd_3stack_2ch_modes,
10376                 .input_mux = &alc861vd_capture_source,
10377         },
10378         [ALC861VD_3ST] = {
10379                 .mixers = { alc861vd_3st_mixer },
10380                 .init_verbs = { alc861vd_volume_init_verbs,
10381                                  alc861vd_3stack_init_verbs },
10382                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10383                 .dac_nids = alc861vd_dac_nids,
10384                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10385                 .channel_mode = alc861vd_3stack_2ch_modes,
10386                 .input_mux = &alc861vd_capture_source,
10387         },
10388         [ALC861VD_3ST_DIG] = {
10389                 .mixers = { alc861vd_3st_mixer },
10390                 .init_verbs = { alc861vd_volume_init_verbs,
10391                                  alc861vd_3stack_init_verbs },
10392                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10393                 .dac_nids = alc861vd_dac_nids,
10394                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10395                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10396                 .channel_mode = alc861vd_3stack_2ch_modes,
10397                 .input_mux = &alc861vd_capture_source,
10398         },
10399         [ALC861VD_6ST_DIG] = {
10400                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10401                 .init_verbs = { alc861vd_volume_init_verbs,
10402                                 alc861vd_6stack_init_verbs },
10403                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10404                 .dac_nids = alc861vd_dac_nids,
10405                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10406                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10407                 .channel_mode = alc861vd_6stack_modes,
10408                 .input_mux = &alc861vd_capture_source,
10409         },
10410         [ALC861VD_LENOVO] = {
10411                 .mixers = { alc861vd_lenovo_mixer },
10412                 .init_verbs = { alc861vd_volume_init_verbs,
10413                                 alc861vd_3stack_init_verbs,
10414                                 alc861vd_eapd_verbs,
10415                                 alc861vd_lenovo_unsol_verbs },
10416                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10417                 .dac_nids = alc660vd_dac_nids,
10418                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10419                 .adc_nids = alc861vd_adc_nids,
10420                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10421                 .channel_mode = alc861vd_3stack_2ch_modes,
10422                 .input_mux = &alc861vd_capture_source,
10423                 .unsol_event = alc861vd_lenovo_unsol_event,
10424                 .init_hook = alc861vd_lenovo_automute,
10425         },
10426         [ALC861VD_DALLAS] = {
10427                 .mixers = { alc861vd_dallas_mixer },
10428                 .init_verbs = { alc861vd_dallas_verbs },
10429                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10430                 .dac_nids = alc861vd_dac_nids,
10431                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10432                 .adc_nids = alc861vd_adc_nids,
10433                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10434                 .channel_mode = alc861vd_3stack_2ch_modes,
10435                 .input_mux = &alc861vd_dallas_capture_source,
10436                 .unsol_event = alc861vd_dallas_unsol_event,
10437                 .init_hook = alc861vd_dallas_automute,
10438         },      
10439 };
10440
10441 /*
10442  * BIOS auto configuration
10443  */
10444 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10445                                 hda_nid_t nid, int pin_type, int dac_idx)
10446 {
10447         /* set as output */
10448         snd_hda_codec_write(codec, nid, 0,
10449                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10450         snd_hda_codec_write(codec, nid, 0,
10451                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10452 }
10453
10454 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10455 {
10456         struct alc_spec *spec = codec->spec;
10457         int i;
10458
10459         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10460         for (i = 0; i <= HDA_SIDE; i++) {
10461                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10462                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10463                 if (nid)
10464                         alc861vd_auto_set_output_and_unmute(codec, nid,
10465                                                             pin_type, i);
10466         }
10467 }
10468
10469
10470 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10471 {
10472         struct alc_spec *spec = codec->spec;
10473         hda_nid_t pin;
10474
10475         pin = spec->autocfg.hp_pins[0];
10476         if (pin) /* connect to front and  use dac 0 */
10477                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10478 }
10479
10480 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
10481 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
10482
10483 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10484 {
10485         struct alc_spec *spec = codec->spec;
10486         int i;
10487
10488         for (i = 0; i < AUTO_PIN_LAST; i++) {
10489                 hda_nid_t nid = spec->autocfg.input_pins[i];
10490                 if (alc861vd_is_input_pin(nid)) {
10491                         snd_hda_codec_write(codec, nid, 0,
10492                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
10493                                         i <= AUTO_PIN_FRONT_MIC ?
10494                                                         PIN_VREF80 : PIN_IN);
10495                         if (nid != ALC861VD_PIN_CD_NID)
10496                                 snd_hda_codec_write(codec, nid, 0,
10497                                                 AC_VERB_SET_AMP_GAIN_MUTE,
10498                                                 AMP_OUT_MUTE);
10499                 }
10500         }
10501 }
10502
10503 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
10504 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
10505
10506 /* add playback controls from the parsed DAC table */
10507 /* Based on ALC880 version. But ALC861VD has separate,
10508  * different NIDs for mute/unmute switch and volume control */
10509 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10510                                              const struct auto_pin_cfg *cfg)
10511 {
10512         char name[32];
10513         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10514         hda_nid_t nid_v, nid_s;
10515         int i, err;
10516
10517         for (i = 0; i < cfg->line_outs; i++) {
10518                 if (!spec->multiout.dac_nids[i])
10519                         continue;
10520                 nid_v = alc861vd_idx_to_mixer_vol(
10521                                 alc880_dac_to_idx(
10522                                         spec->multiout.dac_nids[i]));
10523                 nid_s = alc861vd_idx_to_mixer_switch(
10524                                 alc880_dac_to_idx(
10525                                         spec->multiout.dac_nids[i]));
10526
10527                 if (i == 2) {
10528                         /* Center/LFE */
10529                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10530                                           "Center Playback Volume",
10531                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10532                                                               HDA_OUTPUT));
10533                         if (err < 0)
10534                                 return err;
10535                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10536                                           "LFE Playback Volume",
10537                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10538                                                               HDA_OUTPUT));
10539                         if (err < 0)
10540                                 return err;
10541                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10542                                           "Center Playback Switch",
10543                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10544                                                               HDA_INPUT));
10545                         if (err < 0)
10546                                 return err;
10547                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10548                                           "LFE Playback Switch",
10549                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10550                                                               HDA_INPUT));
10551                         if (err < 0)
10552                                 return err;
10553                 } else {
10554                         sprintf(name, "%s Playback Volume", chname[i]);
10555                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10556                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10557                                                               HDA_OUTPUT));
10558                         if (err < 0)
10559                                 return err;
10560                         sprintf(name, "%s Playback Switch", chname[i]);
10561                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10562                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10563                                                               HDA_INPUT));
10564                         if (err < 0)
10565                                 return err;
10566                 }
10567         }
10568         return 0;
10569 }
10570
10571 /* add playback controls for speaker and HP outputs */
10572 /* Based on ALC880 version. But ALC861VD has separate,
10573  * different NIDs for mute/unmute switch and volume control */
10574 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10575                                         hda_nid_t pin, const char *pfx)
10576 {
10577         hda_nid_t nid_v, nid_s;
10578         int err;
10579         char name[32];
10580
10581         if (!pin)
10582                 return 0;
10583
10584         if (alc880_is_fixed_pin(pin)) {
10585                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10586                 /* specify the DAC as the extra output */
10587                 if (!spec->multiout.hp_nid)
10588                         spec->multiout.hp_nid = nid_v;
10589                 else
10590                         spec->multiout.extra_out_nid[0] = nid_v;
10591                 /* control HP volume/switch on the output mixer amp */
10592                 nid_v = alc861vd_idx_to_mixer_vol(
10593                                 alc880_fixed_pin_idx(pin));
10594                 nid_s = alc861vd_idx_to_mixer_switch(
10595                                 alc880_fixed_pin_idx(pin));
10596
10597                 sprintf(name, "%s Playback Volume", pfx);
10598                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10599                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10600                 if (err < 0)
10601                         return err;
10602                 sprintf(name, "%s Playback Switch", pfx);
10603                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10604                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10605                 if (err < 0)
10606                         return err;
10607         } else if (alc880_is_multi_pin(pin)) {
10608                 /* set manual connection */
10609                 /* we have only a switch on HP-out PIN */
10610                 sprintf(name, "%s Playback Switch", pfx);
10611                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10612                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10613                 if (err < 0)
10614                         return err;
10615         }
10616         return 0;
10617 }
10618
10619 /* parse the BIOS configuration and set up the alc_spec
10620  * return 1 if successful, 0 if the proper config is not found,
10621  * or a negative error code
10622  * Based on ALC880 version - had to change it to override
10623  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10624 static int alc861vd_parse_auto_config(struct hda_codec *codec)
10625 {
10626         struct alc_spec *spec = codec->spec;
10627         int err;
10628         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10629
10630         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10631                                            alc861vd_ignore);
10632         if (err < 0)
10633                 return err;
10634         if (!spec->autocfg.line_outs)
10635                 return 0; /* can't find valid BIOS pin config */
10636
10637         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10638         if (err < 0)
10639                 return err;
10640         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10641         if (err < 0)
10642                 return err;
10643         err = alc861vd_auto_create_extra_out(spec,
10644                                              spec->autocfg.speaker_pins[0],
10645                                              "Speaker");
10646         if (err < 0)
10647                 return err;
10648         err = alc861vd_auto_create_extra_out(spec,
10649                                              spec->autocfg.hp_pins[0],
10650                                              "Headphone");
10651         if (err < 0)
10652                 return err;
10653         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10654         if (err < 0)
10655                 return err;
10656
10657         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10658
10659         if (spec->autocfg.dig_out_pin)
10660                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10661
10662         if (spec->kctl_alloc)
10663                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10664
10665         spec->init_verbs[spec->num_init_verbs++]
10666                 = alc861vd_volume_init_verbs;
10667
10668         spec->num_mux_defs = 1;
10669         spec->input_mux = &spec->private_imux;
10670
10671         return 1;
10672 }
10673
10674 /* additional initialization for auto-configuration model */
10675 static void alc861vd_auto_init(struct hda_codec *codec)
10676 {
10677         alc861vd_auto_init_multi_out(codec);
10678         alc861vd_auto_init_hp_out(codec);
10679         alc861vd_auto_init_analog_input(codec);
10680 }
10681
10682 static int patch_alc861vd(struct hda_codec *codec)
10683 {
10684         struct alc_spec *spec;
10685         int err, board_config;
10686
10687         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10688         if (spec == NULL)
10689                 return -ENOMEM;
10690
10691         codec->spec = spec;
10692
10693         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10694                                                   alc861vd_models,
10695                                                   alc861vd_cfg_tbl);
10696
10697         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10698                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10699                         "ALC861VD, trying auto-probe from BIOS...\n");
10700                 board_config = ALC861VD_AUTO;
10701         }
10702
10703         if (board_config == ALC861VD_AUTO) {
10704                 /* automatic parse from the BIOS config */
10705                 err = alc861vd_parse_auto_config(codec);
10706                 if (err < 0) {
10707                         alc_free(codec);
10708                         return err;
10709                 } else if (!err) {
10710                         printk(KERN_INFO
10711                                "hda_codec: Cannot set up configuration "
10712                                "from BIOS.  Using base mode...\n");
10713                         board_config = ALC861VD_3ST;
10714                 }
10715         }
10716
10717         if (board_config != ALC861VD_AUTO)
10718                 setup_preset(spec, &alc861vd_presets[board_config]);
10719
10720         spec->stream_name_analog = "ALC861VD Analog";
10721         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10722         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10723
10724         spec->stream_name_digital = "ALC861VD Digital";
10725         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10726         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10727
10728         spec->adc_nids = alc861vd_adc_nids;
10729         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10730
10731         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10732         spec->num_mixers++;
10733
10734         codec->patch_ops = alc_patch_ops;
10735
10736         if (board_config == ALC861VD_AUTO)
10737                 spec->init_hook = alc861vd_auto_init;
10738
10739         return 0;
10740 }
10741
10742 /*
10743  * ALC662 support
10744  *
10745  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10746  * configuration.  Each pin widget can choose any input DACs and a mixer.
10747  * Each ADC is connected from a mixer of all inputs.  This makes possible
10748  * 6-channel independent captures.
10749  *
10750  * In addition, an independent DAC for the multi-playback (not used in this
10751  * driver yet).
10752  */
10753 #define ALC662_DIGOUT_NID       0x06
10754 #define ALC662_DIGIN_NID        0x0a
10755
10756 static hda_nid_t alc662_dac_nids[4] = {
10757         /* front, rear, clfe, rear_surr */
10758         0x02, 0x03, 0x04
10759 };
10760
10761 static hda_nid_t alc662_adc_nids[1] = {
10762         /* ADC1-2 */
10763         0x09,
10764 };
10765 /* input MUX */
10766 /* FIXME: should be a matrix-type input source selection */
10767
10768 static struct hda_input_mux alc662_capture_source = {
10769         .num_items = 4,
10770         .items = {
10771                 { "Mic", 0x0 },
10772                 { "Front Mic", 0x1 },
10773                 { "Line", 0x2 },
10774                 { "CD", 0x4 },
10775         },
10776 };
10777
10778 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10779         .num_items = 2,
10780         .items = {
10781                 { "Mic", 0x1 },
10782                 { "Line", 0x2 },
10783         },
10784 };
10785 #define alc662_mux_enum_info alc_mux_enum_info
10786 #define alc662_mux_enum_get alc_mux_enum_get
10787
10788 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10789                                struct snd_ctl_elem_value *ucontrol)
10790 {
10791         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10792         struct alc_spec *spec = codec->spec;
10793         const struct hda_input_mux *imux = spec->input_mux;
10794         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10795         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
10796         hda_nid_t nid = capture_mixers[adc_idx];
10797         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10798         unsigned int i, idx;
10799
10800         idx = ucontrol->value.enumerated.item[0];
10801         if (idx >= imux->num_items)
10802                 idx = imux->num_items - 1;
10803         if (*cur_val == idx && !codec->in_resume)
10804                 return 0;
10805         for (i = 0; i < imux->num_items; i++) {
10806                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
10807                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10808                                     v | (imux->items[i].index << 8));
10809         }
10810         *cur_val = idx;
10811         return 1;
10812 }
10813 /*
10814  * 2ch mode
10815  */
10816 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10817         { 2, NULL }
10818 };
10819
10820 /*
10821  * 2ch mode
10822  */
10823 static struct hda_verb alc662_3ST_ch2_init[] = {
10824         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10825         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10826         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10827         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10828         { } /* end */
10829 };
10830
10831 /*
10832  * 6ch mode
10833  */
10834 static struct hda_verb alc662_3ST_ch6_init[] = {
10835         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10836         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10837         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10838         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10839         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10840         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10841         { } /* end */
10842 };
10843
10844 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10845         { 2, alc662_3ST_ch2_init },
10846         { 6, alc662_3ST_ch6_init },
10847 };
10848
10849 /*
10850  * 2ch mode
10851  */
10852 static struct hda_verb alc662_sixstack_ch6_init[] = {
10853         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10854         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10855         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10856         { } /* end */
10857 };
10858
10859 /*
10860  * 6ch mode
10861  */
10862 static struct hda_verb alc662_sixstack_ch8_init[] = {
10863         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10864         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10865         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10866         { } /* end */
10867 };
10868
10869 static struct hda_channel_mode alc662_5stack_modes[2] = {
10870         { 2, alc662_sixstack_ch6_init },
10871         { 6, alc662_sixstack_ch8_init },
10872 };
10873
10874 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10875  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10876  */
10877
10878 static struct snd_kcontrol_new alc662_base_mixer[] = {
10879         /* output mixer control */
10880         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10881         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
10882         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10883         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10884         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10885         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10886         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10887         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10888         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10889
10890         /*Input mixer control */
10891         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
10892         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
10893         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
10894         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
10895         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
10896         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
10897         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
10898         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
10899
10900         /* Capture mixer control */
10901         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10902         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10903         {
10904                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10905                 .name = "Capture Source",
10906                 .count = 1,
10907                 .info = alc_mux_enum_info,
10908                 .get = alc_mux_enum_get,
10909                 .put = alc_mux_enum_put,
10910         },
10911         { } /* end */
10912 };
10913
10914 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
10915         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10916         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10917         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10918         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10919         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10920         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10921         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10922         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10923         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10924         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10925         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10926         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10927         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10928         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10929         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10930         {
10931                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10932                 /* .name = "Capture Source", */
10933                 .name = "Input Source",
10934                 .count = 1,
10935                 .info = alc662_mux_enum_info,
10936                 .get = alc662_mux_enum_get,
10937                 .put = alc662_mux_enum_put,
10938         },
10939         { } /* end */
10940 };
10941
10942 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
10943         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10944         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10945         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10946         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
10947         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10948         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10949         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10950         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10951         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10952         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10953         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10954         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10955         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10956         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10957         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10958         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10959         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10960         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10961         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10962         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10963         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10964         {
10965                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10966                 /* .name = "Capture Source", */
10967                 .name = "Input Source",
10968                 .count = 1,
10969                 .info = alc662_mux_enum_info,
10970                 .get = alc662_mux_enum_get,
10971                 .put = alc662_mux_enum_put,
10972         },
10973         { } /* end */
10974 };
10975
10976 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
10977         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10978         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10979         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10980         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
10981         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10982         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10983         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10984         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10985         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10986         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10987         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10988         {
10989                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10990                 /* .name = "Capture Source", */
10991                 .name = "Input Source",
10992                 .count = 1,
10993                 .info = alc662_mux_enum_info,
10994                 .get = alc662_mux_enum_get,
10995                 .put = alc662_mux_enum_put,
10996         },
10997         { } /* end */
10998 };
10999
11000 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11001         {
11002                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11003                 .name = "Channel Mode",
11004                 .info = alc_ch_mode_info,
11005                 .get = alc_ch_mode_get,
11006                 .put = alc_ch_mode_put,
11007         },
11008         { } /* end */
11009 };
11010
11011 static struct hda_verb alc662_init_verbs[] = {
11012         /* ADC: mute amp left and right */
11013         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11014         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11015         /* Front mixer: unmute input/output amp left and right (volume = 0) */
11016
11017         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11018         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11019         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11020         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11021         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11022
11023         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11024         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11025         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11026         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11027         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11028         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11029
11030         /* Front Pin: output 0 (0x0c) */
11031         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11032         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11033
11034         /* Rear Pin: output 1 (0x0d) */
11035         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11036         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11037
11038         /* CLFE Pin: output 2 (0x0e) */
11039         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11040         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11041
11042         /* Mic (rear) pin: input vref at 80% */
11043         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11044         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11045         /* Front Mic pin: input vref at 80% */
11046         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11047         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11048         /* Line In pin: input */
11049         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11050         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11051         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11052         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11053         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11054         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11055         /* CD pin widget for input */
11056         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11057
11058         /* FIXME: use matrix-type input source selection */
11059         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11060         /* Input mixer */
11061         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11062         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11063         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11064         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11065         { }
11066 };
11067
11068 static struct hda_verb alc662_sue_init_verbs[] = {
11069         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11070         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11071         {}
11072 };
11073
11074 /*
11075  * generic initialization of ADC, input mixers and output mixers
11076  */
11077 static struct hda_verb alc662_auto_init_verbs[] = {
11078         /*
11079          * Unmute ADC and set the default input to mic-in
11080          */
11081         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11082         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11083
11084         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11085          * mixer widget
11086          * Note: PASD motherboards uses the Line In 2 as the input for front
11087          * panel mic (mic 2)
11088          */
11089         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11090         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11091         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11092         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11093         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11094         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11095
11096         /*
11097          * Set up output mixers (0x0c - 0x0f)
11098          */
11099         /* set vol=0 to output mixers */
11100         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11101         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11102         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11103
11104         /* set up input amps for analog loopback */
11105         /* Amp Indices: DAC = 0, mixer = 1 */
11106         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11107         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11108         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11109         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11110         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11111         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11112
11113
11114         /* FIXME: use matrix-type input source selection */
11115         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11116         /* Input mixer */
11117         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11118         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11119         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11120         /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
11121         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11122
11123         { }
11124 };
11125
11126 /* capture mixer elements */
11127 static struct snd_kcontrol_new alc662_capture_mixer[] = {
11128         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11129         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11130         {
11131                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11132                 /* The multiple "Capture Source" controls confuse alsamixer
11133                  * So call somewhat different..
11134                  * FIXME: the controls appear in the "playback" view!
11135                  */
11136                 /* .name = "Capture Source", */
11137                 .name = "Input Source",
11138                 .count = 1,
11139                 .info = alc882_mux_enum_info,
11140                 .get = alc882_mux_enum_get,
11141                 .put = alc882_mux_enum_put,
11142         },
11143         { } /* end */
11144 };
11145
11146 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11147 {
11148         unsigned int present;
11149         unsigned char bits;
11150
11151         present = snd_hda_codec_read(codec, 0x14, 0,
11152                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11153         bits = present ? 0x80 : 0;
11154         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11155                                  0x80, bits);
11156         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11157                                  0x80, bits);
11158 }
11159
11160 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11161 {
11162         unsigned int present;
11163         unsigned char bits;
11164
11165         present = snd_hda_codec_read(codec, 0x1b, 0,
11166                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11167         bits = present ? 0x80 : 0;
11168         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11169                                  0x80, bits);
11170         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11171                                  0x80, bits);
11172         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11173                                  0x80, bits);
11174         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11175                                  0x80, bits);
11176 }
11177
11178 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11179                                            unsigned int res)
11180 {
11181         if ((res >> 26) == ALC880_HP_EVENT)
11182                 alc662_lenovo_101e_all_automute(codec);
11183         if ((res >> 26) == ALC880_FRONT_EVENT)
11184                 alc662_lenovo_101e_ispeaker_automute(codec);
11185 }
11186
11187
11188 /* pcm configuration: identiacal with ALC880 */
11189 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
11190 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
11191 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
11192 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
11193
11194 /*
11195  * configuration and preset
11196  */
11197 static const char *alc662_models[ALC662_MODEL_LAST] = {
11198         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
11199         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
11200         [ALC662_3ST_6ch]        = "3stack-6ch",
11201         [ALC662_5ST_DIG]        = "6stack-dig",
11202         [ALC662_LENOVO_101E]    = "lenovo-101e",
11203         [ALC662_AUTO]           = "auto",
11204 };
11205
11206 static struct snd_pci_quirk alc662_cfg_tbl[] = {
11207         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11208         {}
11209 };
11210
11211 static struct alc_config_preset alc662_presets[] = {
11212         [ALC662_3ST_2ch_DIG] = {
11213                 .mixers = { alc662_3ST_2ch_mixer },
11214                 .init_verbs = { alc662_init_verbs },
11215                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11216                 .dac_nids = alc662_dac_nids,
11217                 .dig_out_nid = ALC662_DIGOUT_NID,
11218                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11219                 .adc_nids = alc662_adc_nids,
11220                 .dig_in_nid = ALC662_DIGIN_NID,
11221                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11222                 .channel_mode = alc662_3ST_2ch_modes,
11223                 .input_mux = &alc662_capture_source,
11224         },
11225         [ALC662_3ST_6ch_DIG] = {
11226                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11227                 .init_verbs = { alc662_init_verbs },
11228                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11229                 .dac_nids = alc662_dac_nids,
11230                 .dig_out_nid = ALC662_DIGOUT_NID,
11231                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11232                 .adc_nids = alc662_adc_nids,
11233                 .dig_in_nid = ALC662_DIGIN_NID,
11234                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11235                 .channel_mode = alc662_3ST_6ch_modes,
11236                 .need_dac_fix = 1,
11237                 .input_mux = &alc662_capture_source,
11238         },
11239         [ALC662_3ST_6ch] = {
11240                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11241                 .init_verbs = { alc662_init_verbs },
11242                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11243                 .dac_nids = alc662_dac_nids,
11244                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11245                 .adc_nids = alc662_adc_nids,
11246                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11247                 .channel_mode = alc662_3ST_6ch_modes,
11248                 .need_dac_fix = 1,
11249                 .input_mux = &alc662_capture_source,
11250         },
11251         [ALC662_5ST_DIG] = {
11252                 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
11253                 .init_verbs = { alc662_init_verbs },
11254                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11255                 .dac_nids = alc662_dac_nids,
11256                 .dig_out_nid = ALC662_DIGOUT_NID,
11257                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11258                 .adc_nids = alc662_adc_nids,
11259                 .dig_in_nid = ALC662_DIGIN_NID,
11260                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11261                 .channel_mode = alc662_5stack_modes,
11262                 .input_mux = &alc662_capture_source,
11263         },
11264         [ALC662_LENOVO_101E] = {
11265                 .mixers = { alc662_lenovo_101e_mixer },
11266                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11267                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11268                 .dac_nids = alc662_dac_nids,
11269                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11270                 .adc_nids = alc662_adc_nids,
11271                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11272                 .channel_mode = alc662_3ST_2ch_modes,
11273                 .input_mux = &alc662_lenovo_101e_capture_source,
11274                 .unsol_event = alc662_lenovo_101e_unsol_event,
11275                 .init_hook = alc662_lenovo_101e_all_automute,
11276         },
11277
11278 };
11279
11280
11281 /*
11282  * BIOS auto configuration
11283  */
11284
11285 /* add playback controls from the parsed DAC table */
11286 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11287                                              const struct auto_pin_cfg *cfg)
11288 {
11289         char name[32];
11290         static const char *chname[4] = {
11291                 "Front", "Surround", NULL /*CLFE*/, "Side"
11292         };
11293         hda_nid_t nid;
11294         int i, err;
11295
11296         for (i = 0; i < cfg->line_outs; i++) {
11297                 if (!spec->multiout.dac_nids[i])
11298                         continue;
11299                 nid = alc880_idx_to_mixer(i);
11300                 if (i == 2) {
11301                         /* Center/LFE */
11302                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11303                                           "Center Playback Volume",
11304                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11305                                                               HDA_OUTPUT));
11306                         if (err < 0)
11307                                 return err;
11308                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11309                                           "LFE Playback Volume",
11310                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11311                                                               HDA_OUTPUT));
11312                         if (err < 0)
11313                                 return err;
11314                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11315                                           "Center Playback Switch",
11316                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11317                                                               HDA_INPUT));
11318                         if (err < 0)
11319                                 return err;
11320                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11321                                           "LFE Playback Switch",
11322                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11323                                                               HDA_INPUT));
11324                         if (err < 0)
11325                                 return err;
11326                 } else {
11327                         sprintf(name, "%s Playback Volume", chname[i]);
11328                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11329                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11330                                                               HDA_OUTPUT));
11331                         if (err < 0)
11332                                 return err;
11333                         sprintf(name, "%s Playback Switch", chname[i]);
11334                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11335                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11336                                                               HDA_INPUT));
11337                         if (err < 0)
11338                                 return err;
11339                 }
11340         }
11341         return 0;
11342 }
11343
11344 /* add playback controls for speaker and HP outputs */
11345 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11346                                         const char *pfx)
11347 {
11348         hda_nid_t nid;
11349         int err;
11350         char name[32];
11351
11352         if (!pin)
11353                 return 0;
11354
11355         if (alc880_is_fixed_pin(pin)) {
11356                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11357                 /* printk("DAC nid=%x\n",nid); */
11358                 /* specify the DAC as the extra output */
11359                 if (!spec->multiout.hp_nid)
11360                         spec->multiout.hp_nid = nid;
11361                 else
11362                         spec->multiout.extra_out_nid[0] = nid;
11363                 /* control HP volume/switch on the output mixer amp */
11364                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11365                 sprintf(name, "%s Playback Volume", pfx);
11366                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11367                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11368                 if (err < 0)
11369                         return err;
11370                 sprintf(name, "%s Playback Switch", pfx);
11371                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11372                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11373                 if (err < 0)
11374                         return err;
11375         } else if (alc880_is_multi_pin(pin)) {
11376                 /* set manual connection */
11377                 /* we have only a switch on HP-out PIN */
11378                 sprintf(name, "%s Playback Switch", pfx);
11379                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11380                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11381                 if (err < 0)
11382                         return err;
11383         }
11384         return 0;
11385 }
11386
11387 /* create playback/capture controls for input pins */
11388 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11389                                                 const struct auto_pin_cfg *cfg)
11390 {
11391         struct hda_input_mux *imux = &spec->private_imux;
11392         int i, err, idx;
11393
11394         for (i = 0; i < AUTO_PIN_LAST; i++) {
11395                 if (alc880_is_input_pin(cfg->input_pins[i])) {
11396                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
11397                         err = new_analog_input(spec, cfg->input_pins[i],
11398                                                auto_pin_cfg_labels[i],
11399                                                idx, 0x0b);
11400                         if (err < 0)
11401                                 return err;
11402                         imux->items[imux->num_items].label =
11403                                 auto_pin_cfg_labels[i];
11404                         imux->items[imux->num_items].index =
11405                                 alc880_input_pin_idx(cfg->input_pins[i]);
11406                         imux->num_items++;
11407                 }
11408         }
11409         return 0;
11410 }
11411
11412 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11413                                               hda_nid_t nid, int pin_type,
11414                                               int dac_idx)
11415 {
11416         /* set as output */
11417         snd_hda_codec_write(codec, nid, 0,
11418                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11419         snd_hda_codec_write(codec, nid, 0,
11420                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11421         /* need the manual connection? */
11422         if (alc880_is_multi_pin(nid)) {
11423                 struct alc_spec *spec = codec->spec;
11424                 int idx = alc880_multi_pin_idx(nid);
11425                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11426                                     AC_VERB_SET_CONNECT_SEL,
11427                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11428         }
11429 }
11430
11431 static void alc662_auto_init_multi_out(struct hda_codec *codec)
11432 {
11433         struct alc_spec *spec = codec->spec;
11434         int i;
11435
11436         for (i = 0; i <= HDA_SIDE; i++) {
11437                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11438                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11439                 if (nid)
11440                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11441                                                           i);
11442         }
11443 }
11444
11445 static void alc662_auto_init_hp_out(struct hda_codec *codec)
11446 {
11447         struct alc_spec *spec = codec->spec;
11448         hda_nid_t pin;
11449
11450         pin = spec->autocfg.hp_pins[0];
11451         if (pin) /* connect to front */
11452                 /* use dac 0 */
11453                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11454 }
11455
11456 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
11457 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
11458
11459 static void alc662_auto_init_analog_input(struct hda_codec *codec)
11460 {
11461         struct alc_spec *spec = codec->spec;
11462         int i;
11463
11464         for (i = 0; i < AUTO_PIN_LAST; i++) {
11465                 hda_nid_t nid = spec->autocfg.input_pins[i];
11466                 if (alc662_is_input_pin(nid)) {
11467                         snd_hda_codec_write(codec, nid, 0,
11468                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
11469                                             (i <= AUTO_PIN_FRONT_MIC ?
11470                                              PIN_VREF80 : PIN_IN));
11471                         if (nid != ALC662_PIN_CD_NID)
11472                                 snd_hda_codec_write(codec, nid, 0,
11473                                                     AC_VERB_SET_AMP_GAIN_MUTE,
11474                                                     AMP_OUT_MUTE);
11475                 }
11476         }
11477 }
11478
11479 static int alc662_parse_auto_config(struct hda_codec *codec)
11480 {
11481         struct alc_spec *spec = codec->spec;
11482         int err;
11483         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11484
11485         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11486                                            alc662_ignore);
11487         if (err < 0)
11488                 return err;
11489         if (!spec->autocfg.line_outs)
11490                 return 0; /* can't find valid BIOS pin config */
11491
11492         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11493         if (err < 0)
11494                 return err;
11495         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11496         if (err < 0)
11497                 return err;
11498         err = alc662_auto_create_extra_out(spec,
11499                                            spec->autocfg.speaker_pins[0],
11500                                            "Speaker");
11501         if (err < 0)
11502                 return err;
11503         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11504                                            "Headphone");
11505         if (err < 0)
11506                 return err;
11507         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11508         if (err < 0)
11509                 return err;
11510
11511         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11512
11513         if (spec->autocfg.dig_out_pin)
11514                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11515
11516         if (spec->kctl_alloc)
11517                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11518
11519         spec->num_mux_defs = 1;
11520         spec->input_mux = &spec->private_imux;
11521         
11522         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11523         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11524         spec->num_mixers++;
11525         return 1;
11526 }
11527
11528 /* additional initialization for auto-configuration model */
11529 static void alc662_auto_init(struct hda_codec *codec)
11530 {
11531         alc662_auto_init_multi_out(codec);
11532         alc662_auto_init_hp_out(codec);
11533         alc662_auto_init_analog_input(codec);
11534 }
11535
11536 static int patch_alc662(struct hda_codec *codec)
11537 {
11538         struct alc_spec *spec;
11539         int err, board_config;
11540
11541         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11542         if (!spec)
11543                 return -ENOMEM;
11544
11545         codec->spec = spec;
11546
11547         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11548                                                   alc662_models,
11549                                                   alc662_cfg_tbl);
11550         if (board_config < 0) {
11551                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11552                        "trying auto-probe from BIOS...\n");
11553                 board_config = ALC662_AUTO;
11554         }
11555
11556         if (board_config == ALC662_AUTO) {
11557                 /* automatic parse from the BIOS config */
11558                 err = alc662_parse_auto_config(codec);
11559                 if (err < 0) {
11560                         alc_free(codec);
11561                         return err;
11562                 } else if (!err) {
11563                         printk(KERN_INFO
11564                                "hda_codec: Cannot set up configuration "
11565                                "from BIOS.  Using base mode...\n");
11566                         board_config = ALC662_3ST_2ch_DIG;
11567                 }
11568         }
11569
11570         if (board_config != ALC662_AUTO)
11571                 setup_preset(spec, &alc662_presets[board_config]);
11572
11573         spec->stream_name_analog = "ALC662 Analog";
11574         spec->stream_analog_playback = &alc662_pcm_analog_playback;
11575         spec->stream_analog_capture = &alc662_pcm_analog_capture;
11576
11577         spec->stream_name_digital = "ALC662 Digital";
11578         spec->stream_digital_playback = &alc662_pcm_digital_playback;
11579         spec->stream_digital_capture = &alc662_pcm_digital_capture;
11580
11581         if (!spec->adc_nids && spec->input_mux) {
11582                 spec->adc_nids = alc662_adc_nids;
11583                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11584         }
11585
11586         codec->patch_ops = alc_patch_ops;
11587         if (board_config == ALC662_AUTO)
11588                 spec->init_hook = alc662_auto_init;
11589
11590         return 0;
11591 }
11592
11593 /*
11594  * patch entries
11595  */
11596 struct hda_codec_preset snd_hda_preset_realtek[] = {
11597         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11598         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11599         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11600         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11601           .patch = patch_alc861 },
11602         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11603         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11604         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11605         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11606           .patch = patch_alc883 },
11607         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11608           .patch = patch_alc662 },
11609         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11610         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11611         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11612         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11613         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11614         {} /* terminator */
11615 };