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