[ALSA] hda-codec - add snd_hda_codec_stereo() function
[linux-2.6] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_BENQ_ED8,
96         ALC262_SONY_ASSAMD,
97         ALC262_BENQ_T31,
98         ALC262_AUTO,
99         ALC262_MODEL_LAST /* last tag */
100 };
101
102 /* ALC268 models */
103 enum {
104         ALC268_3ST,
105         ALC268_AUTO,
106         ALC268_MODEL_LAST /* last tag */
107 };
108
109 /* ALC861 models */
110 enum {
111         ALC861_3ST,
112         ALC660_3ST,
113         ALC861_3ST_DIG,
114         ALC861_6ST_DIG,
115         ALC861_UNIWILL_M31,
116         ALC861_TOSHIBA,
117         ALC861_ASUS,
118         ALC861_ASUS_LAPTOP,
119         ALC861_AUTO,
120         ALC861_MODEL_LAST,
121 };
122
123 /* ALC861-VD models */
124 enum {
125         ALC660VD_3ST,
126         ALC660VD_3ST_DIG,
127         ALC861VD_3ST,
128         ALC861VD_3ST_DIG,
129         ALC861VD_6ST_DIG,
130         ALC861VD_LENOVO,
131         ALC861VD_DALLAS,
132         ALC861VD_AUTO,
133         ALC861VD_MODEL_LAST,
134 };
135
136 /* ALC662 models */
137 enum {
138         ALC662_3ST_2ch_DIG,
139         ALC662_3ST_6ch_DIG,
140         ALC662_3ST_6ch,
141         ALC662_5ST_DIG,
142         ALC662_LENOVO_101E,
143         ALC662_AUTO,
144         ALC662_MODEL_LAST,
145 };
146
147 /* ALC882 models */
148 enum {
149         ALC882_3ST_DIG,
150         ALC882_6ST_DIG,
151         ALC882_ARIMA,
152         ALC882_W2JC,
153         ALC882_TARGA,
154         ALC882_ASUS_A7J,
155         ALC885_MACPRO,
156         ALC885_IMAC24,
157         ALC882_AUTO,
158         ALC882_MODEL_LAST,
159 };
160
161 /* ALC883 models */
162 enum {
163         ALC883_3ST_2ch_DIG,
164         ALC883_3ST_6ch_DIG,
165         ALC883_3ST_6ch,
166         ALC883_6ST_DIG,
167         ALC883_TARGA_DIG,
168         ALC883_TARGA_2ch_DIG,
169         ALC883_ACER,
170         ALC883_ACER_ASPIRE,
171         ALC883_MEDION,
172         ALC883_MEDION_MD2,      
173         ALC883_LAPTOP_EAPD,
174         ALC883_LENOVO_101E_2ch,
175         ALC883_LENOVO_NB0763,
176         ALC888_LENOVO_MS7195_DIG,               
177         ALC888_6ST_HP,
178         ALC888_3ST_HP,
179         ALC883_AUTO,
180         ALC883_MODEL_LAST,
181 };
182
183 /* for GPIO Poll */
184 #define GPIO_MASK       0x03
185
186 struct alc_spec {
187         /* codec parameterization */
188         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
189         unsigned int num_mixers;
190
191         const struct hda_verb *init_verbs[5];   /* initialization verbs
192                                                  * don't forget NULL
193                                                  * termination!
194                                                  */
195         unsigned int num_init_verbs;
196
197         char *stream_name_analog;       /* analog PCM stream */
198         struct hda_pcm_stream *stream_analog_playback;
199         struct hda_pcm_stream *stream_analog_capture;
200
201         char *stream_name_digital;      /* digital PCM stream */
202         struct hda_pcm_stream *stream_digital_playback;
203         struct hda_pcm_stream *stream_digital_capture;
204
205         /* playback */
206         struct hda_multi_out multiout;  /* playback set-up
207                                          * max_channels, dacs must be set
208                                          * dig_out_nid and hp_nid are optional
209                                          */
210
211         /* capture */
212         unsigned int num_adc_nids;
213         hda_nid_t *adc_nids;
214         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
215
216         /* capture source */
217         unsigned int num_mux_defs;
218         const struct hda_input_mux *input_mux;
219         unsigned int cur_mux[3];
220
221         /* channel model */
222         const struct hda_channel_mode *channel_mode;
223         int num_channel_mode;
224         int need_dac_fix;
225
226         /* PCM information */
227         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
228
229         /* dynamic controls, init_verbs and input_mux */
230         struct auto_pin_cfg autocfg;
231         unsigned int num_kctl_alloc, num_kctl_used;
232         struct snd_kcontrol_new *kctl_alloc;
233         struct hda_input_mux private_imux;
234         hda_nid_t private_dac_nids[5];
235
236         /* hooks */
237         void (*init_hook)(struct hda_codec *codec);
238         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
239
240         /* for pin sensing */
241         unsigned int sense_updated: 1;
242         unsigned int jack_present: 1;
243 };
244
245 /*
246  * configuration template - to be copied to the spec instance
247  */
248 struct alc_config_preset {
249         struct snd_kcontrol_new *mixers[5]; /* should be identical size
250                                              * with spec
251                                              */
252         const struct hda_verb *init_verbs[5];
253         unsigned int num_dacs;
254         hda_nid_t *dac_nids;
255         hda_nid_t dig_out_nid;          /* optional */
256         hda_nid_t hp_nid;               /* optional */
257         unsigned int num_adc_nids;
258         hda_nid_t *adc_nids;
259         hda_nid_t dig_in_nid;
260         unsigned int num_channel_mode;
261         const struct hda_channel_mode *channel_mode;
262         int need_dac_fix;
263         unsigned int num_mux_defs;
264         const struct hda_input_mux *input_mux;
265         void (*unsol_event)(struct hda_codec *, unsigned int);
266         void (*init_hook)(struct hda_codec *);
267 };
268
269
270 /*
271  * input MUX handling
272  */
273 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
274                              struct snd_ctl_elem_info *uinfo)
275 {
276         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
277         struct alc_spec *spec = codec->spec;
278         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
279         if (mux_idx >= spec->num_mux_defs)
280                 mux_idx = 0;
281         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
282 }
283
284 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
285                             struct snd_ctl_elem_value *ucontrol)
286 {
287         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
288         struct alc_spec *spec = codec->spec;
289         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
290
291         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
292         return 0;
293 }
294
295 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
296                             struct snd_ctl_elem_value *ucontrol)
297 {
298         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
299         struct alc_spec *spec = codec->spec;
300         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
301         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
302         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
303                                      spec->adc_nids[adc_idx],
304                                      &spec->cur_mux[adc_idx]);
305 }
306
307
308 /*
309  * channel mode setting
310  */
311 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
312                             struct snd_ctl_elem_info *uinfo)
313 {
314         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
315         struct alc_spec *spec = codec->spec;
316         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
317                                     spec->num_channel_mode);
318 }
319
320 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
321                            struct snd_ctl_elem_value *ucontrol)
322 {
323         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
324         struct alc_spec *spec = codec->spec;
325         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
326                                    spec->num_channel_mode,
327                                    spec->multiout.max_channels);
328 }
329
330 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
331                            struct snd_ctl_elem_value *ucontrol)
332 {
333         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
334         struct alc_spec *spec = codec->spec;
335         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
336                                       spec->num_channel_mode,
337                                       &spec->multiout.max_channels);
338         if (err >= 0 && spec->need_dac_fix)
339                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
340         return err;
341 }
342
343 /*
344  * Control the mode of pin widget settings via the mixer.  "pc" is used
345  * instead of "%" to avoid consequences of accidently treating the % as 
346  * being part of a format specifier.  Maximum allowed length of a value is
347  * 63 characters plus NULL terminator.
348  *
349  * Note: some retasking pin complexes seem to ignore requests for input
350  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
351  * are requested.  Therefore order this list so that this behaviour will not
352  * cause problems when mixer clients move through the enum sequentially.
353  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
354  * March 2006.
355  */
356 static char *alc_pin_mode_names[] = {
357         "Mic 50pc bias", "Mic 80pc bias",
358         "Line in", "Line out", "Headphone out",
359 };
360 static unsigned char alc_pin_mode_values[] = {
361         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
362 };
363 /* The control can present all 5 options, or it can limit the options based
364  * in the pin being assumed to be exclusively an input or an output pin.  In
365  * addition, "input" pins may or may not process the mic bias option
366  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
367  * accept requests for bias as of chip versions up to March 2006) and/or
368  * wiring in the computer.
369  */
370 #define ALC_PIN_DIR_IN              0x00
371 #define ALC_PIN_DIR_OUT             0x01
372 #define ALC_PIN_DIR_INOUT           0x02
373 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
374 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
375
376 /* Info about the pin modes supported by the different pin direction modes. 
377  * For each direction the minimum and maximum values are given.
378  */
379 static signed char alc_pin_mode_dir_info[5][2] = {
380         { 0, 2 },    /* ALC_PIN_DIR_IN */
381         { 3, 4 },    /* ALC_PIN_DIR_OUT */
382         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
383         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
384         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
385 };
386 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
387 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
388 #define alc_pin_mode_n_items(_dir) \
389         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
390
391 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
392                              struct snd_ctl_elem_info *uinfo)
393 {
394         unsigned int item_num = uinfo->value.enumerated.item;
395         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
396
397         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
398         uinfo->count = 1;
399         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
400
401         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
402                 item_num = alc_pin_mode_min(dir);
403         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
404         return 0;
405 }
406
407 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
408                             struct snd_ctl_elem_value *ucontrol)
409 {
410         unsigned int i;
411         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
412         hda_nid_t nid = kcontrol->private_value & 0xffff;
413         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
414         long *valp = ucontrol->value.integer.value;
415         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
416                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
417                                                  0x00);
418
419         /* Find enumerated value for current pinctl setting */
420         i = alc_pin_mode_min(dir);
421         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
422                 i++;
423         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
424         return 0;
425 }
426
427 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
428                             struct snd_ctl_elem_value *ucontrol)
429 {
430         signed int change;
431         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
432         hda_nid_t nid = kcontrol->private_value & 0xffff;
433         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
434         long val = *ucontrol->value.integer.value;
435         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
436                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
437                                                  0x00);
438
439         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
440                 val = alc_pin_mode_min(dir);
441
442         change = pinctl != alc_pin_mode_values[val];
443         if (change) {
444                 /* Set pin mode to that requested */
445                 snd_hda_codec_write_cache(codec, nid, 0,
446                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
447                                           alc_pin_mode_values[val]);
448
449                 /* Also enable the retasking pin's input/output as required 
450                  * for the requested pin mode.  Enum values of 2 or less are
451                  * input modes.
452                  *
453                  * Dynamically switching the input/output buffers probably
454                  * reduces noise slightly (particularly on input) so we'll
455                  * do it.  However, having both input and output buffers
456                  * enabled simultaneously doesn't seem to be problematic if
457                  * this turns out to be necessary in the future.
458                  */
459                 if (val <= 2) {
460                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
461                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
462                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
463                                                  HDA_AMP_MUTE, 0);
464                 } else {
465                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
466                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
467                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
468                                                  HDA_AMP_MUTE, 0);
469                 }
470         }
471         return change;
472 }
473
474 #define ALC_PIN_MODE(xname, nid, dir) \
475         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
476           .info = alc_pin_mode_info, \
477           .get = alc_pin_mode_get, \
478           .put = alc_pin_mode_put, \
479           .private_value = nid | (dir<<16) }
480
481 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
482  * together using a mask with more than one bit set.  This control is
483  * currently used only by the ALC260 test model.  At this stage they are not
484  * needed for any "production" models.
485  */
486 #ifdef CONFIG_SND_DEBUG
487 #define alc_gpio_data_info      snd_ctl_boolean_mono_info
488
489 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
490                              struct snd_ctl_elem_value *ucontrol)
491 {
492         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
493         hda_nid_t nid = kcontrol->private_value & 0xffff;
494         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
495         long *valp = ucontrol->value.integer.value;
496         unsigned int val = snd_hda_codec_read(codec, nid, 0,
497                                               AC_VERB_GET_GPIO_DATA, 0x00);
498
499         *valp = (val & mask) != 0;
500         return 0;
501 }
502 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
503                              struct snd_ctl_elem_value *ucontrol)
504 {
505         signed int change;
506         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
507         hda_nid_t nid = kcontrol->private_value & 0xffff;
508         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
509         long val = *ucontrol->value.integer.value;
510         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
511                                                     AC_VERB_GET_GPIO_DATA,
512                                                     0x00);
513
514         /* Set/unset the masked GPIO bit(s) as needed */
515         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
516         if (val == 0)
517                 gpio_data &= ~mask;
518         else
519                 gpio_data |= mask;
520         snd_hda_codec_write_cache(codec, nid, 0,
521                                   AC_VERB_SET_GPIO_DATA, gpio_data);
522
523         return change;
524 }
525 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
526         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
527           .info = alc_gpio_data_info, \
528           .get = alc_gpio_data_get, \
529           .put = alc_gpio_data_put, \
530           .private_value = nid | (mask<<16) }
531 #endif   /* CONFIG_SND_DEBUG */
532
533 /* A switch control to allow the enabling of the digital IO pins on the
534  * ALC260.  This is incredibly simplistic; the intention of this control is
535  * to provide something in the test model allowing digital outputs to be
536  * identified if present.  If models are found which can utilise these
537  * outputs a more complete mixer control can be devised for those models if
538  * necessary.
539  */
540 #ifdef CONFIG_SND_DEBUG
541 #define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
542
543 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
544                               struct snd_ctl_elem_value *ucontrol)
545 {
546         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
547         hda_nid_t nid = kcontrol->private_value & 0xffff;
548         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
549         long *valp = ucontrol->value.integer.value;
550         unsigned int val = snd_hda_codec_read(codec, nid, 0,
551                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
552
553         *valp = (val & mask) != 0;
554         return 0;
555 }
556 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
557                               struct snd_ctl_elem_value *ucontrol)
558 {
559         signed int change;
560         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
561         hda_nid_t nid = kcontrol->private_value & 0xffff;
562         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
563         long val = *ucontrol->value.integer.value;
564         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
565                                                     AC_VERB_GET_DIGI_CONVERT,
566                                                     0x00);
567
568         /* Set/unset the masked control bit(s) as needed */
569         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
570         if (val==0)
571                 ctrl_data &= ~mask;
572         else
573                 ctrl_data |= mask;
574         snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
575                                   ctrl_data);
576
577         return change;
578 }
579 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
580         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
581           .info = alc_spdif_ctrl_info, \
582           .get = alc_spdif_ctrl_get, \
583           .put = alc_spdif_ctrl_put, \
584           .private_value = nid | (mask<<16) }
585 #endif   /* CONFIG_SND_DEBUG */
586
587 /*
588  * set up from the preset table
589  */
590 static void setup_preset(struct alc_spec *spec,
591                          const struct alc_config_preset *preset)
592 {
593         int i;
594
595         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
596                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
597         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
598              i++)
599                 spec->init_verbs[spec->num_init_verbs++] =
600                         preset->init_verbs[i];
601         
602         spec->channel_mode = preset->channel_mode;
603         spec->num_channel_mode = preset->num_channel_mode;
604         spec->need_dac_fix = preset->need_dac_fix;
605
606         spec->multiout.max_channels = spec->channel_mode[0].channels;
607
608         spec->multiout.num_dacs = preset->num_dacs;
609         spec->multiout.dac_nids = preset->dac_nids;
610         spec->multiout.dig_out_nid = preset->dig_out_nid;
611         spec->multiout.hp_nid = preset->hp_nid;
612         
613         spec->num_mux_defs = preset->num_mux_defs;
614         if (!spec->num_mux_defs)
615                 spec->num_mux_defs = 1;
616         spec->input_mux = preset->input_mux;
617
618         spec->num_adc_nids = preset->num_adc_nids;
619         spec->adc_nids = preset->adc_nids;
620         spec->dig_in_nid = preset->dig_in_nid;
621
622         spec->unsol_event = preset->unsol_event;
623         spec->init_hook = preset->init_hook;
624 }
625
626 /* Enable GPIO mask and set output */
627 static struct hda_verb alc_gpio1_init_verbs[] = {
628         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
629         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
630         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
631         { }
632 };
633
634 static struct hda_verb alc_gpio2_init_verbs[] = {
635         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
636         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
637         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
638         { }
639 };
640
641 static struct hda_verb alc_gpio3_init_verbs[] = {
642         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
643         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
644         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
645         { }
646 };
647
648 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
649  *      31 ~ 16 :       Manufacture ID
650  *      15 ~ 8  :       SKU ID
651  *      7  ~ 0  :       Assembly ID
652  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
653  */
654 static void alc_subsystem_id(struct hda_codec *codec,
655                              unsigned int porta, unsigned int porte,
656                              unsigned int portd)
657 {
658         unsigned int ass, tmp;
659
660         ass = codec->subsystem_id;
661         if (!(ass & 1))
662                 return;
663
664         /* Override */
665         tmp = (ass & 0x38) >> 3;        /* external Amp control */
666         switch (tmp) {
667         case 1:
668                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
669                 break;
670         case 3:
671                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
672                 break;
673         case 7:
674                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
675                 break;
676         case 5:
677                 switch (codec->vendor_id) {
678                 case 0x10ec0862:
679                 case 0x10ec0660:
680                 case 0x10ec0662:        
681                 case 0x10ec0267:
682                 case 0x10ec0268:
683                         snd_hda_codec_write(codec, 0x14, 0,
684                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
685                         snd_hda_codec_write(codec, 0x15, 0,
686                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
687                         return;
688                 }
689         case 6:
690                 if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
691                         hda_nid_t port = 0;
692                         tmp = (ass & 0x1800) >> 11;
693                         switch (tmp) {
694                         case 0: port = porta; break;
695                         case 1: port = porte; break;
696                         case 2: port = portd; break;
697                         }
698                         if (port)
699                                 snd_hda_codec_write(codec, port, 0,
700                                                     AC_VERB_SET_EAPD_BTLENABLE,
701                                                     2);
702                 }
703                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
704                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
705                                     (tmp == 5 ? 0x3040 : 0x3050));
706                 break;
707         }
708 }
709
710 /*
711  * Fix-up pin default configurations
712  */
713
714 struct alc_pincfg {
715         hda_nid_t nid;
716         u32 val;
717 };
718
719 static void alc_fix_pincfg(struct hda_codec *codec,
720                            const struct snd_pci_quirk *quirk,
721                            const struct alc_pincfg **pinfix)
722 {
723         const struct alc_pincfg *cfg;
724
725         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
726         if (!quirk)
727                 return;
728
729         cfg = pinfix[quirk->value];
730         for (; cfg->nid; cfg++) {
731                 int i;
732                 u32 val = cfg->val;
733                 for (i = 0; i < 4; i++) {
734                         snd_hda_codec_write(codec, cfg->nid, 0,
735                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
736                                     val & 0xff);
737                         val >>= 8;
738                 }
739         }
740 }
741
742 /*
743  * ALC880 3-stack model
744  *
745  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
746  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
747  *                 F-Mic = 0x1b, HP = 0x19
748  */
749
750 static hda_nid_t alc880_dac_nids[4] = {
751         /* front, rear, clfe, rear_surr */
752         0x02, 0x05, 0x04, 0x03
753 };
754
755 static hda_nid_t alc880_adc_nids[3] = {
756         /* ADC0-2 */
757         0x07, 0x08, 0x09,
758 };
759
760 /* The datasheet says the node 0x07 is connected from inputs,
761  * but it shows zero connection in the real implementation on some devices.
762  * Note: this is a 915GAV bug, fixed on 915GLV
763  */
764 static hda_nid_t alc880_adc_nids_alt[2] = {
765         /* ADC1-2 */
766         0x08, 0x09,
767 };
768
769 #define ALC880_DIGOUT_NID       0x06
770 #define ALC880_DIGIN_NID        0x0a
771
772 static struct hda_input_mux alc880_capture_source = {
773         .num_items = 4,
774         .items = {
775                 { "Mic", 0x0 },
776                 { "Front Mic", 0x3 },
777                 { "Line", 0x2 },
778                 { "CD", 0x4 },
779         },
780 };
781
782 /* channel source setting (2/6 channel selection for 3-stack) */
783 /* 2ch mode */
784 static struct hda_verb alc880_threestack_ch2_init[] = {
785         /* set line-in to input, mute it */
786         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
787         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
788         /* set mic-in to input vref 80%, mute it */
789         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
790         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
791         { } /* end */
792 };
793
794 /* 6ch mode */
795 static struct hda_verb alc880_threestack_ch6_init[] = {
796         /* set line-in to output, unmute it */
797         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
798         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
799         /* set mic-in to output, unmute it */
800         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
801         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
802         { } /* end */
803 };
804
805 static struct hda_channel_mode alc880_threestack_modes[2] = {
806         { 2, alc880_threestack_ch2_init },
807         { 6, alc880_threestack_ch6_init },
808 };
809
810 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
811         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
812         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
813         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
814         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
815         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
816         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
817         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
818         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
819         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
820         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
821         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
822         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
823         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
824         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
825         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
826         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
827         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
828         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
829         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
830         {
831                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
832                 .name = "Channel Mode",
833                 .info = alc_ch_mode_info,
834                 .get = alc_ch_mode_get,
835                 .put = alc_ch_mode_put,
836         },
837         { } /* end */
838 };
839
840 /* capture mixer elements */
841 static struct snd_kcontrol_new alc880_capture_mixer[] = {
842         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
843         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
844         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
845         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
846         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
847         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
848         {
849                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
850                 /* The multiple "Capture Source" controls confuse alsamixer
851                  * So call somewhat different..
852                  * FIXME: the controls appear in the "playback" view!
853                  */
854                 /* .name = "Capture Source", */
855                 .name = "Input Source",
856                 .count = 3,
857                 .info = alc_mux_enum_info,
858                 .get = alc_mux_enum_get,
859                 .put = alc_mux_enum_put,
860         },
861         { } /* end */
862 };
863
864 /* capture mixer elements (in case NID 0x07 not available) */
865 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
866         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
867         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
868         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
869         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
870         {
871                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
872                 /* The multiple "Capture Source" controls confuse alsamixer
873                  * So call somewhat different..
874                  * FIXME: the controls appear in the "playback" view!
875                  */
876                 /* .name = "Capture Source", */
877                 .name = "Input Source",
878                 .count = 2,
879                 .info = alc_mux_enum_info,
880                 .get = alc_mux_enum_get,
881                 .put = alc_mux_enum_put,
882         },
883         { } /* end */
884 };
885
886
887
888 /*
889  * ALC880 5-stack model
890  *
891  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
892  *      Side = 0x02 (0xd)
893  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
894  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
895  */
896
897 /* additional mixers to alc880_three_stack_mixer */
898 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
899         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
900         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
901         { } /* end */
902 };
903
904 /* channel source setting (6/8 channel selection for 5-stack) */
905 /* 6ch mode */
906 static struct hda_verb alc880_fivestack_ch6_init[] = {
907         /* set line-in to input, mute it */
908         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
909         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
910         { } /* end */
911 };
912
913 /* 8ch mode */
914 static struct hda_verb alc880_fivestack_ch8_init[] = {
915         /* set line-in to output, unmute it */
916         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
917         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
918         { } /* end */
919 };
920
921 static struct hda_channel_mode alc880_fivestack_modes[2] = {
922         { 6, alc880_fivestack_ch6_init },
923         { 8, alc880_fivestack_ch8_init },
924 };
925
926
927 /*
928  * ALC880 6-stack model
929  *
930  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
931  *      Side = 0x05 (0x0f)
932  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
933  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
934  */
935
936 static hda_nid_t alc880_6st_dac_nids[4] = {
937         /* front, rear, clfe, rear_surr */
938         0x02, 0x03, 0x04, 0x05
939 };
940
941 static struct hda_input_mux alc880_6stack_capture_source = {
942         .num_items = 4,
943         .items = {
944                 { "Mic", 0x0 },
945                 { "Front Mic", 0x1 },
946                 { "Line", 0x2 },
947                 { "CD", 0x4 },
948         },
949 };
950
951 /* fixed 8-channels */
952 static struct hda_channel_mode alc880_sixstack_modes[1] = {
953         { 8, NULL },
954 };
955
956 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
957         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
958         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
959         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
960         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
961         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
962         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
963         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
964         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
965         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
966         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
967         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
968         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
969         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
970         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
971         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
972         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
973         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
974         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
975         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
976         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
977         {
978                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
979                 .name = "Channel Mode",
980                 .info = alc_ch_mode_info,
981                 .get = alc_ch_mode_get,
982                 .put = alc_ch_mode_put,
983         },
984         { } /* end */
985 };
986
987
988 /*
989  * ALC880 W810 model
990  *
991  * W810 has rear IO for:
992  * Front (DAC 02)
993  * Surround (DAC 03)
994  * Center/LFE (DAC 04)
995  * Digital out (06)
996  *
997  * The system also has a pair of internal speakers, and a headphone jack.
998  * These are both connected to Line2 on the codec, hence to DAC 02.
999  * 
1000  * There is a variable resistor to control the speaker or headphone
1001  * volume. This is a hardware-only device without a software API.
1002  *
1003  * Plugging headphones in will disable the internal speakers. This is
1004  * implemented in hardware, not via the driver using jack sense. In
1005  * a similar fashion, plugging into the rear socket marked "front" will
1006  * disable both the speakers and headphones.
1007  *
1008  * For input, there's a microphone jack, and an "audio in" jack.
1009  * These may not do anything useful with this driver yet, because I
1010  * haven't setup any initialization verbs for these yet...
1011  */
1012
1013 static hda_nid_t alc880_w810_dac_nids[3] = {
1014         /* front, rear/surround, clfe */
1015         0x02, 0x03, 0x04
1016 };
1017
1018 /* fixed 6 channels */
1019 static struct hda_channel_mode alc880_w810_modes[1] = {
1020         { 6, NULL }
1021 };
1022
1023 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1024 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1025         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1026         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1027         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1028         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1029         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1030         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1031         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1032         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1033         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1034         { } /* end */
1035 };
1036
1037
1038 /*
1039  * Z710V model
1040  *
1041  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1042  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1043  *                 Line = 0x1a
1044  */
1045
1046 static hda_nid_t alc880_z71v_dac_nids[1] = {
1047         0x02
1048 };
1049 #define ALC880_Z71V_HP_DAC      0x03
1050
1051 /* fixed 2 channels */
1052 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1053         { 2, NULL }
1054 };
1055
1056 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1057         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1058         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1059         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1060         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1061         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1062         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1063         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1064         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1065         { } /* end */
1066 };
1067
1068
1069 /* FIXME! */
1070 /*
1071  * ALC880 F1734 model
1072  *
1073  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1074  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1075  */
1076
1077 static hda_nid_t alc880_f1734_dac_nids[1] = {
1078         0x03
1079 };
1080 #define ALC880_F1734_HP_DAC     0x02
1081
1082 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1083         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1084         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1085         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1086         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1087         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1088         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1089         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1090         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1091         { } /* end */
1092 };
1093
1094
1095 /* FIXME! */
1096 /*
1097  * ALC880 ASUS model
1098  *
1099  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1100  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1101  *  Mic = 0x18, Line = 0x1a
1102  */
1103
1104 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1105 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1106
1107 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1108         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1109         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1110         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1111         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1112         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1113         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1114         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1115         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1116         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1117         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1118         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1119         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1120         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1121         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1122         {
1123                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1124                 .name = "Channel Mode",
1125                 .info = alc_ch_mode_info,
1126                 .get = alc_ch_mode_get,
1127                 .put = alc_ch_mode_put,
1128         },
1129         { } /* end */
1130 };
1131
1132 /* FIXME! */
1133 /*
1134  * ALC880 ASUS W1V model
1135  *
1136  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1137  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1138  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1139  */
1140
1141 /* additional mixers to alc880_asus_mixer */
1142 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1143         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1144         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1145         { } /* end */
1146 };
1147
1148 /* additional mixers to alc880_asus_mixer */
1149 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1150         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1151         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1152         { } /* end */
1153 };
1154
1155 /* TCL S700 */
1156 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1157         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1158         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1159         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1160         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1161         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1162         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1163         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1164         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1165         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1166         {
1167                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1168                 /* The multiple "Capture Source" controls confuse alsamixer
1169                  * So call somewhat different..
1170                  * FIXME: the controls appear in the "playback" view!
1171                  */
1172                 /* .name = "Capture Source", */
1173                 .name = "Input Source",
1174                 .count = 1,
1175                 .info = alc_mux_enum_info,
1176                 .get = alc_mux_enum_get,
1177                 .put = alc_mux_enum_put,
1178         },
1179         { } /* end */
1180 };
1181
1182 /* Uniwill */
1183 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1184         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1185         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1186         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1187         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1188         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1189         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1190         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1191         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1192         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1193         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1194         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1195         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1196         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1197         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1198         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1199         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1200         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1201         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1202         {
1203                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1204                 .name = "Channel Mode",
1205                 .info = alc_ch_mode_info,
1206                 .get = alc_ch_mode_get,
1207                 .put = alc_ch_mode_put,
1208         },
1209         { } /* end */
1210 };
1211
1212 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1213         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1214         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1215         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1216         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1217         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1218         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1219         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1220         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1221         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1222         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1223         { } /* end */
1224 };
1225
1226 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1227         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1228         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1229         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1230         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1231         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1232         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1233         { } /* end */
1234 };
1235
1236 /*
1237  * build control elements
1238  */
1239 static int alc_build_controls(struct hda_codec *codec)
1240 {
1241         struct alc_spec *spec = codec->spec;
1242         int err;
1243         int i;
1244
1245         for (i = 0; i < spec->num_mixers; i++) {
1246                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1247                 if (err < 0)
1248                         return err;
1249         }
1250
1251         if (spec->multiout.dig_out_nid) {
1252                 err = snd_hda_create_spdif_out_ctls(codec,
1253                                                     spec->multiout.dig_out_nid);
1254                 if (err < 0)
1255                         return err;
1256         }
1257         if (spec->dig_in_nid) {
1258                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1259                 if (err < 0)
1260                         return err;
1261         }
1262         return 0;
1263 }
1264
1265
1266 /*
1267  * initialize the codec volumes, etc
1268  */
1269
1270 /*
1271  * generic initialization of ADC, input mixers and output mixers
1272  */
1273 static struct hda_verb alc880_volume_init_verbs[] = {
1274         /*
1275          * Unmute ADC0-2 and set the default input to mic-in
1276          */
1277         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1278         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1279         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1280         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1281         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1282         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1283
1284         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1285          * mixer widget
1286          * Note: PASD motherboards uses the Line In 2 as the input for front
1287          * panel mic (mic 2)
1288          */
1289         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1290         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1291         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1292         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1293         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1294         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1295
1296         /*
1297          * Set up output mixers (0x0c - 0x0f)
1298          */
1299         /* set vol=0 to output mixers */
1300         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1301         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1302         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1303         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1304         /* set up input amps for analog loopback */
1305         /* Amp Indices: DAC = 0, mixer = 1 */
1306         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1307         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1308         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1309         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1310         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1311         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1312         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1313         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1314
1315         { }
1316 };
1317
1318 /*
1319  * 3-stack pin configuration:
1320  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1321  */
1322 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1323         /*
1324          * preset connection lists of input pins
1325          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1326          */
1327         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1328         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1329         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1330
1331         /*
1332          * Set pin mode and muting
1333          */
1334         /* set front pin widgets 0x14 for output */
1335         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1336         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1337         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1338         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1339         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1340         /* Mic2 (as headphone out) for HP output */
1341         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1342         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1343         /* Line In pin widget for input */
1344         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1345         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1346         /* Line2 (as front mic) pin widget for input and vref at 80% */
1347         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1348         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1349         /* CD pin widget for input */
1350         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1351
1352         { }
1353 };
1354
1355 /*
1356  * 5-stack pin configuration:
1357  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1358  * line-in/side = 0x1a, f-mic = 0x1b
1359  */
1360 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1361         /*
1362          * preset connection lists of input pins
1363          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1364          */
1365         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1366         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1367
1368         /*
1369          * Set pin mode and muting
1370          */
1371         /* set pin widgets 0x14-0x17 for output */
1372         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1373         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1374         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1375         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376         /* unmute pins for output (no gain on this amp) */
1377         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1378         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1379         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1380         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1381
1382         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1383         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1384         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1385         /* Mic2 (as headphone out) for HP output */
1386         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1387         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1388         /* Line In pin widget for input */
1389         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1390         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1391         /* Line2 (as front mic) pin widget for input and vref at 80% */
1392         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1393         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1394         /* CD pin widget for input */
1395         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1396
1397         { }
1398 };
1399
1400 /*
1401  * W810 pin configuration:
1402  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1403  */
1404 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1405         /* hphone/speaker input selector: front DAC */
1406         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1407
1408         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1409         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1410         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1411         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1412         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1413         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1414
1415         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1416         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1417
1418         { }
1419 };
1420
1421 /*
1422  * Z71V pin configuration:
1423  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1424  */
1425 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1426         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1427         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1428         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1429         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1430
1431         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1432         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1433         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1434         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1435
1436         { }
1437 };
1438
1439 /*
1440  * 6-stack pin configuration:
1441  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1442  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1443  */
1444 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1445         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1446
1447         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1448         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1449         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1450         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1451         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1452         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1453         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1454         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1455
1456         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1457         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1458         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1459         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1460         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1461         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1462         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1463         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1464         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1465         
1466         { }
1467 };
1468
1469 /*
1470  * Uniwill pin configuration:
1471  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1472  * line = 0x1a
1473  */
1474 static struct hda_verb alc880_uniwill_init_verbs[] = {
1475         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1476
1477         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1478         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1479         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1480         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1481         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1482         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1483         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1484         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1485         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1486         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1487         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1488         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1489         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1490         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1491
1492         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1493         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1494         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1495         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1496         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1497         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1498         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1499         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1500         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1501
1502         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1503         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1504
1505         { }
1506 };
1507
1508 /*
1509 * Uniwill P53
1510 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1511  */
1512 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1513         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1514
1515         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1516         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1517         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1518         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1519         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1520         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1521         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1522         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1523         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1524         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1525         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1526         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1527
1528         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1529         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1530         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1531         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1532         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1533         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1534
1535         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1536         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1537
1538         { }
1539 };
1540
1541 static struct hda_verb alc880_beep_init_verbs[] = {
1542         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1543         { }
1544 };
1545
1546 /* toggle speaker-output according to the hp-jack state */
1547 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1548 {
1549         unsigned int present;
1550         unsigned char bits;
1551
1552         present = snd_hda_codec_read(codec, 0x14, 0,
1553                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1554         bits = present ? HDA_AMP_MUTE : 0;
1555         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1556                                  HDA_AMP_MUTE, bits);
1557         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1558                                  HDA_AMP_MUTE, bits);
1559 }
1560
1561 /* auto-toggle front mic */
1562 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1563 {
1564         unsigned int present;
1565         unsigned char bits;
1566
1567         present = snd_hda_codec_read(codec, 0x18, 0,
1568                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1569         bits = present ? HDA_AMP_MUTE : 0;
1570         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1571 }
1572
1573 static void alc880_uniwill_automute(struct hda_codec *codec)
1574 {
1575         alc880_uniwill_hp_automute(codec);
1576         alc880_uniwill_mic_automute(codec);
1577 }
1578
1579 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1580                                        unsigned int res)
1581 {
1582         /* Looks like the unsol event is incompatible with the standard
1583          * definition.  4bit tag is placed at 28 bit!
1584          */
1585         switch (res >> 28) {
1586         case ALC880_HP_EVENT:
1587                 alc880_uniwill_hp_automute(codec);
1588                 break;
1589         case ALC880_MIC_EVENT:
1590                 alc880_uniwill_mic_automute(codec);
1591                 break;
1592         }
1593 }
1594
1595 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1596 {
1597         unsigned int present;
1598         unsigned char bits;
1599
1600         present = snd_hda_codec_read(codec, 0x14, 0,
1601                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1602         bits = present ? HDA_AMP_MUTE : 0;
1603         snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1604 }
1605
1606 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1607 {
1608         unsigned int present;
1609         
1610         present = snd_hda_codec_read(codec, 0x21, 0,
1611                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1612         present &= HDA_AMP_VOLMASK;
1613         snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1614                                  HDA_AMP_VOLMASK, present);
1615         snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1616                                  HDA_AMP_VOLMASK, present);
1617 }
1618
1619 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1620                                            unsigned int res)
1621 {
1622         /* Looks like the unsol event is incompatible with the standard
1623          * definition.  4bit tag is placed at 28 bit!
1624          */
1625         if ((res >> 28) == ALC880_HP_EVENT)
1626                 alc880_uniwill_p53_hp_automute(codec);
1627         if ((res >> 28) == ALC880_DCVOL_EVENT)
1628                 alc880_uniwill_p53_dcvol_automute(codec);
1629 }
1630
1631 /* FIXME! */
1632 /*
1633  * F1734 pin configuration:
1634  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1635  */
1636 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1637         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1638         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1639         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1640         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1641
1642         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1643         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1644         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1645         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1646
1647         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1648         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1649         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1650         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1651         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1652         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1653         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1654         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1655         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1656
1657         { }
1658 };
1659
1660 /* FIXME! */
1661 /*
1662  * ASUS pin configuration:
1663  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1664  */
1665 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1666         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1667         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1668         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1669         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1670
1671         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1672         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1673         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1674         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1675         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1676         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1677         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1678         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1679
1680         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1681         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1682         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1683         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1684         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1685         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1686         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1687         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1688         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1689         
1690         { }
1691 };
1692
1693 /* Enable GPIO mask and set output */
1694 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1695 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1696
1697 /* Clevo m520g init */
1698 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1699         /* headphone output */
1700         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1701         /* line-out */
1702         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1703         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704         /* Line-in */
1705         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1706         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1707         /* CD */
1708         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1709         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710         /* Mic1 (rear panel) */
1711         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1712         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1713         /* Mic2 (front panel) */
1714         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1715         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1716         /* headphone */
1717         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1718         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1719         /* change to EAPD mode */
1720         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1721         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1722
1723         { }
1724 };
1725
1726 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1727         /* change to EAPD mode */
1728         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1729         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1730
1731         /* Headphone output */
1732         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1733         /* Front output*/
1734         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1735         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1736
1737         /* Line In pin widget for input */
1738         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1739         /* CD pin widget for input */
1740         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1741         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1742         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1743
1744         /* change to EAPD mode */
1745         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1746         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1747
1748         { }
1749 };
1750
1751 /*
1752  * LG m1 express dual
1753  *
1754  * Pin assignment:
1755  *   Rear Line-In/Out (blue): 0x14
1756  *   Build-in Mic-In: 0x15
1757  *   Speaker-out: 0x17
1758  *   HP-Out (green): 0x1b
1759  *   Mic-In/Out (red): 0x19
1760  *   SPDIF-Out: 0x1e
1761  */
1762
1763 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1764 static hda_nid_t alc880_lg_dac_nids[3] = {
1765         0x05, 0x02, 0x03
1766 };
1767
1768 /* seems analog CD is not working */
1769 static struct hda_input_mux alc880_lg_capture_source = {
1770         .num_items = 3,
1771         .items = {
1772                 { "Mic", 0x1 },
1773                 { "Line", 0x5 },
1774                 { "Internal Mic", 0x6 },
1775         },
1776 };
1777
1778 /* 2,4,6 channel modes */
1779 static struct hda_verb alc880_lg_ch2_init[] = {
1780         /* set line-in and mic-in to input */
1781         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1782         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1783         { }
1784 };
1785
1786 static struct hda_verb alc880_lg_ch4_init[] = {
1787         /* set line-in to out and mic-in to input */
1788         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1789         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1790         { }
1791 };
1792
1793 static struct hda_verb alc880_lg_ch6_init[] = {
1794         /* set line-in and mic-in to output */
1795         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1796         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1797         { }
1798 };
1799
1800 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1801         { 2, alc880_lg_ch2_init },
1802         { 4, alc880_lg_ch4_init },
1803         { 6, alc880_lg_ch6_init },
1804 };
1805
1806 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1807         /* FIXME: it's not really "master" but front channels */
1808         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1809         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1810         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1811         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1812         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1813         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1814         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1815         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1816         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1817         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1818         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1819         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1820         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1821         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1822         {
1823                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1824                 .name = "Channel Mode",
1825                 .info = alc_ch_mode_info,
1826                 .get = alc_ch_mode_get,
1827                 .put = alc_ch_mode_put,
1828         },
1829         { } /* end */
1830 };
1831
1832 static struct hda_verb alc880_lg_init_verbs[] = {
1833         /* set capture source to mic-in */
1834         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1835         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1836         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1837         /* mute all amp mixer inputs */
1838         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1839         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1840         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1841         /* line-in to input */
1842         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1843         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1844         /* built-in mic */
1845         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1846         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1847         /* speaker-out */
1848         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1849         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1850         /* mic-in to input */
1851         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1852         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1853         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1854         /* HP-out */
1855         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1856         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1857         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1858         /* jack sense */
1859         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1860         { }
1861 };
1862
1863 /* toggle speaker-output according to the hp-jack state */
1864 static void alc880_lg_automute(struct hda_codec *codec)
1865 {
1866         unsigned int present;
1867         unsigned char bits;
1868
1869         present = snd_hda_codec_read(codec, 0x1b, 0,
1870                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1871         bits = present ? HDA_AMP_MUTE : 0;
1872         snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
1873                                  HDA_AMP_MUTE, bits);
1874 }
1875
1876 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1877 {
1878         /* Looks like the unsol event is incompatible with the standard
1879          * definition.  4bit tag is placed at 28 bit!
1880          */
1881         if ((res >> 28) == 0x01)
1882                 alc880_lg_automute(codec);
1883 }
1884
1885 /*
1886  * LG LW20
1887  *
1888  * Pin assignment:
1889  *   Speaker-out: 0x14
1890  *   Mic-In: 0x18
1891  *   Built-in Mic-In: 0x19
1892  *   Line-In: 0x1b
1893  *   HP-Out: 0x1a
1894  *   SPDIF-Out: 0x1e
1895  */
1896
1897 static struct hda_input_mux alc880_lg_lw_capture_source = {
1898         .num_items = 3,
1899         .items = {
1900                 { "Mic", 0x0 },
1901                 { "Internal Mic", 0x1 },
1902                 { "Line In", 0x2 },
1903         },
1904 };
1905
1906 #define alc880_lg_lw_modes alc880_threestack_modes
1907
1908 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1909         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1910         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1911         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1912         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1913         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1914         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1915         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1916         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1917         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1918         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1919         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1920         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1921         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1922         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1923         {
1924                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1925                 .name = "Channel Mode",
1926                 .info = alc_ch_mode_info,
1927                 .get = alc_ch_mode_get,
1928                 .put = alc_ch_mode_put,
1929         },
1930         { } /* end */
1931 };
1932
1933 static struct hda_verb alc880_lg_lw_init_verbs[] = {
1934         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1935         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1936         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1937
1938         /* set capture source to mic-in */
1939         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1940         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1941         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1942         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1943         /* speaker-out */
1944         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1945         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1946         /* HP-out */
1947         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1948         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1949         /* mic-in to input */
1950         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1951         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1952         /* built-in mic */
1953         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1954         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1955         /* jack sense */
1956         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1957         { }
1958 };
1959
1960 /* toggle speaker-output according to the hp-jack state */
1961 static void alc880_lg_lw_automute(struct hda_codec *codec)
1962 {
1963         unsigned int present;
1964         unsigned char bits;
1965
1966         present = snd_hda_codec_read(codec, 0x1b, 0,
1967                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1968         bits = present ? HDA_AMP_MUTE : 0;
1969         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1970                                  HDA_AMP_MUTE, bits);
1971 }
1972
1973 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1974 {
1975         /* Looks like the unsol event is incompatible with the standard
1976          * definition.  4bit tag is placed at 28 bit!
1977          */
1978         if ((res >> 28) == 0x01)
1979                 alc880_lg_lw_automute(codec);
1980 }
1981
1982 /*
1983  * Common callbacks
1984  */
1985
1986 static int alc_init(struct hda_codec *codec)
1987 {
1988         struct alc_spec *spec = codec->spec;
1989         unsigned int i;
1990
1991         for (i = 0; i < spec->num_init_verbs; i++)
1992                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1993
1994         if (spec->init_hook)
1995                 spec->init_hook(codec);
1996
1997         return 0;
1998 }
1999
2000 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2001 {
2002         struct alc_spec *spec = codec->spec;
2003
2004         if (spec->unsol_event)
2005                 spec->unsol_event(codec, res);
2006 }
2007
2008 /*
2009  * Analog playback callbacks
2010  */
2011 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2012                                     struct hda_codec *codec,
2013                                     struct snd_pcm_substream *substream)
2014 {
2015         struct alc_spec *spec = codec->spec;
2016         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2017 }
2018
2019 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2020                                        struct hda_codec *codec,
2021                                        unsigned int stream_tag,
2022                                        unsigned int format,
2023                                        struct snd_pcm_substream *substream)
2024 {
2025         struct alc_spec *spec = codec->spec;
2026         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2027                                                 stream_tag, format, substream);
2028 }
2029
2030 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2031                                        struct hda_codec *codec,
2032                                        struct snd_pcm_substream *substream)
2033 {
2034         struct alc_spec *spec = codec->spec;
2035         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2036 }
2037
2038 /*
2039  * Digital out
2040  */
2041 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2042                                         struct hda_codec *codec,
2043                                         struct snd_pcm_substream *substream)
2044 {
2045         struct alc_spec *spec = codec->spec;
2046         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2047 }
2048
2049 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2050                                            struct hda_codec *codec,
2051                                            unsigned int stream_tag,
2052                                            unsigned int format,
2053                                            struct snd_pcm_substream *substream)
2054 {
2055         struct alc_spec *spec = codec->spec;
2056         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2057                                              stream_tag, format, substream);
2058 }
2059
2060 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2061                                          struct hda_codec *codec,
2062                                          struct snd_pcm_substream *substream)
2063 {
2064         struct alc_spec *spec = codec->spec;
2065         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2066 }
2067
2068 /*
2069  * Analog capture
2070  */
2071 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2072                                       struct hda_codec *codec,
2073                                       unsigned int stream_tag,
2074                                       unsigned int format,
2075                                       struct snd_pcm_substream *substream)
2076 {
2077         struct alc_spec *spec = codec->spec;
2078
2079         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2080                                    stream_tag, 0, format);
2081         return 0;
2082 }
2083
2084 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2085                                       struct hda_codec *codec,
2086                                       struct snd_pcm_substream *substream)
2087 {
2088         struct alc_spec *spec = codec->spec;
2089
2090         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2091                                    0, 0, 0);
2092         return 0;
2093 }
2094
2095
2096 /*
2097  */
2098 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2099         .substreams = 1,
2100         .channels_min = 2,
2101         .channels_max = 8,
2102         /* NID is set in alc_build_pcms */
2103         .ops = {
2104                 .open = alc880_playback_pcm_open,
2105                 .prepare = alc880_playback_pcm_prepare,
2106                 .cleanup = alc880_playback_pcm_cleanup
2107         },
2108 };
2109
2110 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2111         .substreams = 2,
2112         .channels_min = 2,
2113         .channels_max = 2,
2114         /* NID is set in alc_build_pcms */
2115         .ops = {
2116                 .prepare = alc880_capture_pcm_prepare,
2117                 .cleanup = alc880_capture_pcm_cleanup
2118         },
2119 };
2120
2121 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2122         .substreams = 1,
2123         .channels_min = 2,
2124         .channels_max = 2,
2125         /* NID is set in alc_build_pcms */
2126         .ops = {
2127                 .open = alc880_dig_playback_pcm_open,
2128                 .close = alc880_dig_playback_pcm_close,
2129                 .prepare = alc880_dig_playback_pcm_prepare
2130         },
2131 };
2132
2133 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2134         .substreams = 1,
2135         .channels_min = 2,
2136         .channels_max = 2,
2137         /* NID is set in alc_build_pcms */
2138 };
2139
2140 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2141 static struct hda_pcm_stream alc_pcm_null_playback = {
2142         .substreams = 0,
2143         .channels_min = 0,
2144         .channels_max = 0,
2145 };
2146
2147 static int alc_build_pcms(struct hda_codec *codec)
2148 {
2149         struct alc_spec *spec = codec->spec;
2150         struct hda_pcm *info = spec->pcm_rec;
2151         int i;
2152
2153         codec->num_pcms = 1;
2154         codec->pcm_info = info;
2155
2156         info->name = spec->stream_name_analog;
2157         if (spec->stream_analog_playback) {
2158                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2159                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2160                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2161         }
2162         if (spec->stream_analog_capture) {
2163                 snd_assert(spec->adc_nids, return -EINVAL);
2164                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2165                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2166         }
2167
2168         if (spec->channel_mode) {
2169                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2170                 for (i = 0; i < spec->num_channel_mode; i++) {
2171                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2172                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2173                         }
2174                 }
2175         }
2176
2177         /* SPDIF for stream index #1 */
2178         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2179                 codec->num_pcms = 2;
2180                 info = spec->pcm_rec + 1;
2181                 info->name = spec->stream_name_digital;
2182                 if (spec->multiout.dig_out_nid &&
2183                     spec->stream_digital_playback) {
2184                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2185                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2186                 }
2187                 if (spec->dig_in_nid &&
2188                     spec->stream_digital_capture) {
2189                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2190                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2191                 }
2192         }
2193
2194         /* If the use of more than one ADC is requested for the current
2195          * model, configure a second analog capture-only PCM.
2196          */
2197         /* Additional Analaog capture for index #2 */
2198         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2199             spec->adc_nids) {
2200                 codec->num_pcms = 3;
2201                 info = spec->pcm_rec + 2;
2202                 info->name = spec->stream_name_analog;
2203                 /* No playback stream for second PCM */
2204                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2205                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2206                 if (spec->stream_analog_capture) {
2207                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2208                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2209                 }
2210         }
2211
2212         return 0;
2213 }
2214
2215 static void alc_free(struct hda_codec *codec)
2216 {
2217         struct alc_spec *spec = codec->spec;
2218         unsigned int i;
2219
2220         if (!spec)
2221                 return;
2222
2223         if (spec->kctl_alloc) {
2224                 for (i = 0; i < spec->num_kctl_used; i++)
2225                         kfree(spec->kctl_alloc[i].name);
2226                 kfree(spec->kctl_alloc);
2227         }
2228         kfree(spec);
2229 }
2230
2231 /*
2232  */
2233 static struct hda_codec_ops alc_patch_ops = {
2234         .build_controls = alc_build_controls,
2235         .build_pcms = alc_build_pcms,
2236         .init = alc_init,
2237         .free = alc_free,
2238         .unsol_event = alc_unsol_event,
2239 };
2240
2241
2242 /*
2243  * Test configuration for debugging
2244  *
2245  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2246  * enum controls.
2247  */
2248 #ifdef CONFIG_SND_DEBUG
2249 static hda_nid_t alc880_test_dac_nids[4] = {
2250         0x02, 0x03, 0x04, 0x05
2251 };
2252
2253 static struct hda_input_mux alc880_test_capture_source = {
2254         .num_items = 7,
2255         .items = {
2256                 { "In-1", 0x0 },
2257                 { "In-2", 0x1 },
2258                 { "In-3", 0x2 },
2259                 { "In-4", 0x3 },
2260                 { "CD", 0x4 },
2261                 { "Front", 0x5 },
2262                 { "Surround", 0x6 },
2263         },
2264 };
2265
2266 static struct hda_channel_mode alc880_test_modes[4] = {
2267         { 2, NULL },
2268         { 4, NULL },
2269         { 6, NULL },
2270         { 8, NULL },
2271 };
2272
2273 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2274                                  struct snd_ctl_elem_info *uinfo)
2275 {
2276         static char *texts[] = {
2277                 "N/A", "Line Out", "HP Out",
2278                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2279         };
2280         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2281         uinfo->count = 1;
2282         uinfo->value.enumerated.items = 8;
2283         if (uinfo->value.enumerated.item >= 8)
2284                 uinfo->value.enumerated.item = 7;
2285         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2286         return 0;
2287 }
2288
2289 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2290                                 struct snd_ctl_elem_value *ucontrol)
2291 {
2292         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2293         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2294         unsigned int pin_ctl, item = 0;
2295
2296         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2297                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2298         if (pin_ctl & AC_PINCTL_OUT_EN) {
2299                 if (pin_ctl & AC_PINCTL_HP_EN)
2300                         item = 2;
2301                 else
2302                         item = 1;
2303         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2304                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2305                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2306                 case AC_PINCTL_VREF_50:  item = 4; break;
2307                 case AC_PINCTL_VREF_GRD: item = 5; break;
2308                 case AC_PINCTL_VREF_80:  item = 6; break;
2309                 case AC_PINCTL_VREF_100: item = 7; break;
2310                 }
2311         }
2312         ucontrol->value.enumerated.item[0] = item;
2313         return 0;
2314 }
2315
2316 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2317                                 struct snd_ctl_elem_value *ucontrol)
2318 {
2319         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2320         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2321         static unsigned int ctls[] = {
2322                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2323                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2324                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2325                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2326                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2327                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2328         };
2329         unsigned int old_ctl, new_ctl;
2330
2331         old_ctl = snd_hda_codec_read(codec, nid, 0,
2332                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2333         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2334         if (old_ctl != new_ctl) {
2335                 int val;
2336                 snd_hda_codec_write_cache(codec, nid, 0,
2337                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
2338                                           new_ctl);
2339                 val = ucontrol->value.enumerated.item[0] >= 3 ?
2340                         HDA_AMP_MUTE : 0;
2341                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2342                                          HDA_AMP_MUTE, val);
2343                 return 1;
2344         }
2345         return 0;
2346 }
2347
2348 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2349                                  struct snd_ctl_elem_info *uinfo)
2350 {
2351         static char *texts[] = {
2352                 "Front", "Surround", "CLFE", "Side"
2353         };
2354         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2355         uinfo->count = 1;
2356         uinfo->value.enumerated.items = 4;
2357         if (uinfo->value.enumerated.item >= 4)
2358                 uinfo->value.enumerated.item = 3;
2359         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2360         return 0;
2361 }
2362
2363 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2364                                 struct snd_ctl_elem_value *ucontrol)
2365 {
2366         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2367         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2368         unsigned int sel;
2369
2370         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2371         ucontrol->value.enumerated.item[0] = sel & 3;
2372         return 0;
2373 }
2374
2375 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2376                                 struct snd_ctl_elem_value *ucontrol)
2377 {
2378         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2379         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2380         unsigned int sel;
2381
2382         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2383         if (ucontrol->value.enumerated.item[0] != sel) {
2384                 sel = ucontrol->value.enumerated.item[0] & 3;
2385                 snd_hda_codec_write_cache(codec, nid, 0,
2386                                           AC_VERB_SET_CONNECT_SEL, sel);
2387                 return 1;
2388         }
2389         return 0;
2390 }
2391
2392 #define PIN_CTL_TEST(xname,nid) {                       \
2393                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2394                         .name = xname,                 \
2395                         .info = alc_test_pin_ctl_info, \
2396                         .get = alc_test_pin_ctl_get,   \
2397                         .put = alc_test_pin_ctl_put,   \
2398                         .private_value = nid           \
2399                         }
2400
2401 #define PIN_SRC_TEST(xname,nid) {                       \
2402                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2403                         .name = xname,                 \
2404                         .info = alc_test_pin_src_info, \
2405                         .get = alc_test_pin_src_get,   \
2406                         .put = alc_test_pin_src_put,   \
2407                         .private_value = nid           \
2408                         }
2409
2410 static struct snd_kcontrol_new alc880_test_mixer[] = {
2411         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2412         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2413         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2414         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2415         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2416         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2417         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2418         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2419         PIN_CTL_TEST("Front Pin Mode", 0x14),
2420         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2421         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2422         PIN_CTL_TEST("Side Pin Mode", 0x17),
2423         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2424         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2425         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2426         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2427         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2428         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2429         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2430         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2431         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2432         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2433         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2434         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2435         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2436         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2437         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2438         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2439         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2440         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2441         {
2442                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2443                 .name = "Channel Mode",
2444                 .info = alc_ch_mode_info,
2445                 .get = alc_ch_mode_get,
2446                 .put = alc_ch_mode_put,
2447         },
2448         { } /* end */
2449 };
2450
2451 static struct hda_verb alc880_test_init_verbs[] = {
2452         /* Unmute inputs of 0x0c - 0x0f */
2453         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2454         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2455         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2456         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2457         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2458         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2459         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2460         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2461         /* Vol output for 0x0c-0x0f */
2462         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2463         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2464         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2465         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2466         /* Set output pins 0x14-0x17 */
2467         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2468         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2469         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2470         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2471         /* Unmute output pins 0x14-0x17 */
2472         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2473         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2474         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2475         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2476         /* Set input pins 0x18-0x1c */
2477         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2478         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2479         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2480         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2481         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2482         /* Mute input pins 0x18-0x1b */
2483         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2484         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2485         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2486         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2487         /* ADC set up */
2488         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2489         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2490         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2491         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2492         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2493         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2494         /* Analog input/passthru */
2495         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2496         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2497         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2498         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2499         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2500         { }
2501 };
2502 #endif
2503
2504 /*
2505  */
2506
2507 static const char *alc880_models[ALC880_MODEL_LAST] = {
2508         [ALC880_3ST]            = "3stack",
2509         [ALC880_TCL_S700]       = "tcl",
2510         [ALC880_3ST_DIG]        = "3stack-digout",
2511         [ALC880_CLEVO]          = "clevo",
2512         [ALC880_5ST]            = "5stack",
2513         [ALC880_5ST_DIG]        = "5stack-digout",
2514         [ALC880_W810]           = "w810",
2515         [ALC880_Z71V]           = "z71v",
2516         [ALC880_6ST]            = "6stack",
2517         [ALC880_6ST_DIG]        = "6stack-digout",
2518         [ALC880_ASUS]           = "asus",
2519         [ALC880_ASUS_W1V]       = "asus-w1v",
2520         [ALC880_ASUS_DIG]       = "asus-dig",
2521         [ALC880_ASUS_DIG2]      = "asus-dig2",
2522         [ALC880_UNIWILL_DIG]    = "uniwill",
2523         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2524         [ALC880_FUJITSU]        = "fujitsu",
2525         [ALC880_F1734]          = "F1734",
2526         [ALC880_LG]             = "lg",
2527         [ALC880_LG_LW]          = "lg-lw",
2528 #ifdef CONFIG_SND_DEBUG
2529         [ALC880_TEST]           = "test",
2530 #endif
2531         [ALC880_AUTO]           = "auto",
2532 };
2533
2534 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2535         /* Broken BIOS configuration */
2536         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2537         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2538
2539         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2540         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2541         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2542         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2543         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2544         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2545         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2546         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2547         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2548
2549         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2550         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2551
2552         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2553         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2554         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2555         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2556         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2557         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2558         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2559         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2560         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2561         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2562         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2563         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2564         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2565         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2566         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2567
2568         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2569         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2570         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2571         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2572         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2573         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2574         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2575         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2576         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2577         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2578         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2579         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2580         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2581         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2582         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2583         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2584         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2585         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2586
2587         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2588         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2589         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2590         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2591
2592         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2593         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2594         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2595         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2596
2597         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2598         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2599         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2600         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2601
2602         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2603         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2604         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2605         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2606         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2607         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2608         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2609         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2610         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2611         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2612         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2613
2614         {}
2615 };
2616
2617 /*
2618  * ALC880 codec presets
2619  */
2620 static struct alc_config_preset alc880_presets[] = {
2621         [ALC880_3ST] = {
2622                 .mixers = { alc880_three_stack_mixer },
2623                 .init_verbs = { alc880_volume_init_verbs,
2624                                 alc880_pin_3stack_init_verbs },
2625                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2626                 .dac_nids = alc880_dac_nids,
2627                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2628                 .channel_mode = alc880_threestack_modes,
2629                 .need_dac_fix = 1,
2630                 .input_mux = &alc880_capture_source,
2631         },
2632         [ALC880_3ST_DIG] = {
2633                 .mixers = { alc880_three_stack_mixer },
2634                 .init_verbs = { alc880_volume_init_verbs,
2635                                 alc880_pin_3stack_init_verbs },
2636                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2637                 .dac_nids = alc880_dac_nids,
2638                 .dig_out_nid = ALC880_DIGOUT_NID,
2639                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2640                 .channel_mode = alc880_threestack_modes,
2641                 .need_dac_fix = 1,
2642                 .input_mux = &alc880_capture_source,
2643         },
2644         [ALC880_TCL_S700] = {
2645                 .mixers = { alc880_tcl_s700_mixer },
2646                 .init_verbs = { alc880_volume_init_verbs,
2647                                 alc880_pin_tcl_S700_init_verbs,
2648                                 alc880_gpio2_init_verbs },
2649                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2650                 .dac_nids = alc880_dac_nids,
2651                 .hp_nid = 0x03,
2652                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2653                 .channel_mode = alc880_2_jack_modes,
2654                 .input_mux = &alc880_capture_source,
2655         },
2656         [ALC880_5ST] = {
2657                 .mixers = { alc880_three_stack_mixer,
2658                             alc880_five_stack_mixer},
2659                 .init_verbs = { alc880_volume_init_verbs,
2660                                 alc880_pin_5stack_init_verbs },
2661                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2662                 .dac_nids = alc880_dac_nids,
2663                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2664                 .channel_mode = alc880_fivestack_modes,
2665                 .input_mux = &alc880_capture_source,
2666         },
2667         [ALC880_5ST_DIG] = {
2668                 .mixers = { alc880_three_stack_mixer,
2669                             alc880_five_stack_mixer },
2670                 .init_verbs = { alc880_volume_init_verbs,
2671                                 alc880_pin_5stack_init_verbs },
2672                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2673                 .dac_nids = alc880_dac_nids,
2674                 .dig_out_nid = ALC880_DIGOUT_NID,
2675                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2676                 .channel_mode = alc880_fivestack_modes,
2677                 .input_mux = &alc880_capture_source,
2678         },
2679         [ALC880_6ST] = {
2680                 .mixers = { alc880_six_stack_mixer },
2681                 .init_verbs = { alc880_volume_init_verbs,
2682                                 alc880_pin_6stack_init_verbs },
2683                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2684                 .dac_nids = alc880_6st_dac_nids,
2685                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2686                 .channel_mode = alc880_sixstack_modes,
2687                 .input_mux = &alc880_6stack_capture_source,
2688         },
2689         [ALC880_6ST_DIG] = {
2690                 .mixers = { alc880_six_stack_mixer },
2691                 .init_verbs = { alc880_volume_init_verbs,
2692                                 alc880_pin_6stack_init_verbs },
2693                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2694                 .dac_nids = alc880_6st_dac_nids,
2695                 .dig_out_nid = ALC880_DIGOUT_NID,
2696                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2697                 .channel_mode = alc880_sixstack_modes,
2698                 .input_mux = &alc880_6stack_capture_source,
2699         },
2700         [ALC880_W810] = {
2701                 .mixers = { alc880_w810_base_mixer },
2702                 .init_verbs = { alc880_volume_init_verbs,
2703                                 alc880_pin_w810_init_verbs,
2704                                 alc880_gpio2_init_verbs },
2705                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2706                 .dac_nids = alc880_w810_dac_nids,
2707                 .dig_out_nid = ALC880_DIGOUT_NID,
2708                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2709                 .channel_mode = alc880_w810_modes,
2710                 .input_mux = &alc880_capture_source,
2711         },
2712         [ALC880_Z71V] = {
2713                 .mixers = { alc880_z71v_mixer },
2714                 .init_verbs = { alc880_volume_init_verbs,
2715                                 alc880_pin_z71v_init_verbs },
2716                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2717                 .dac_nids = alc880_z71v_dac_nids,
2718                 .dig_out_nid = ALC880_DIGOUT_NID,
2719                 .hp_nid = 0x03,
2720                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2721                 .channel_mode = alc880_2_jack_modes,
2722                 .input_mux = &alc880_capture_source,
2723         },
2724         [ALC880_F1734] = {
2725                 .mixers = { alc880_f1734_mixer },
2726                 .init_verbs = { alc880_volume_init_verbs,
2727                                 alc880_pin_f1734_init_verbs },
2728                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2729                 .dac_nids = alc880_f1734_dac_nids,
2730                 .hp_nid = 0x02,
2731                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2732                 .channel_mode = alc880_2_jack_modes,
2733                 .input_mux = &alc880_capture_source,
2734         },
2735         [ALC880_ASUS] = {
2736                 .mixers = { alc880_asus_mixer },
2737                 .init_verbs = { alc880_volume_init_verbs,
2738                                 alc880_pin_asus_init_verbs,
2739                                 alc880_gpio1_init_verbs },
2740                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2741                 .dac_nids = alc880_asus_dac_nids,
2742                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2743                 .channel_mode = alc880_asus_modes,
2744                 .need_dac_fix = 1,
2745                 .input_mux = &alc880_capture_source,
2746         },
2747         [ALC880_ASUS_DIG] = {
2748                 .mixers = { alc880_asus_mixer },
2749                 .init_verbs = { alc880_volume_init_verbs,
2750                                 alc880_pin_asus_init_verbs,
2751                                 alc880_gpio1_init_verbs },
2752                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2753                 .dac_nids = alc880_asus_dac_nids,
2754                 .dig_out_nid = ALC880_DIGOUT_NID,
2755                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2756                 .channel_mode = alc880_asus_modes,
2757                 .need_dac_fix = 1,
2758                 .input_mux = &alc880_capture_source,
2759         },
2760         [ALC880_ASUS_DIG2] = {
2761                 .mixers = { alc880_asus_mixer },
2762                 .init_verbs = { alc880_volume_init_verbs,
2763                                 alc880_pin_asus_init_verbs,
2764                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2765                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2766                 .dac_nids = alc880_asus_dac_nids,
2767                 .dig_out_nid = ALC880_DIGOUT_NID,
2768                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2769                 .channel_mode = alc880_asus_modes,
2770                 .need_dac_fix = 1,
2771                 .input_mux = &alc880_capture_source,
2772         },
2773         [ALC880_ASUS_W1V] = {
2774                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2775                 .init_verbs = { alc880_volume_init_verbs,
2776                                 alc880_pin_asus_init_verbs,
2777                                 alc880_gpio1_init_verbs },
2778                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2779                 .dac_nids = alc880_asus_dac_nids,
2780                 .dig_out_nid = ALC880_DIGOUT_NID,
2781                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2782                 .channel_mode = alc880_asus_modes,
2783                 .need_dac_fix = 1,
2784                 .input_mux = &alc880_capture_source,
2785         },
2786         [ALC880_UNIWILL_DIG] = {
2787                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2788                 .init_verbs = { alc880_volume_init_verbs,
2789                                 alc880_pin_asus_init_verbs },
2790                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2791                 .dac_nids = alc880_asus_dac_nids,
2792                 .dig_out_nid = ALC880_DIGOUT_NID,
2793                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2794                 .channel_mode = alc880_asus_modes,
2795                 .need_dac_fix = 1,
2796                 .input_mux = &alc880_capture_source,
2797         },
2798         [ALC880_UNIWILL] = {
2799                 .mixers = { alc880_uniwill_mixer },
2800                 .init_verbs = { alc880_volume_init_verbs,
2801                                 alc880_uniwill_init_verbs },
2802                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2803                 .dac_nids = alc880_asus_dac_nids,
2804                 .dig_out_nid = ALC880_DIGOUT_NID,
2805                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2806                 .channel_mode = alc880_threestack_modes,
2807                 .need_dac_fix = 1,
2808                 .input_mux = &alc880_capture_source,
2809                 .unsol_event = alc880_uniwill_unsol_event,
2810                 .init_hook = alc880_uniwill_automute,
2811         },
2812         [ALC880_UNIWILL_P53] = {
2813                 .mixers = { alc880_uniwill_p53_mixer },
2814                 .init_verbs = { alc880_volume_init_verbs,
2815                                 alc880_uniwill_p53_init_verbs },
2816                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2817                 .dac_nids = alc880_asus_dac_nids,
2818                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2819                 .channel_mode = alc880_threestack_modes,
2820                 .input_mux = &alc880_capture_source,
2821                 .unsol_event = alc880_uniwill_p53_unsol_event,
2822                 .init_hook = alc880_uniwill_p53_hp_automute,
2823         },
2824         [ALC880_FUJITSU] = {
2825                 .mixers = { alc880_fujitsu_mixer,
2826                             alc880_pcbeep_mixer, },
2827                 .init_verbs = { alc880_volume_init_verbs,
2828                                 alc880_uniwill_p53_init_verbs,
2829                                 alc880_beep_init_verbs },
2830                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2831                 .dac_nids = alc880_dac_nids,
2832                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2833                 .channel_mode = alc880_2_jack_modes,
2834                 .input_mux = &alc880_capture_source,
2835                 .unsol_event = alc880_uniwill_p53_unsol_event,
2836                 .init_hook = alc880_uniwill_p53_hp_automute,
2837         },
2838         [ALC880_CLEVO] = {
2839                 .mixers = { alc880_three_stack_mixer },
2840                 .init_verbs = { alc880_volume_init_verbs,
2841                                 alc880_pin_clevo_init_verbs },
2842                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2843                 .dac_nids = alc880_dac_nids,
2844                 .hp_nid = 0x03,
2845                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2846                 .channel_mode = alc880_threestack_modes,
2847                 .need_dac_fix = 1,
2848                 .input_mux = &alc880_capture_source,
2849         },
2850         [ALC880_LG] = {
2851                 .mixers = { alc880_lg_mixer },
2852                 .init_verbs = { alc880_volume_init_verbs,
2853                                 alc880_lg_init_verbs },
2854                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2855                 .dac_nids = alc880_lg_dac_nids,
2856                 .dig_out_nid = ALC880_DIGOUT_NID,
2857                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2858                 .channel_mode = alc880_lg_ch_modes,
2859                 .need_dac_fix = 1,
2860                 .input_mux = &alc880_lg_capture_source,
2861                 .unsol_event = alc880_lg_unsol_event,
2862                 .init_hook = alc880_lg_automute,
2863         },
2864         [ALC880_LG_LW] = {
2865                 .mixers = { alc880_lg_lw_mixer },
2866                 .init_verbs = { alc880_volume_init_verbs,
2867                                 alc880_lg_lw_init_verbs },
2868                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2869                 .dac_nids = alc880_dac_nids,
2870                 .dig_out_nid = ALC880_DIGOUT_NID,
2871                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2872                 .channel_mode = alc880_lg_lw_modes,
2873                 .input_mux = &alc880_lg_lw_capture_source,
2874                 .unsol_event = alc880_lg_lw_unsol_event,
2875                 .init_hook = alc880_lg_lw_automute,
2876         },
2877 #ifdef CONFIG_SND_DEBUG
2878         [ALC880_TEST] = {
2879                 .mixers = { alc880_test_mixer },
2880                 .init_verbs = { alc880_test_init_verbs },
2881                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2882                 .dac_nids = alc880_test_dac_nids,
2883                 .dig_out_nid = ALC880_DIGOUT_NID,
2884                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2885                 .channel_mode = alc880_test_modes,
2886                 .input_mux = &alc880_test_capture_source,
2887         },
2888 #endif
2889 };
2890
2891 /*
2892  * Automatic parse of I/O pins from the BIOS configuration
2893  */
2894
2895 #define NUM_CONTROL_ALLOC       32
2896 #define NUM_VERB_ALLOC          32
2897
2898 enum {
2899         ALC_CTL_WIDGET_VOL,
2900         ALC_CTL_WIDGET_MUTE,
2901         ALC_CTL_BIND_MUTE,
2902 };
2903 static struct snd_kcontrol_new alc880_control_templates[] = {
2904         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2905         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2906         HDA_BIND_MUTE(NULL, 0, 0, 0),
2907 };
2908
2909 /* add dynamic controls */
2910 static int add_control(struct alc_spec *spec, int type, const char *name,
2911                        unsigned long val)
2912 {
2913         struct snd_kcontrol_new *knew;
2914
2915         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2916                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2917
2918                 /* array + terminator */
2919                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2920                 if (!knew)
2921                         return -ENOMEM;
2922                 if (spec->kctl_alloc) {
2923                         memcpy(knew, spec->kctl_alloc,
2924                                sizeof(*knew) * spec->num_kctl_alloc);
2925                         kfree(spec->kctl_alloc);
2926                 }
2927                 spec->kctl_alloc = knew;
2928                 spec->num_kctl_alloc = num;
2929         }
2930
2931         knew = &spec->kctl_alloc[spec->num_kctl_used];
2932         *knew = alc880_control_templates[type];
2933         knew->name = kstrdup(name, GFP_KERNEL);
2934         if (!knew->name)
2935                 return -ENOMEM;
2936         knew->private_value = val;
2937         spec->num_kctl_used++;
2938         return 0;
2939 }
2940
2941 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
2942 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
2943 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
2944 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
2945 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
2946 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
2947 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
2948 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
2949 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
2950 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
2951 #define ALC880_PIN_CD_NID               0x1c
2952
2953 /* fill in the dac_nids table from the parsed pin configuration */
2954 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
2955                                      const struct auto_pin_cfg *cfg)
2956 {
2957         hda_nid_t nid;
2958         int assigned[4];
2959         int i, j;
2960
2961         memset(assigned, 0, sizeof(assigned));
2962         spec->multiout.dac_nids = spec->private_dac_nids;
2963
2964         /* check the pins hardwired to audio widget */
2965         for (i = 0; i < cfg->line_outs; i++) {
2966                 nid = cfg->line_out_pins[i];
2967                 if (alc880_is_fixed_pin(nid)) {
2968                         int idx = alc880_fixed_pin_idx(nid);
2969                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
2970                         assigned[idx] = 1;
2971                 }
2972         }
2973         /* left pins can be connect to any audio widget */
2974         for (i = 0; i < cfg->line_outs; i++) {
2975                 nid = cfg->line_out_pins[i];
2976                 if (alc880_is_fixed_pin(nid))
2977                         continue;
2978                 /* search for an empty channel */
2979                 for (j = 0; j < cfg->line_outs; j++) {
2980                         if (!assigned[j]) {
2981                                 spec->multiout.dac_nids[i] =
2982                                         alc880_idx_to_dac(j);
2983                                 assigned[j] = 1;
2984                                 break;
2985                         }
2986                 }
2987         }
2988         spec->multiout.num_dacs = cfg->line_outs;
2989         return 0;
2990 }
2991
2992 /* add playback controls from the parsed DAC table */
2993 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
2994                                              const struct auto_pin_cfg *cfg)
2995 {
2996         char name[32];
2997         static const char *chname[4] = {
2998                 "Front", "Surround", NULL /*CLFE*/, "Side"
2999         };
3000         hda_nid_t nid;
3001         int i, err;
3002
3003         for (i = 0; i < cfg->line_outs; i++) {
3004                 if (!spec->multiout.dac_nids[i])
3005                         continue;
3006                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3007                 if (i == 2) {
3008                         /* Center/LFE */
3009                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3010                                           "Center Playback Volume",
3011                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3012                                                               HDA_OUTPUT));
3013                         if (err < 0)
3014                                 return err;
3015                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3016                                           "LFE Playback Volume",
3017                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3018                                                               HDA_OUTPUT));
3019                         if (err < 0)
3020                                 return err;
3021                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3022                                           "Center Playback Switch",
3023                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3024                                                               HDA_INPUT));
3025                         if (err < 0)
3026                                 return err;
3027                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3028                                           "LFE Playback Switch",
3029                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3030                                                               HDA_INPUT));
3031                         if (err < 0)
3032                                 return err;
3033                 } else {
3034                         sprintf(name, "%s Playback Volume", chname[i]);
3035                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3036                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3037                                                               HDA_OUTPUT));
3038                         if (err < 0)
3039                                 return err;
3040                         sprintf(name, "%s Playback Switch", chname[i]);
3041                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3042                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3043                                                               HDA_INPUT));
3044                         if (err < 0)
3045                                 return err;
3046                 }
3047         }
3048         return 0;
3049 }
3050
3051 /* add playback controls for speaker and HP outputs */
3052 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3053                                         const char *pfx)
3054 {
3055         hda_nid_t nid;
3056         int err;
3057         char name[32];
3058
3059         if (!pin)
3060                 return 0;
3061
3062         if (alc880_is_fixed_pin(pin)) {
3063                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3064                 /* specify the DAC as the extra output */
3065                 if (!spec->multiout.hp_nid)
3066                         spec->multiout.hp_nid = nid;
3067                 else
3068                         spec->multiout.extra_out_nid[0] = nid;
3069                 /* control HP volume/switch on the output mixer amp */
3070                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3071                 sprintf(name, "%s Playback Volume", pfx);
3072                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3073                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3074                 if (err < 0)
3075                         return err;
3076                 sprintf(name, "%s Playback Switch", pfx);
3077                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3078                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3079                 if (err < 0)
3080                         return err;
3081         } else if (alc880_is_multi_pin(pin)) {
3082                 /* set manual connection */
3083                 /* we have only a switch on HP-out PIN */
3084                 sprintf(name, "%s Playback Switch", pfx);
3085                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3086                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3087                 if (err < 0)
3088                         return err;
3089         }
3090         return 0;
3091 }
3092
3093 /* create input playback/capture controls for the given pin */
3094 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3095                             const char *ctlname,
3096                             int idx, hda_nid_t mix_nid)
3097 {
3098         char name[32];
3099         int err;
3100
3101         sprintf(name, "%s Playback Volume", ctlname);
3102         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3103                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3104         if (err < 0)
3105                 return err;
3106         sprintf(name, "%s Playback Switch", ctlname);
3107         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3108                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3109         if (err < 0)
3110                 return err;
3111         return 0;
3112 }
3113
3114 /* create playback/capture controls for input pins */
3115 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3116                                                 const struct auto_pin_cfg *cfg)
3117 {
3118         struct hda_input_mux *imux = &spec->private_imux;
3119         int i, err, idx;
3120
3121         for (i = 0; i < AUTO_PIN_LAST; i++) {
3122                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3123                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3124                         err = new_analog_input(spec, cfg->input_pins[i],
3125                                                auto_pin_cfg_labels[i],
3126                                                idx, 0x0b);
3127                         if (err < 0)
3128                                 return err;
3129                         imux->items[imux->num_items].label =
3130                                 auto_pin_cfg_labels[i];
3131                         imux->items[imux->num_items].index =
3132                                 alc880_input_pin_idx(cfg->input_pins[i]);
3133                         imux->num_items++;
3134                 }
3135         }
3136         return 0;
3137 }
3138
3139 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3140                                               hda_nid_t nid, int pin_type,
3141                                               int dac_idx)
3142 {
3143         /* set as output */
3144         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3145                             pin_type);
3146         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3147                             AMP_OUT_UNMUTE);
3148         /* need the manual connection? */
3149         if (alc880_is_multi_pin(nid)) {
3150                 struct alc_spec *spec = codec->spec;
3151                 int idx = alc880_multi_pin_idx(nid);
3152                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3153                                     AC_VERB_SET_CONNECT_SEL,
3154                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3155         }
3156 }
3157
3158 static int get_pin_type(int line_out_type)
3159 {
3160         if (line_out_type == AUTO_PIN_HP_OUT)
3161                 return PIN_HP;
3162         else
3163                 return PIN_OUT;
3164 }
3165
3166 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3167 {
3168         struct alc_spec *spec = codec->spec;
3169         int i;
3170         
3171         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3172         for (i = 0; i < spec->autocfg.line_outs; i++) {
3173                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3174                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3175                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3176         }
3177 }
3178
3179 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3180 {
3181         struct alc_spec *spec = codec->spec;
3182         hda_nid_t pin;
3183
3184         pin = spec->autocfg.speaker_pins[0];
3185         if (pin) /* connect to front */
3186                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3187         pin = spec->autocfg.hp_pins[0];
3188         if (pin) /* connect to front */
3189                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3190 }
3191
3192 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3193 {
3194         struct alc_spec *spec = codec->spec;
3195         int i;
3196
3197         for (i = 0; i < AUTO_PIN_LAST; i++) {
3198                 hda_nid_t nid = spec->autocfg.input_pins[i];
3199                 if (alc880_is_input_pin(nid)) {
3200                         snd_hda_codec_write(codec, nid, 0,
3201                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3202                                             i <= AUTO_PIN_FRONT_MIC ?
3203                                             PIN_VREF80 : PIN_IN);
3204                         if (nid != ALC880_PIN_CD_NID)
3205                                 snd_hda_codec_write(codec, nid, 0,
3206                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3207                                                     AMP_OUT_MUTE);
3208                 }
3209         }
3210 }
3211
3212 /* parse the BIOS configuration and set up the alc_spec */
3213 /* return 1 if successful, 0 if the proper config is not found,
3214  * or a negative error code
3215  */
3216 static int alc880_parse_auto_config(struct hda_codec *codec)
3217 {
3218         struct alc_spec *spec = codec->spec;
3219         int err;
3220         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3221
3222         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3223                                            alc880_ignore);
3224         if (err < 0)
3225                 return err;
3226         if (!spec->autocfg.line_outs)
3227                 return 0; /* can't find valid BIOS pin config */
3228
3229         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3230         if (err < 0)
3231                 return err;
3232         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3233         if (err < 0)
3234                 return err;
3235         err = alc880_auto_create_extra_out(spec,
3236                                            spec->autocfg.speaker_pins[0],
3237                                            "Speaker");
3238         if (err < 0)
3239                 return err;
3240         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3241                                            "Headphone");
3242         if (err < 0)
3243                 return err;
3244         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3245         if (err < 0)
3246                 return err;
3247
3248         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3249
3250         if (spec->autocfg.dig_out_pin)
3251                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3252         if (spec->autocfg.dig_in_pin)
3253                 spec->dig_in_nid = ALC880_DIGIN_NID;
3254
3255         if (spec->kctl_alloc)
3256                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3257
3258         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3259
3260         spec->num_mux_defs = 1;
3261         spec->input_mux = &spec->private_imux;
3262
3263         return 1;
3264 }
3265
3266 /* additional initialization for auto-configuration model */
3267 static void alc880_auto_init(struct hda_codec *codec)
3268 {
3269         alc880_auto_init_multi_out(codec);
3270         alc880_auto_init_extra_out(codec);
3271         alc880_auto_init_analog_input(codec);
3272 }
3273
3274 /*
3275  * OK, here we have finally the patch for ALC880
3276  */
3277
3278 static int patch_alc880(struct hda_codec *codec)
3279 {
3280         struct alc_spec *spec;
3281         int board_config;
3282         int err;
3283
3284         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3285         if (spec == NULL)
3286                 return -ENOMEM;
3287
3288         codec->spec = spec;
3289
3290         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3291                                                   alc880_models,
3292                                                   alc880_cfg_tbl);
3293         if (board_config < 0) {
3294                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3295                        "trying auto-probe from BIOS...\n");
3296                 board_config = ALC880_AUTO;
3297         }
3298
3299         if (board_config == ALC880_AUTO) {
3300                 /* automatic parse from the BIOS config */
3301                 err = alc880_parse_auto_config(codec);
3302                 if (err < 0) {
3303                         alc_free(codec);
3304                         return err;
3305                 } else if (!err) {
3306                         printk(KERN_INFO
3307                                "hda_codec: Cannot set up configuration "
3308                                "from BIOS.  Using 3-stack mode...\n");
3309                         board_config = ALC880_3ST;
3310                 }
3311         }
3312
3313         if (board_config != ALC880_AUTO)
3314                 setup_preset(spec, &alc880_presets[board_config]);
3315
3316         spec->stream_name_analog = "ALC880 Analog";
3317         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3318         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3319
3320         spec->stream_name_digital = "ALC880 Digital";
3321         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3322         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3323
3324         if (!spec->adc_nids && spec->input_mux) {
3325                 /* check whether NID 0x07 is valid */
3326                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3327                 /* get type */
3328                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3329                 if (wcap != AC_WID_AUD_IN) {
3330                         spec->adc_nids = alc880_adc_nids_alt;
3331                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3332                         spec->mixers[spec->num_mixers] =
3333                                 alc880_capture_alt_mixer;
3334                         spec->num_mixers++;
3335                 } else {
3336                         spec->adc_nids = alc880_adc_nids;
3337                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3338                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3339                         spec->num_mixers++;
3340                 }
3341         }
3342
3343         codec->patch_ops = alc_patch_ops;
3344         if (board_config == ALC880_AUTO)
3345                 spec->init_hook = alc880_auto_init;
3346
3347         return 0;
3348 }
3349
3350
3351 /*
3352  * ALC260 support
3353  */
3354
3355 static hda_nid_t alc260_dac_nids[1] = {
3356         /* front */
3357         0x02,
3358 };
3359
3360 static hda_nid_t alc260_adc_nids[1] = {
3361         /* ADC0 */
3362         0x04,
3363 };
3364
3365 static hda_nid_t alc260_adc_nids_alt[1] = {
3366         /* ADC1 */
3367         0x05,
3368 };
3369
3370 static hda_nid_t alc260_hp_adc_nids[2] = {
3371         /* ADC1, 0 */
3372         0x05, 0x04
3373 };
3374
3375 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3376  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3377  */
3378 static hda_nid_t alc260_dual_adc_nids[2] = {
3379         /* ADC0, ADC1 */
3380         0x04, 0x05
3381 };
3382
3383 #define ALC260_DIGOUT_NID       0x03
3384 #define ALC260_DIGIN_NID        0x06
3385
3386 static struct hda_input_mux alc260_capture_source = {
3387         .num_items = 4,
3388         .items = {
3389                 { "Mic", 0x0 },
3390                 { "Front Mic", 0x1 },
3391                 { "Line", 0x2 },
3392                 { "CD", 0x4 },
3393         },
3394 };
3395
3396 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3397  * headphone jack and the internal CD lines since these are the only pins at
3398  * which audio can appear.  For flexibility, also allow the option of
3399  * recording the mixer output on the second ADC (ADC0 doesn't have a
3400  * connection to the mixer output).
3401  */
3402 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3403         {
3404                 .num_items = 3,
3405                 .items = {
3406                         { "Mic/Line", 0x0 },
3407                         { "CD", 0x4 },
3408                         { "Headphone", 0x2 },
3409                 },
3410         },
3411         {
3412                 .num_items = 4,
3413                 .items = {
3414                         { "Mic/Line", 0x0 },
3415                         { "CD", 0x4 },
3416                         { "Headphone", 0x2 },
3417                         { "Mixer", 0x5 },
3418                 },
3419         },
3420
3421 };
3422
3423 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3424  * the Fujitsu S702x, but jacks are marked differently.
3425  */
3426 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3427         {
3428                 .num_items = 4,
3429                 .items = {
3430                         { "Mic", 0x0 },
3431                         { "Line", 0x2 },
3432                         { "CD", 0x4 },
3433                         { "Headphone", 0x5 },
3434                 },
3435         },
3436         {
3437                 .num_items = 5,
3438                 .items = {
3439                         { "Mic", 0x0 },
3440                         { "Line", 0x2 },
3441                         { "CD", 0x4 },
3442                         { "Headphone", 0x6 },
3443                         { "Mixer", 0x5 },
3444                 },
3445         },
3446 };
3447 /*
3448  * This is just place-holder, so there's something for alc_build_pcms to look
3449  * at when it calculates the maximum number of channels. ALC260 has no mixer
3450  * element which allows changing the channel mode, so the verb list is
3451  * never used.
3452  */
3453 static struct hda_channel_mode alc260_modes[1] = {
3454         { 2, NULL },
3455 };
3456
3457
3458 /* Mixer combinations
3459  *
3460  * basic: base_output + input + pc_beep + capture
3461  * HP: base_output + input + capture_alt
3462  * HP_3013: hp_3013 + input + capture
3463  * fujitsu: fujitsu + capture
3464  * acer: acer + capture
3465  */
3466
3467 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3468         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3469         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3470         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3471         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3472         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3473         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3474         { } /* end */
3475 };
3476
3477 static struct snd_kcontrol_new alc260_input_mixer[] = {
3478         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3479         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3480         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3481         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3482         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3483         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3484         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3485         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3486         { } /* end */
3487 };
3488
3489 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3490         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3491         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3492         { } /* end */
3493 };
3494
3495 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3496         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3497         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3498         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3499         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3500         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3501         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3502         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3503         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3504         { } /* end */
3505 };
3506
3507 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3508  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3509  */
3510 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3511         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3512         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3513         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3514         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3515         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3516         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3517         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3518         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3519         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3520         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3521         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3522         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3523         { } /* end */
3524 };
3525
3526 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3527  * versions of the ALC260 don't act on requests to enable mic bias from NID
3528  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3529  * datasheet doesn't mention this restriction.  At this stage it's not clear
3530  * whether this behaviour is intentional or is a hardware bug in chip
3531  * revisions available in early 2006.  Therefore for now allow the
3532  * "Headphone Jack Mode" control to span all choices, but if it turns out
3533  * that the lack of mic bias for this NID is intentional we could change the
3534  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3535  *
3536  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3537  * don't appear to make the mic bias available from the "line" jack, even
3538  * though the NID used for this jack (0x14) can supply it.  The theory is
3539  * that perhaps Acer have included blocking capacitors between the ALC260
3540  * and the output jack.  If this turns out to be the case for all such
3541  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3542  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3543  *
3544  * The C20x Tablet series have a mono internal speaker which is controlled
3545  * via the chip's Mono sum widget and pin complex, so include the necessary
3546  * controls for such models.  On models without a "mono speaker" the control
3547  * won't do anything.
3548  */
3549 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3550         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3551         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3552         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3553         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3554                               HDA_OUTPUT),
3555         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3556                            HDA_INPUT),
3557         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3558         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3559         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3560         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3561         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3562         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3563         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3564         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3565         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3566         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3567         { } /* end */
3568 };
3569
3570 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3571  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3572  */
3573 static struct snd_kcontrol_new alc260_will_mixer[] = {
3574         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3575         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3576         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3577         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3578         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3579         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3580         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3581         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3582         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3583         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3584         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3585         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3586         { } /* end */
3587 };
3588
3589 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3590  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3591  */
3592 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3593         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3594         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3595         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3596         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3597         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3598         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3599         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3600         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3601         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3602         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3603         { } /* end */
3604 };
3605
3606 /* capture mixer elements */
3607 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3608         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3609         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3610         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3611         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3612         {
3613                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3614                 /* The multiple "Capture Source" controls confuse alsamixer
3615                  * So call somewhat different..
3616                  * FIXME: the controls appear in the "playback" view!
3617                  */
3618                 /* .name = "Capture Source", */
3619                 .name = "Input Source",
3620                 .count = 2,
3621                 .info = alc_mux_enum_info,
3622                 .get = alc_mux_enum_get,
3623                 .put = alc_mux_enum_put,
3624         },
3625         { } /* end */
3626 };
3627
3628 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3629         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3630         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3631         {
3632                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3633                 /* The multiple "Capture Source" controls confuse alsamixer
3634                  * So call somewhat different..
3635                  * FIXME: the controls appear in the "playback" view!
3636                  */
3637                 /* .name = "Capture Source", */
3638                 .name = "Input Source",
3639                 .count = 1,
3640                 .info = alc_mux_enum_info,
3641                 .get = alc_mux_enum_get,
3642                 .put = alc_mux_enum_put,
3643         },
3644         { } /* end */
3645 };
3646
3647 /*
3648  * initialization verbs
3649  */
3650 static struct hda_verb alc260_init_verbs[] = {
3651         /* Line In pin widget for input */
3652         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3653         /* CD pin widget for input */
3654         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3655         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3656         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3657         /* Mic2 (front panel) pin widget for input and vref at 80% */
3658         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3659         /* LINE-2 is used for line-out in rear */
3660         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3661         /* select line-out */
3662         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3663         /* LINE-OUT pin */
3664         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3665         /* enable HP */
3666         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3667         /* enable Mono */
3668         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3669         /* mute capture amp left and right */
3670         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3671         /* set connection select to line in (default select for this ADC) */
3672         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3673         /* mute capture amp left and right */
3674         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3675         /* set connection select to line in (default select for this ADC) */
3676         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3677         /* set vol=0 Line-Out mixer amp left and right */
3678         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3679         /* unmute pin widget amp left and right (no gain on this amp) */
3680         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3681         /* set vol=0 HP mixer amp left and right */
3682         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3683         /* unmute pin widget amp left and right (no gain on this amp) */
3684         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3685         /* set vol=0 Mono mixer amp left and right */
3686         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3687         /* unmute pin widget amp left and right (no gain on this amp) */
3688         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3689         /* unmute LINE-2 out pin */
3690         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3691         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3692          * Line In 2 = 0x03
3693          */
3694         /* mute CD */
3695         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3696         /* mute Line In */
3697         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3698         /* mute Mic */
3699         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3700         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3701         /* mute Front out path */
3702         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3703         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3704         /* mute Headphone out path */
3705         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3706         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3707         /* mute Mono out path */
3708         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3709         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3710         { }
3711 };
3712
3713 #if 0 /* should be identical with alc260_init_verbs? */
3714 static struct hda_verb alc260_hp_init_verbs[] = {
3715         /* Headphone and output */
3716         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3717         /* mono output */
3718         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3719         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3720         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3721         /* Mic2 (front panel) pin widget for input and vref at 80% */
3722         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3723         /* Line In pin widget for input */
3724         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3725         /* Line-2 pin widget for output */
3726         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3727         /* CD pin widget for input */
3728         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3729         /* unmute amp left and right */
3730         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3731         /* set connection select to line in (default select for this ADC) */
3732         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3733         /* unmute Line-Out mixer amp left and right (volume = 0) */
3734         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3735         /* mute pin widget amp left and right (no gain on this amp) */
3736         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3737         /* unmute HP mixer amp left and right (volume = 0) */
3738         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3739         /* mute pin widget amp left and right (no gain on this amp) */
3740         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3741         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3742          * Line In 2 = 0x03
3743          */
3744         /* unmute CD */
3745         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3746         /* unmute Line In */
3747         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3748         /* unmute Mic */
3749         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3750         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3751         /* Unmute Front out path */
3752         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3753         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3754         /* Unmute Headphone out path */
3755         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3756         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3757         /* Unmute Mono out path */
3758         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3759         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3760         { }
3761 };
3762 #endif
3763
3764 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3765         /* Line out and output */
3766         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3767         /* mono output */
3768         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3769         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3770         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3771         /* Mic2 (front panel) pin widget for input and vref at 80% */
3772         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3773         /* Line In pin widget for input */
3774         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3775         /* Headphone pin widget for output */
3776         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3777         /* CD pin widget for input */
3778         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3779         /* unmute amp left and right */
3780         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3781         /* set connection select to line in (default select for this ADC) */
3782         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3783         /* unmute Line-Out mixer amp left and right (volume = 0) */
3784         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3785         /* mute pin widget amp left and right (no gain on this amp) */
3786         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3787         /* unmute HP mixer amp left and right (volume = 0) */
3788         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3789         /* mute pin widget amp left and right (no gain on this amp) */
3790         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3791         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3792          * Line In 2 = 0x03
3793          */
3794         /* unmute CD */
3795         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3796         /* unmute Line In */
3797         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3798         /* unmute Mic */
3799         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3800         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3801         /* Unmute Front out path */
3802         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3803         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3804         /* Unmute Headphone out path */
3805         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3806         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3807         /* Unmute Mono out path */
3808         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3809         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3810         { }
3811 };
3812
3813 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3814  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3815  * audio = 0x16, internal speaker = 0x10.
3816  */
3817 static struct hda_verb alc260_fujitsu_init_verbs[] = {
3818         /* Disable all GPIOs */
3819         {0x01, AC_VERB_SET_GPIO_MASK, 0},
3820         /* Internal speaker is connected to headphone pin */
3821         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3822         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3823         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3824         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3825         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3826         /* Ensure all other unused pins are disabled and muted. */
3827         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3828         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3829         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3830         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3831         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3832         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3833         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3834         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3835
3836         /* Disable digital (SPDIF) pins */
3837         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3838         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3839
3840         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
3841          * when acting as an output.
3842          */
3843         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3844
3845         /* Start with output sum widgets muted and their output gains at min */
3846         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3847         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3848         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3849         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3850         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3851         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3852         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3853         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3854         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3855
3856         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3857         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3858         /* Unmute Line1 pin widget output buffer since it starts as an output.
3859          * If the pin mode is changed by the user the pin mode control will
3860          * take care of enabling the pin's input/output buffers as needed.
3861          * Therefore there's no need to enable the input buffer at this
3862          * stage.
3863          */
3864         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3865         /* Unmute input buffer of pin widget used for Line-in (no equiv 
3866          * mixer ctrl)
3867          */
3868         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3869
3870         /* Mute capture amp left and right */
3871         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3872         /* Set ADC connection select to match default mixer setting - line 
3873          * in (on mic1 pin)
3874          */
3875         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3876
3877         /* Do the same for the second ADC: mute capture input amp and
3878          * set ADC connection to line in (on mic1 pin)
3879          */
3880         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3881         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3882
3883         /* Mute all inputs to mixer widget (even unconnected ones) */
3884         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3885         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3886         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3887         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3888         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3889         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3890         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3891         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3892
3893         { }
3894 };
3895
3896 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3897  * similar laptops (adapted from Fujitsu init verbs).
3898  */
3899 static struct hda_verb alc260_acer_init_verbs[] = {
3900         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3901          * the headphone jack.  Turn this on and rely on the standard mute
3902          * methods whenever the user wants to turn these outputs off.
3903          */
3904         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3905         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3906         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3907         /* Internal speaker/Headphone jack is connected to Line-out pin */
3908         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3909         /* Internal microphone/Mic jack is connected to Mic1 pin */
3910         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3911         /* Line In jack is connected to Line1 pin */
3912         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3913         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3914         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3915         /* Ensure all other unused pins are disabled and muted. */
3916         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3917         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3918         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3919         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3920         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3921         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3922         /* Disable digital (SPDIF) pins */
3923         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3924         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3925
3926         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
3927          * bus when acting as outputs.
3928          */
3929         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3930         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3931
3932         /* Start with output sum widgets muted and their output gains at min */
3933         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3934         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3935         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3936         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3937         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3938         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3939         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3940         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3941         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3942
3943         /* Unmute Line-out pin widget amp left and right
3944          * (no equiv mixer ctrl)
3945          */
3946         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3947         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3948         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3949         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3950          * inputs. If the pin mode is changed by the user the pin mode control
3951          * will take care of enabling the pin's input/output buffers as needed.
3952          * Therefore there's no need to enable the input buffer at this
3953          * stage.
3954          */
3955         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3956         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3957
3958         /* Mute capture amp left and right */
3959         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3960         /* Set ADC connection select to match default mixer setting - mic
3961          * (on mic1 pin)
3962          */
3963         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3964
3965         /* Do similar with the second ADC: mute capture input amp and
3966          * set ADC connection to mic to match ALSA's default state.
3967          */
3968         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3969         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3970
3971         /* Mute all inputs to mixer widget (even unconnected ones) */
3972         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3973         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3974         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3975         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3976         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3977         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3978         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3979         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3980
3981         { }
3982 };
3983
3984 static struct hda_verb alc260_will_verbs[] = {
3985         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3986         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
3987         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
3988         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3989         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
3990         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
3991         {}
3992 };
3993
3994 static struct hda_verb alc260_replacer_672v_verbs[] = {
3995         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3996         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
3997         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
3998
3999         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4000         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4001         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4002
4003         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4004         {}
4005 };
4006
4007 /* toggle speaker-output according to the hp-jack state */
4008 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4009 {
4010         unsigned int present;
4011
4012         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4013         present = snd_hda_codec_read(codec, 0x0f, 0,
4014                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4015         if (present) {
4016                 snd_hda_codec_write_cache(codec, 0x01, 0,
4017                                           AC_VERB_SET_GPIO_DATA, 1);
4018                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4019                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4020                                           PIN_HP);
4021         } else {
4022                 snd_hda_codec_write_cache(codec, 0x01, 0,
4023                                           AC_VERB_SET_GPIO_DATA, 0);
4024                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4025                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4026                                           PIN_OUT);
4027         }
4028 }
4029
4030 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4031                                        unsigned int res)
4032 {
4033         if ((res >> 26) == ALC880_HP_EVENT)
4034                 alc260_replacer_672v_automute(codec);
4035 }
4036
4037 /* Test configuration for debugging, modelled after the ALC880 test
4038  * configuration.
4039  */
4040 #ifdef CONFIG_SND_DEBUG
4041 static hda_nid_t alc260_test_dac_nids[1] = {
4042         0x02,
4043 };
4044 static hda_nid_t alc260_test_adc_nids[2] = {
4045         0x04, 0x05,
4046 };
4047 /* For testing the ALC260, each input MUX needs its own definition since
4048  * the signal assignments are different.  This assumes that the first ADC 
4049  * is NID 0x04.
4050  */
4051 static struct hda_input_mux alc260_test_capture_sources[2] = {
4052         {
4053                 .num_items = 7,
4054                 .items = {
4055                         { "MIC1 pin", 0x0 },
4056                         { "MIC2 pin", 0x1 },
4057                         { "LINE1 pin", 0x2 },
4058                         { "LINE2 pin", 0x3 },
4059                         { "CD pin", 0x4 },
4060                         { "LINE-OUT pin", 0x5 },
4061                         { "HP-OUT pin", 0x6 },
4062                 },
4063         },
4064         {
4065                 .num_items = 8,
4066                 .items = {
4067                         { "MIC1 pin", 0x0 },
4068                         { "MIC2 pin", 0x1 },
4069                         { "LINE1 pin", 0x2 },
4070                         { "LINE2 pin", 0x3 },
4071                         { "CD pin", 0x4 },
4072                         { "Mixer", 0x5 },
4073                         { "LINE-OUT pin", 0x6 },
4074                         { "HP-OUT pin", 0x7 },
4075                 },
4076         },
4077 };
4078 static struct snd_kcontrol_new alc260_test_mixer[] = {
4079         /* Output driver widgets */
4080         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4081         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4082         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4083         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4084         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4085         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4086
4087         /* Modes for retasking pin widgets
4088          * Note: the ALC260 doesn't seem to act on requests to enable mic
4089          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4090          * mention this restriction.  At this stage it's not clear whether
4091          * this behaviour is intentional or is a hardware bug in chip
4092          * revisions available at least up until early 2006.  Therefore for
4093          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4094          * choices, but if it turns out that the lack of mic bias for these
4095          * NIDs is intentional we could change their modes from
4096          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4097          */
4098         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4099         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4100         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4101         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4102         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4103         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4104
4105         /* Loopback mixer controls */
4106         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4107         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4108         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4109         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4110         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4111         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4112         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4113         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4114         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4115         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4116         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4117         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4118         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4119         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4120         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4121         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4122
4123         /* Controls for GPIO pins, assuming they are configured as outputs */
4124         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4125         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4126         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4127         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4128
4129         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4130          * is ambigious as to which NID is which; testing on laptops which
4131          * make this output available should provide clarification. 
4132          */
4133         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4134         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4135
4136         { } /* end */
4137 };
4138 static struct hda_verb alc260_test_init_verbs[] = {
4139         /* Enable all GPIOs as outputs with an initial value of 0 */
4140         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4141         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4142         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4143
4144         /* Enable retasking pins as output, initially without power amp */
4145         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4146         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4147         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4148         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4149         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4150         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4151
4152         /* Disable digital (SPDIF) pins initially, but users can enable
4153          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4154          * payload also sets the generation to 0, output to be in "consumer"
4155          * PCM format, copyright asserted, no pre-emphasis and no validity
4156          * control.
4157          */
4158         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4159         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4160
4161         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4162          * OUT1 sum bus when acting as an output.
4163          */
4164         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4165         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4166         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4167         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4168
4169         /* Start with output sum widgets muted and their output gains at min */
4170         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4171         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4172         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4173         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4174         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4175         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4176         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4177         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4178         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4179
4180         /* Unmute retasking pin widget output buffers since the default
4181          * state appears to be output.  As the pin mode is changed by the
4182          * user the pin mode control will take care of enabling the pin's
4183          * input/output buffers as needed.
4184          */
4185         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4186         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4187         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4188         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4189         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4190         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4191         /* Also unmute the mono-out pin widget */
4192         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4193
4194         /* Mute capture amp left and right */
4195         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4196         /* Set ADC connection select to match default mixer setting (mic1
4197          * pin)
4198          */
4199         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4200
4201         /* Do the same for the second ADC: mute capture input amp and
4202          * set ADC connection to mic1 pin
4203          */
4204         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4205         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4206
4207         /* Mute all inputs to mixer widget (even unconnected ones) */
4208         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4209         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4210         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4211         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4212         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4213         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4214         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4215         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4216
4217         { }
4218 };
4219 #endif
4220
4221 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4222         .substreams = 1,
4223         .channels_min = 2,
4224         .channels_max = 2,
4225 };
4226
4227 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4228         .substreams = 1,
4229         .channels_min = 2,
4230         .channels_max = 2,
4231 };
4232
4233 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4234 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4235
4236 /*
4237  * for BIOS auto-configuration
4238  */
4239
4240 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4241                                         const char *pfx)
4242 {
4243         hda_nid_t nid_vol;
4244         unsigned long vol_val, sw_val;
4245         char name[32];
4246         int err;
4247
4248         if (nid >= 0x0f && nid < 0x11) {
4249                 nid_vol = nid - 0x7;
4250                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4251                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4252         } else if (nid == 0x11) {
4253                 nid_vol = nid - 0x7;
4254                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4255                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4256         } else if (nid >= 0x12 && nid <= 0x15) {
4257                 nid_vol = 0x08;
4258                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4259                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4260         } else
4261                 return 0; /* N/A */
4262         
4263         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4264         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4265         if (err < 0)
4266                 return err;
4267         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4268         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4269         if (err < 0)
4270                 return err;
4271         return 1;
4272 }
4273
4274 /* add playback controls from the parsed DAC table */
4275 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4276                                              const struct auto_pin_cfg *cfg)
4277 {
4278         hda_nid_t nid;
4279         int err;
4280
4281         spec->multiout.num_dacs = 1;
4282         spec->multiout.dac_nids = spec->private_dac_nids;
4283         spec->multiout.dac_nids[0] = 0x02;
4284
4285         nid = cfg->line_out_pins[0];
4286         if (nid) {
4287                 err = alc260_add_playback_controls(spec, nid, "Front");
4288                 if (err < 0)
4289                         return err;
4290         }
4291
4292         nid = cfg->speaker_pins[0];
4293         if (nid) {
4294                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4295                 if (err < 0)
4296                         return err;
4297         }
4298
4299         nid = cfg->hp_pins[0];
4300         if (nid) {
4301                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4302                 if (err < 0)
4303                         return err;
4304         }
4305         return 0;
4306 }
4307
4308 /* create playback/capture controls for input pins */
4309 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4310                                                 const struct auto_pin_cfg *cfg)
4311 {
4312         struct hda_input_mux *imux = &spec->private_imux;
4313         int i, err, idx;
4314
4315         for (i = 0; i < AUTO_PIN_LAST; i++) {
4316                 if (cfg->input_pins[i] >= 0x12) {
4317                         idx = cfg->input_pins[i] - 0x12;
4318                         err = new_analog_input(spec, cfg->input_pins[i],
4319                                                auto_pin_cfg_labels[i], idx,
4320                                                0x07);
4321                         if (err < 0)
4322                                 return err;
4323                         imux->items[imux->num_items].label =
4324                                 auto_pin_cfg_labels[i];
4325                         imux->items[imux->num_items].index = idx;
4326                         imux->num_items++;
4327                 }
4328                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4329                         idx = cfg->input_pins[i] - 0x09;
4330                         err = new_analog_input(spec, cfg->input_pins[i],
4331                                                auto_pin_cfg_labels[i], idx,
4332                                                0x07);
4333                         if (err < 0)
4334                                 return err;
4335                         imux->items[imux->num_items].label =
4336                                 auto_pin_cfg_labels[i];
4337                         imux->items[imux->num_items].index = idx;
4338                         imux->num_items++;
4339                 }
4340         }
4341         return 0;
4342 }
4343
4344 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4345                                               hda_nid_t nid, int pin_type,
4346                                               int sel_idx)
4347 {
4348         /* set as output */
4349         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4350                             pin_type);
4351         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4352                             AMP_OUT_UNMUTE);
4353         /* need the manual connection? */
4354         if (nid >= 0x12) {
4355                 int idx = nid - 0x12;
4356                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4357                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4358         }
4359 }
4360
4361 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4362 {
4363         struct alc_spec *spec = codec->spec;
4364         hda_nid_t nid;
4365
4366         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4367         nid = spec->autocfg.line_out_pins[0];
4368         if (nid) {
4369                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4370                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4371         }
4372         
4373         nid = spec->autocfg.speaker_pins[0];
4374         if (nid)
4375                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4376
4377         nid = spec->autocfg.hp_pins[0];
4378         if (nid)
4379                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4380 }
4381
4382 #define ALC260_PIN_CD_NID               0x16
4383 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4384 {
4385         struct alc_spec *spec = codec->spec;
4386         int i;
4387
4388         for (i = 0; i < AUTO_PIN_LAST; i++) {
4389                 hda_nid_t nid = spec->autocfg.input_pins[i];
4390                 if (nid >= 0x12) {
4391                         snd_hda_codec_write(codec, nid, 0,
4392                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4393                                             i <= AUTO_PIN_FRONT_MIC ?
4394                                             PIN_VREF80 : PIN_IN);
4395                         if (nid != ALC260_PIN_CD_NID)
4396                                 snd_hda_codec_write(codec, nid, 0,
4397                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4398                                                     AMP_OUT_MUTE);
4399                 }
4400         }
4401 }
4402
4403 /*
4404  * generic initialization of ADC, input mixers and output mixers
4405  */
4406 static struct hda_verb alc260_volume_init_verbs[] = {
4407         /*
4408          * Unmute ADC0-1 and set the default input to mic-in
4409          */
4410         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4411         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4412         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4413         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4414         
4415         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4416          * mixer widget
4417          * Note: PASD motherboards uses the Line In 2 as the input for
4418          * front panel mic (mic 2)
4419          */
4420         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4421         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4422         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4423         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4424         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4425         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4426
4427         /*
4428          * Set up output mixers (0x08 - 0x0a)
4429          */
4430         /* set vol=0 to output mixers */
4431         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4432         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4433         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4434         /* set up input amps for analog loopback */
4435         /* Amp Indices: DAC = 0, mixer = 1 */
4436         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4437         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4438         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4439         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4440         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4441         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4442         
4443         { }
4444 };
4445
4446 static int alc260_parse_auto_config(struct hda_codec *codec)
4447 {
4448         struct alc_spec *spec = codec->spec;
4449         unsigned int wcap;
4450         int err;
4451         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4452
4453         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4454                                            alc260_ignore);
4455         if (err < 0)
4456                 return err;
4457         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4458         if (err < 0)
4459                 return err;
4460         if (!spec->kctl_alloc)
4461                 return 0; /* can't find valid BIOS pin config */
4462         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4463         if (err < 0)
4464                 return err;
4465
4466         spec->multiout.max_channels = 2;
4467
4468         if (spec->autocfg.dig_out_pin)
4469                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4470         if (spec->kctl_alloc)
4471                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4472
4473         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4474
4475         spec->num_mux_defs = 1;
4476         spec->input_mux = &spec->private_imux;
4477
4478         /* check whether NID 0x04 is valid */
4479         wcap = get_wcaps(codec, 0x04);
4480         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4481         if (wcap != AC_WID_AUD_IN) {
4482                 spec->adc_nids = alc260_adc_nids_alt;
4483                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4484                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4485         } else {
4486                 spec->adc_nids = alc260_adc_nids;
4487                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4488                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4489         }
4490         spec->num_mixers++;
4491
4492         return 1;
4493 }
4494
4495 /* additional initialization for auto-configuration model */
4496 static void alc260_auto_init(struct hda_codec *codec)
4497 {
4498         alc260_auto_init_multi_out(codec);
4499         alc260_auto_init_analog_input(codec);
4500 }
4501
4502 /*
4503  * ALC260 configurations
4504  */
4505 static const char *alc260_models[ALC260_MODEL_LAST] = {
4506         [ALC260_BASIC]          = "basic",
4507         [ALC260_HP]             = "hp",
4508         [ALC260_HP_3013]        = "hp-3013",
4509         [ALC260_FUJITSU_S702X]  = "fujitsu",
4510         [ALC260_ACER]           = "acer",
4511         [ALC260_WILL]           = "will",
4512         [ALC260_REPLACER_672V]  = "replacer",
4513 #ifdef CONFIG_SND_DEBUG
4514         [ALC260_TEST]           = "test",
4515 #endif
4516         [ALC260_AUTO]           = "auto",
4517 };
4518
4519 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4520         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4521         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4522         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4523         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4524         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4525         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4526         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4527         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4528         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4529         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4530         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4531         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4532         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4533         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4534         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4535         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4536         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4537         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4538         {}
4539 };
4540
4541 static struct alc_config_preset alc260_presets[] = {
4542         [ALC260_BASIC] = {
4543                 .mixers = { alc260_base_output_mixer,
4544                             alc260_input_mixer,
4545                             alc260_pc_beep_mixer,
4546                             alc260_capture_mixer },
4547                 .init_verbs = { alc260_init_verbs },
4548                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4549                 .dac_nids = alc260_dac_nids,
4550                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4551                 .adc_nids = alc260_adc_nids,
4552                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4553                 .channel_mode = alc260_modes,
4554                 .input_mux = &alc260_capture_source,
4555         },
4556         [ALC260_HP] = {
4557                 .mixers = { alc260_base_output_mixer,
4558                             alc260_input_mixer,
4559                             alc260_capture_alt_mixer },
4560                 .init_verbs = { alc260_init_verbs },
4561                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4562                 .dac_nids = alc260_dac_nids,
4563                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4564                 .adc_nids = alc260_hp_adc_nids,
4565                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4566                 .channel_mode = alc260_modes,
4567                 .input_mux = &alc260_capture_source,
4568         },
4569         [ALC260_HP_3013] = {
4570                 .mixers = { alc260_hp_3013_mixer,
4571                             alc260_input_mixer,
4572                             alc260_capture_alt_mixer },
4573                 .init_verbs = { alc260_hp_3013_init_verbs },
4574                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4575                 .dac_nids = alc260_dac_nids,
4576                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4577                 .adc_nids = alc260_hp_adc_nids,
4578                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4579                 .channel_mode = alc260_modes,
4580                 .input_mux = &alc260_capture_source,
4581         },
4582         [ALC260_FUJITSU_S702X] = {
4583                 .mixers = { alc260_fujitsu_mixer,
4584                             alc260_capture_mixer },
4585                 .init_verbs = { alc260_fujitsu_init_verbs },
4586                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4587                 .dac_nids = alc260_dac_nids,
4588                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4589                 .adc_nids = alc260_dual_adc_nids,
4590                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4591                 .channel_mode = alc260_modes,
4592                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4593                 .input_mux = alc260_fujitsu_capture_sources,
4594         },
4595         [ALC260_ACER] = {
4596                 .mixers = { alc260_acer_mixer,
4597                             alc260_capture_mixer },
4598                 .init_verbs = { alc260_acer_init_verbs },
4599                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4600                 .dac_nids = alc260_dac_nids,
4601                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4602                 .adc_nids = alc260_dual_adc_nids,
4603                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4604                 .channel_mode = alc260_modes,
4605                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4606                 .input_mux = alc260_acer_capture_sources,
4607         },
4608         [ALC260_WILL] = {
4609                 .mixers = { alc260_will_mixer,
4610                             alc260_capture_mixer },
4611                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4612                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4613                 .dac_nids = alc260_dac_nids,
4614                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4615                 .adc_nids = alc260_adc_nids,
4616                 .dig_out_nid = ALC260_DIGOUT_NID,
4617                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4618                 .channel_mode = alc260_modes,
4619                 .input_mux = &alc260_capture_source,
4620         },
4621         [ALC260_REPLACER_672V] = {
4622                 .mixers = { alc260_replacer_672v_mixer,
4623                             alc260_capture_mixer },
4624                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4625                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4626                 .dac_nids = alc260_dac_nids,
4627                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4628                 .adc_nids = alc260_adc_nids,
4629                 .dig_out_nid = ALC260_DIGOUT_NID,
4630                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4631                 .channel_mode = alc260_modes,
4632                 .input_mux = &alc260_capture_source,
4633                 .unsol_event = alc260_replacer_672v_unsol_event,
4634                 .init_hook = alc260_replacer_672v_automute,
4635         },
4636 #ifdef CONFIG_SND_DEBUG
4637         [ALC260_TEST] = {
4638                 .mixers = { alc260_test_mixer,
4639                             alc260_capture_mixer },
4640                 .init_verbs = { alc260_test_init_verbs },
4641                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4642                 .dac_nids = alc260_test_dac_nids,
4643                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4644                 .adc_nids = alc260_test_adc_nids,
4645                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4646                 .channel_mode = alc260_modes,
4647                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4648                 .input_mux = alc260_test_capture_sources,
4649         },
4650 #endif
4651 };
4652
4653 static int patch_alc260(struct hda_codec *codec)
4654 {
4655         struct alc_spec *spec;
4656         int err, board_config;
4657
4658         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4659         if (spec == NULL)
4660                 return -ENOMEM;
4661
4662         codec->spec = spec;
4663
4664         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4665                                                   alc260_models,
4666                                                   alc260_cfg_tbl);
4667         if (board_config < 0) {
4668                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4669                            "trying auto-probe from BIOS...\n");
4670                 board_config = ALC260_AUTO;
4671         }
4672
4673         if (board_config == ALC260_AUTO) {
4674                 /* automatic parse from the BIOS config */
4675                 err = alc260_parse_auto_config(codec);
4676                 if (err < 0) {
4677                         alc_free(codec);
4678                         return err;
4679                 } else if (!err) {
4680                         printk(KERN_INFO
4681                                "hda_codec: Cannot set up configuration "
4682                                "from BIOS.  Using base mode...\n");
4683                         board_config = ALC260_BASIC;
4684                 }
4685         }
4686
4687         if (board_config != ALC260_AUTO)
4688                 setup_preset(spec, &alc260_presets[board_config]);
4689
4690         spec->stream_name_analog = "ALC260 Analog";
4691         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4692         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4693
4694         spec->stream_name_digital = "ALC260 Digital";
4695         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4696         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4697
4698         codec->patch_ops = alc_patch_ops;
4699         if (board_config == ALC260_AUTO)
4700                 spec->init_hook = alc260_auto_init;
4701
4702         return 0;
4703 }
4704
4705
4706 /*
4707  * ALC882 support
4708  *
4709  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4710  * configuration.  Each pin widget can choose any input DACs and a mixer.
4711  * Each ADC is connected from a mixer of all inputs.  This makes possible
4712  * 6-channel independent captures.
4713  *
4714  * In addition, an independent DAC for the multi-playback (not used in this
4715  * driver yet).
4716  */
4717 #define ALC882_DIGOUT_NID       0x06
4718 #define ALC882_DIGIN_NID        0x0a
4719
4720 static struct hda_channel_mode alc882_ch_modes[1] = {
4721         { 8, NULL }
4722 };
4723
4724 static hda_nid_t alc882_dac_nids[4] = {
4725         /* front, rear, clfe, rear_surr */
4726         0x02, 0x03, 0x04, 0x05
4727 };
4728
4729 /* identical with ALC880 */
4730 #define alc882_adc_nids         alc880_adc_nids
4731 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4732
4733 /* input MUX */
4734 /* FIXME: should be a matrix-type input source selection */
4735
4736 static struct hda_input_mux alc882_capture_source = {
4737         .num_items = 4,
4738         .items = {
4739                 { "Mic", 0x0 },
4740                 { "Front Mic", 0x1 },
4741                 { "Line", 0x2 },
4742                 { "CD", 0x4 },
4743         },
4744 };
4745 #define alc882_mux_enum_info alc_mux_enum_info
4746 #define alc882_mux_enum_get alc_mux_enum_get
4747
4748 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4749                                struct snd_ctl_elem_value *ucontrol)
4750 {
4751         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4752         struct alc_spec *spec = codec->spec;
4753         const struct hda_input_mux *imux = spec->input_mux;
4754         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4755         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4756         hda_nid_t nid = capture_mixers[adc_idx];
4757         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4758         unsigned int i, idx;
4759
4760         idx = ucontrol->value.enumerated.item[0];
4761         if (idx >= imux->num_items)
4762                 idx = imux->num_items - 1;
4763         if (*cur_val == idx)
4764                 return 0;
4765         for (i = 0; i < imux->num_items; i++) {
4766                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4767                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4768                                          imux->items[i].index,
4769                                          HDA_AMP_MUTE, v);
4770         }
4771         *cur_val = idx;
4772         return 1;
4773 }
4774
4775 /*
4776  * 2ch mode
4777  */
4778 static struct hda_verb alc882_3ST_ch2_init[] = {
4779         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4780         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4781         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4782         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4783         { } /* end */
4784 };
4785
4786 /*
4787  * 6ch mode
4788  */
4789 static struct hda_verb alc882_3ST_ch6_init[] = {
4790         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4791         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4792         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4793         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4794         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4795         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4796         { } /* end */
4797 };
4798
4799 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4800         { 2, alc882_3ST_ch2_init },
4801         { 6, alc882_3ST_ch6_init },
4802 };
4803
4804 /*
4805  * 6ch mode
4806  */
4807 static struct hda_verb alc882_sixstack_ch6_init[] = {
4808         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4809         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4810         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4811         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4812         { } /* end */
4813 };
4814
4815 /*
4816  * 8ch mode
4817  */
4818 static struct hda_verb alc882_sixstack_ch8_init[] = {
4819         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4820         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4821         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4822         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4823         { } /* end */
4824 };
4825
4826 static struct hda_channel_mode alc882_sixstack_modes[2] = {
4827         { 6, alc882_sixstack_ch6_init },
4828         { 8, alc882_sixstack_ch8_init },
4829 };
4830
4831 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4832  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4833  */
4834 static struct snd_kcontrol_new alc882_base_mixer[] = {
4835         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4836         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4837         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4838         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4839         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4840         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4841         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4842         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4843         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4844         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4845         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4846         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4847         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4848         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4849         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4850         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4851         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4852         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4853         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4854         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4855         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4856         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4857         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4858         { } /* end */
4859 };
4860
4861 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4862         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4863         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4864         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4865         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4866         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4867         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4868         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4869         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4870         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4871         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4872         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4873         { } /* end */
4874 };
4875
4876 static struct snd_kcontrol_new alc882_targa_mixer[] = {
4877         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4878         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4879         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4880         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4881         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4882         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4883         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4884         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4885         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4886         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4887         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4888         { } /* end */
4889 };
4890
4891 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4892  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4893  */
4894 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4895         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4896         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4897         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4898         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4899         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4900         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4901         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4902         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4903         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4904         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4905         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4906         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4907         { } /* end */
4908 };
4909
4910 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4911         {
4912                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4913                 .name = "Channel Mode",
4914                 .info = alc_ch_mode_info,
4915                 .get = alc_ch_mode_get,
4916                 .put = alc_ch_mode_put,
4917         },
4918         { } /* end */
4919 };
4920
4921 static struct hda_verb alc882_init_verbs[] = {
4922         /* Front mixer: unmute input/output amp left and right (volume = 0) */
4923         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4924         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4925         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4926         /* Rear mixer */
4927         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4928         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4929         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4930         /* CLFE mixer */
4931         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4932         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4933         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4934         /* Side mixer */
4935         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4936         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4937         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4938
4939         /* Front Pin: output 0 (0x0c) */
4940         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4941         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4942         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4943         /* Rear Pin: output 1 (0x0d) */
4944         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4945         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4946         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4947         /* CLFE Pin: output 2 (0x0e) */
4948         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4949         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4950         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4951         /* Side Pin: output 3 (0x0f) */
4952         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4953         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4954         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4955         /* Mic (rear) pin: input vref at 80% */
4956         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4957         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4958         /* Front Mic pin: input vref at 80% */
4959         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4960         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4961         /* Line In pin: input */
4962         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4963         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4964         /* Line-2 In: Headphone output (output 0 - 0x0c) */
4965         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4966         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4967         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
4968         /* CD pin widget for input */
4969         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4970
4971         /* FIXME: use matrix-type input source selection */
4972         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4973         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4974         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4975         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4976         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4977         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4978         /* Input mixer2 */
4979         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4980         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4981         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4982         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4983         /* Input mixer3 */
4984         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4985         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4986         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4987         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4988         /* ADC1: mute amp left and right */
4989         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4990         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4991         /* ADC2: mute amp left and right */
4992         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4993         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4994         /* ADC3: mute amp left and right */
4995         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4996         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4997
4998         { }
4999 };
5000
5001 static struct hda_verb alc882_eapd_verbs[] = {
5002         /* change to EAPD mode */
5003         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5004         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5005         { }
5006 };
5007
5008 /* Mac Pro test */
5009 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5010         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5011         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5012         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5013         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5014         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5015         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5016         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5017         { } /* end */
5018 };
5019
5020 static struct hda_verb alc882_macpro_init_verbs[] = {
5021         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5022         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5023         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5024         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5025         /* Front Pin: output 0 (0x0c) */
5026         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5027         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5028         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5029         /* Front Mic pin: input vref at 80% */
5030         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5031         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5032         /* Speaker:  output */
5033         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5034         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5035         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5036         /* Headphone output (output 0 - 0x0c) */
5037         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5038         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5039         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5040
5041         /* FIXME: use matrix-type input source selection */
5042         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5043         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5044         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5045         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5046         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5047         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5048         /* Input mixer2 */
5049         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5050         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5051         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5052         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5053         /* Input mixer3 */
5054         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5055         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5056         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5057         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5058         /* ADC1: mute amp left and right */
5059         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5060         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5061         /* ADC2: mute amp left and right */
5062         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5063         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5064         /* ADC3: mute amp left and right */
5065         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5066         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5067
5068         { }
5069 };
5070
5071 /* iMac 24 mixer. */
5072 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5073         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5074         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5075         { } /* end */
5076 };
5077
5078 /* iMac 24 init verbs. */
5079 static struct hda_verb alc885_imac24_init_verbs[] = {
5080         /* Internal speakers: output 0 (0x0c) */
5081         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5082         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5083         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5084         /* Internal speakers: output 0 (0x0c) */
5085         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5086         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5087         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5088         /* Headphone: output 0 (0x0c) */
5089         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5090         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5091         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5092         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5093         /* Front Mic: input vref at 80% */
5094         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5095         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5096         { }
5097 };
5098
5099 /* Toggle speaker-output according to the hp-jack state */
5100 static void alc885_imac24_automute(struct hda_codec *codec)
5101 {
5102         unsigned int present;
5103
5104         present = snd_hda_codec_read(codec, 0x14, 0,
5105                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5106         snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5107                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5108         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5109                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5110 }
5111
5112 /* Processes unsolicited events. */
5113 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5114                                       unsigned int res)
5115 {
5116         /* Headphone insertion or removal. */
5117         if ((res >> 26) == ALC880_HP_EVENT)
5118                 alc885_imac24_automute(codec);
5119 }
5120
5121 static struct hda_verb alc882_targa_verbs[] = {
5122         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5123         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5124
5125         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5126         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5127         
5128         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5129         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5130         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5131
5132         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5133         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5134         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5135         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5136         { } /* end */
5137 };
5138
5139 /* toggle speaker-output according to the hp-jack state */
5140 static void alc882_targa_automute(struct hda_codec *codec)
5141 {
5142         unsigned int present;
5143  
5144         present = snd_hda_codec_read(codec, 0x14, 0,
5145                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5146         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5147                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5148         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5149                                   present ? 1 : 3);
5150 }
5151
5152 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5153 {
5154         /* Looks like the unsol event is incompatible with the standard
5155          * definition.  4bit tag is placed at 26 bit!
5156          */
5157         if (((res >> 26) == ALC880_HP_EVENT)) {
5158                 alc882_targa_automute(codec);
5159         }
5160 }
5161
5162 static struct hda_verb alc882_asus_a7j_verbs[] = {
5163         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5164         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5165
5166         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5167         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5168         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5169         
5170         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5171         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5172         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5173
5174         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5175         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5176         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5177         { } /* end */
5178 };
5179
5180 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5181 {
5182         unsigned int gpiostate, gpiomask, gpiodir;
5183
5184         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5185                                        AC_VERB_GET_GPIO_DATA, 0);
5186
5187         if (!muted)
5188                 gpiostate |= (1 << pin);
5189         else
5190                 gpiostate &= ~(1 << pin);
5191
5192         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5193                                       AC_VERB_GET_GPIO_MASK, 0);
5194         gpiomask |= (1 << pin);
5195
5196         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5197                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5198         gpiodir |= (1 << pin);
5199
5200
5201         snd_hda_codec_write(codec, codec->afg, 0,
5202                             AC_VERB_SET_GPIO_MASK, gpiomask);
5203         snd_hda_codec_write(codec, codec->afg, 0,
5204                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5205
5206         msleep(1);
5207
5208         snd_hda_codec_write(codec, codec->afg, 0,
5209                             AC_VERB_SET_GPIO_DATA, gpiostate);
5210 }
5211
5212 /*
5213  * generic initialization of ADC, input mixers and output mixers
5214  */
5215 static struct hda_verb alc882_auto_init_verbs[] = {
5216         /*
5217          * Unmute ADC0-2 and set the default input to mic-in
5218          */
5219         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5220         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5221         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5222         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5223         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5224         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5225
5226         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5227          * mixer widget
5228          * Note: PASD motherboards uses the Line In 2 as the input for
5229          * front panel mic (mic 2)
5230          */
5231         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5232         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5233         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5234         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5235         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5236         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5237
5238         /*
5239          * Set up output mixers (0x0c - 0x0f)
5240          */
5241         /* set vol=0 to output mixers */
5242         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5243         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5244         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5245         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5246         /* set up input amps for analog loopback */
5247         /* Amp Indices: DAC = 0, mixer = 1 */
5248         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5249         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5250         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5251         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5252         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5253         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5254         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5255         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5256         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5257         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5258
5259         /* FIXME: use matrix-type input source selection */
5260         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5261         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5262         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5263         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5264         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5265         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5266         /* Input mixer2 */
5267         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5268         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5269         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5270         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5271         /* Input mixer3 */
5272         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5273         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5274         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5275         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5276
5277         { }
5278 };
5279
5280 /* capture mixer elements */
5281 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5282         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5283         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5284         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5285         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5286         {
5287                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5288                 /* The multiple "Capture Source" controls confuse alsamixer
5289                  * So call somewhat different..
5290                  * FIXME: the controls appear in the "playback" view!
5291                  */
5292                 /* .name = "Capture Source", */
5293                 .name = "Input Source",
5294                 .count = 2,
5295                 .info = alc882_mux_enum_info,
5296                 .get = alc882_mux_enum_get,
5297                 .put = alc882_mux_enum_put,
5298         },
5299         { } /* end */
5300 };
5301
5302 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5303         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5304         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5305         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5306         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5307         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5308         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5309         {
5310                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5311                 /* The multiple "Capture Source" controls confuse alsamixer
5312                  * So call somewhat different..
5313                  * FIXME: the controls appear in the "playback" view!
5314                  */
5315                 /* .name = "Capture Source", */
5316                 .name = "Input Source",
5317                 .count = 3,
5318                 .info = alc882_mux_enum_info,
5319                 .get = alc882_mux_enum_get,
5320                 .put = alc882_mux_enum_put,
5321         },
5322         { } /* end */
5323 };
5324
5325 /* pcm configuration: identiacal with ALC880 */
5326 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5327 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5328 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5329 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5330
5331 /*
5332  * configuration and preset
5333  */
5334 static const char *alc882_models[ALC882_MODEL_LAST] = {
5335         [ALC882_3ST_DIG]        = "3stack-dig",
5336         [ALC882_6ST_DIG]        = "6stack-dig",
5337         [ALC882_ARIMA]          = "arima",
5338         [ALC882_W2JC]           = "w2jc",
5339         [ALC885_MACPRO]         = "macpro",
5340         [ALC885_IMAC24]         = "imac24",
5341         [ALC882_AUTO]           = "auto",
5342 };
5343
5344 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5345         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5346         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5347         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5348         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5349         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5350         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5351         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5352         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5353         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5354         {}
5355 };
5356
5357 static struct alc_config_preset alc882_presets[] = {
5358         [ALC882_3ST_DIG] = {
5359                 .mixers = { alc882_base_mixer },
5360                 .init_verbs = { alc882_init_verbs },
5361                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5362                 .dac_nids = alc882_dac_nids,
5363                 .dig_out_nid = ALC882_DIGOUT_NID,
5364                 .dig_in_nid = ALC882_DIGIN_NID,
5365                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5366                 .channel_mode = alc882_ch_modes,
5367                 .need_dac_fix = 1,
5368                 .input_mux = &alc882_capture_source,
5369         },
5370         [ALC882_6ST_DIG] = {
5371                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5372                 .init_verbs = { alc882_init_verbs },
5373                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5374                 .dac_nids = alc882_dac_nids,
5375                 .dig_out_nid = ALC882_DIGOUT_NID,
5376                 .dig_in_nid = ALC882_DIGIN_NID,
5377                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5378                 .channel_mode = alc882_sixstack_modes,
5379                 .input_mux = &alc882_capture_source,
5380         },
5381         [ALC882_ARIMA] = {
5382                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5383                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5384                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5385                 .dac_nids = alc882_dac_nids,
5386                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5387                 .channel_mode = alc882_sixstack_modes,
5388                 .input_mux = &alc882_capture_source,
5389         },
5390         [ALC882_W2JC] = {
5391                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5392                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5393                                 alc880_gpio1_init_verbs },
5394                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5395                 .dac_nids = alc882_dac_nids,
5396                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5397                 .channel_mode = alc880_threestack_modes,
5398                 .need_dac_fix = 1,
5399                 .input_mux = &alc882_capture_source,
5400                 .dig_out_nid = ALC882_DIGOUT_NID,
5401         },
5402         [ALC885_MACPRO] = {
5403                 .mixers = { alc882_macpro_mixer },
5404                 .init_verbs = { alc882_macpro_init_verbs },
5405                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5406                 .dac_nids = alc882_dac_nids,
5407                 .dig_out_nid = ALC882_DIGOUT_NID,
5408                 .dig_in_nid = ALC882_DIGIN_NID,
5409                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5410                 .channel_mode = alc882_ch_modes,
5411                 .input_mux = &alc882_capture_source,
5412         },
5413         [ALC885_IMAC24] = {
5414                 .mixers = { alc885_imac24_mixer },
5415                 .init_verbs = { alc885_imac24_init_verbs },
5416                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5417                 .dac_nids = alc882_dac_nids,
5418                 .dig_out_nid = ALC882_DIGOUT_NID,
5419                 .dig_in_nid = ALC882_DIGIN_NID,
5420                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5421                 .channel_mode = alc882_ch_modes,
5422                 .input_mux = &alc882_capture_source,
5423                 .unsol_event = alc885_imac24_unsol_event,
5424                 .init_hook = alc885_imac24_automute,
5425         },
5426         [ALC882_TARGA] = {
5427                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5428                             alc882_capture_mixer },
5429                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5430                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5431                 .dac_nids = alc882_dac_nids,
5432                 .dig_out_nid = ALC882_DIGOUT_NID,
5433                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5434                 .adc_nids = alc882_adc_nids,
5435                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5436                 .channel_mode = alc882_3ST_6ch_modes,
5437                 .need_dac_fix = 1,
5438                 .input_mux = &alc882_capture_source,
5439                 .unsol_event = alc882_targa_unsol_event,
5440                 .init_hook = alc882_targa_automute,
5441         },
5442         [ALC882_ASUS_A7J] = {
5443                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5444                             alc882_capture_mixer },
5445                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5446                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5447                 .dac_nids = alc882_dac_nids,
5448                 .dig_out_nid = ALC882_DIGOUT_NID,
5449                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5450                 .adc_nids = alc882_adc_nids,
5451                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5452                 .channel_mode = alc882_3ST_6ch_modes,
5453                 .need_dac_fix = 1,
5454                 .input_mux = &alc882_capture_source,
5455         },      
5456 };
5457
5458
5459 /*
5460  * Pin config fixes
5461  */
5462 enum { 
5463         PINFIX_ABIT_AW9D_MAX
5464 };
5465
5466 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5467         { 0x15, 0x01080104 }, /* side */
5468         { 0x16, 0x01011012 }, /* rear */
5469         { 0x17, 0x01016011 }, /* clfe */
5470         { }
5471 };
5472
5473 static const struct alc_pincfg *alc882_pin_fixes[] = {
5474         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5475 };
5476
5477 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5478         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5479         {}
5480 };
5481
5482 /*
5483  * BIOS auto configuration
5484  */
5485 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5486                                               hda_nid_t nid, int pin_type,
5487                                               int dac_idx)
5488 {
5489         /* set as output */
5490         struct alc_spec *spec = codec->spec;
5491         int idx;
5492
5493         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5494                 idx = 4;
5495         else
5496                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5497
5498         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5499                             pin_type);
5500         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5501                             AMP_OUT_UNMUTE);
5502         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5503
5504 }
5505
5506 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5507 {
5508         struct alc_spec *spec = codec->spec;
5509         int i;
5510
5511         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5512         for (i = 0; i <= HDA_SIDE; i++) {
5513                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5514                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5515                 if (nid)
5516                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5517                                                           i);
5518         }
5519 }
5520
5521 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5522 {
5523         struct alc_spec *spec = codec->spec;
5524         hda_nid_t pin;
5525
5526         pin = spec->autocfg.hp_pins[0];
5527         if (pin) /* connect to front */
5528                 /* use dac 0 */
5529                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5530 }
5531
5532 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5533 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5534
5535 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5536 {
5537         struct alc_spec *spec = codec->spec;
5538         int i;
5539
5540         for (i = 0; i < AUTO_PIN_LAST; i++) {
5541                 hda_nid_t nid = spec->autocfg.input_pins[i];
5542                 if (alc882_is_input_pin(nid)) {
5543                         snd_hda_codec_write(codec, nid, 0,
5544                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5545                                             i <= AUTO_PIN_FRONT_MIC ?
5546                                             PIN_VREF80 : PIN_IN);
5547                         if (nid != ALC882_PIN_CD_NID)
5548                                 snd_hda_codec_write(codec, nid, 0,
5549                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5550                                                     AMP_OUT_MUTE);
5551                 }
5552         }
5553 }
5554
5555 /* almost identical with ALC880 parser... */
5556 static int alc882_parse_auto_config(struct hda_codec *codec)
5557 {
5558         struct alc_spec *spec = codec->spec;
5559         int err = alc880_parse_auto_config(codec);
5560
5561         if (err < 0)
5562                 return err;
5563         else if (err > 0)
5564                 /* hack - override the init verbs */
5565                 spec->init_verbs[0] = alc882_auto_init_verbs;
5566         return err;
5567 }
5568
5569 /* additional initialization for auto-configuration model */
5570 static void alc882_auto_init(struct hda_codec *codec)
5571 {
5572         alc882_auto_init_multi_out(codec);
5573         alc882_auto_init_hp_out(codec);
5574         alc882_auto_init_analog_input(codec);
5575 }
5576
5577 static int patch_alc882(struct hda_codec *codec)
5578 {
5579         struct alc_spec *spec;
5580         int err, board_config;
5581
5582         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5583         if (spec == NULL)
5584                 return -ENOMEM;
5585
5586         codec->spec = spec;
5587
5588         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5589                                                   alc882_models,
5590                                                   alc882_cfg_tbl);
5591
5592         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5593                 /* Pick up systems that don't supply PCI SSID */
5594                 switch (codec->subsystem_id) {
5595                 case 0x106b0c00: /* Mac Pro */
5596                         board_config = ALC885_MACPRO;
5597                         break;
5598                 case 0x106b1000: /* iMac 24 */
5599                         board_config = ALC885_IMAC24;
5600                         break;
5601                 default:
5602                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5603                                          "trying auto-probe from BIOS...\n");
5604                         board_config = ALC882_AUTO;
5605                 }
5606         }
5607
5608         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5609
5610         if (board_config == ALC882_AUTO) {
5611                 /* automatic parse from the BIOS config */
5612                 err = alc882_parse_auto_config(codec);
5613                 if (err < 0) {
5614                         alc_free(codec);
5615                         return err;
5616                 } else if (!err) {
5617                         printk(KERN_INFO
5618                                "hda_codec: Cannot set up configuration "
5619                                "from BIOS.  Using base mode...\n");
5620                         board_config = ALC882_3ST_DIG;
5621                 }
5622         }
5623
5624         if (board_config != ALC882_AUTO)
5625                 setup_preset(spec, &alc882_presets[board_config]);
5626
5627         if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
5628                 alc882_gpio_mute(codec, 0, 0);
5629                 alc882_gpio_mute(codec, 1, 0);
5630         }
5631
5632         spec->stream_name_analog = "ALC882 Analog";
5633         spec->stream_analog_playback = &alc882_pcm_analog_playback;
5634         spec->stream_analog_capture = &alc882_pcm_analog_capture;
5635
5636         spec->stream_name_digital = "ALC882 Digital";
5637         spec->stream_digital_playback = &alc882_pcm_digital_playback;
5638         spec->stream_digital_capture = &alc882_pcm_digital_capture;
5639
5640         if (!spec->adc_nids && spec->input_mux) {
5641                 /* check whether NID 0x07 is valid */
5642                 unsigned int wcap = get_wcaps(codec, 0x07);
5643                 /* get type */
5644                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5645                 if (wcap != AC_WID_AUD_IN) {
5646                         spec->adc_nids = alc882_adc_nids_alt;
5647                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5648                         spec->mixers[spec->num_mixers] =
5649                                 alc882_capture_alt_mixer;
5650                         spec->num_mixers++;
5651                 } else {
5652                         spec->adc_nids = alc882_adc_nids;
5653                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5654                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5655                         spec->num_mixers++;
5656                 }
5657         }
5658
5659         codec->patch_ops = alc_patch_ops;
5660         if (board_config == ALC882_AUTO)
5661                 spec->init_hook = alc882_auto_init;
5662
5663         return 0;
5664 }
5665
5666 /*
5667  * ALC883 support
5668  *
5669  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5670  * configuration.  Each pin widget can choose any input DACs and a mixer.
5671  * Each ADC is connected from a mixer of all inputs.  This makes possible
5672  * 6-channel independent captures.
5673  *
5674  * In addition, an independent DAC for the multi-playback (not used in this
5675  * driver yet).
5676  */
5677 #define ALC883_DIGOUT_NID       0x06
5678 #define ALC883_DIGIN_NID        0x0a
5679
5680 static hda_nid_t alc883_dac_nids[4] = {
5681         /* front, rear, clfe, rear_surr */
5682         0x02, 0x04, 0x03, 0x05
5683 };
5684
5685 static hda_nid_t alc883_adc_nids[2] = {
5686         /* ADC1-2 */
5687         0x08, 0x09,
5688 };
5689
5690 /* input MUX */
5691 /* FIXME: should be a matrix-type input source selection */
5692
5693 static struct hda_input_mux alc883_capture_source = {
5694         .num_items = 4,
5695         .items = {
5696                 { "Mic", 0x0 },
5697                 { "Front Mic", 0x1 },
5698                 { "Line", 0x2 },
5699                 { "CD", 0x4 },
5700         },
5701 };
5702
5703 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5704         .num_items = 2,
5705         .items = {
5706                 { "Mic", 0x1 },
5707                 { "Line", 0x2 },
5708         },
5709 };
5710
5711 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5712         .num_items = 4,
5713         .items = {
5714                 { "Mic", 0x0 },
5715                 { "iMic", 0x1 },
5716                 { "Line", 0x2 },
5717                 { "CD", 0x4 },
5718         },
5719 };
5720
5721 #define alc883_mux_enum_info alc_mux_enum_info
5722 #define alc883_mux_enum_get alc_mux_enum_get
5723
5724 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5725                                struct snd_ctl_elem_value *ucontrol)
5726 {
5727         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5728         struct alc_spec *spec = codec->spec;
5729         const struct hda_input_mux *imux = spec->input_mux;
5730         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5731         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5732         hda_nid_t nid = capture_mixers[adc_idx];
5733         unsigned int *cur_val = &spec->cur_mux[adc_idx];
5734         unsigned int i, idx;
5735
5736         idx = ucontrol->value.enumerated.item[0];
5737         if (idx >= imux->num_items)
5738                 idx = imux->num_items - 1;
5739         if (*cur_val == idx)
5740                 return 0;
5741         for (i = 0; i < imux->num_items; i++) {
5742                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5743                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5744                                          imux->items[i].index,
5745                                          HDA_AMP_MUTE, v);
5746         }
5747         *cur_val = idx;
5748         return 1;
5749 }
5750
5751 /*
5752  * 2ch mode
5753  */
5754 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5755         { 2, NULL }
5756 };
5757
5758 /*
5759  * 2ch mode
5760  */
5761 static struct hda_verb alc883_3ST_ch2_init[] = {
5762         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5763         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5764         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5765         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5766         { } /* end */
5767 };
5768
5769 /*
5770  * 6ch mode
5771  */
5772 static struct hda_verb alc883_3ST_ch6_init[] = {
5773         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5774         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5775         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5776         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5777         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5778         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5779         { } /* end */
5780 };
5781
5782 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5783         { 2, alc883_3ST_ch2_init },
5784         { 6, alc883_3ST_ch6_init },
5785 };
5786
5787 /*
5788  * 6ch mode
5789  */
5790 static struct hda_verb alc883_sixstack_ch6_init[] = {
5791         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5792         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5793         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5794         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5795         { } /* end */
5796 };
5797
5798 /*
5799  * 8ch mode
5800  */
5801 static struct hda_verb alc883_sixstack_ch8_init[] = {
5802         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5803         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5804         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5805         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5806         { } /* end */
5807 };
5808
5809 static struct hda_channel_mode alc883_sixstack_modes[2] = {
5810         { 6, alc883_sixstack_ch6_init },
5811         { 8, alc883_sixstack_ch8_init },
5812 };
5813
5814 static struct hda_verb alc883_medion_eapd_verbs[] = {
5815         /* eanable EAPD on medion laptop */
5816         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5817         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5818         { }
5819 };
5820
5821 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5822  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5823  */
5824
5825 static struct snd_kcontrol_new alc883_base_mixer[] = {
5826         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5827         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5828         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5829         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5830         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5831         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5832         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5833         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5834         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5835         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5836         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5837         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5838         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5839         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5840         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5841         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5842         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5843         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5844         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5845         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5846         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5847         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5848         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5849         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5850         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5851         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5852         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5853         {
5854                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5855                 /* .name = "Capture Source", */
5856                 .name = "Input Source",
5857                 .count = 2,
5858                 .info = alc883_mux_enum_info,
5859                 .get = alc883_mux_enum_get,
5860                 .put = alc883_mux_enum_put,
5861         },
5862         { } /* end */
5863 };
5864
5865 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5866         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5867         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5868         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5869         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5870         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5871         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5872         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5873         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5874         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5875         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5876         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5877         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5878         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5879         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5880         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5881         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5882         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5883         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5884         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5885         {
5886                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5887                 /* .name = "Capture Source", */
5888                 .name = "Input Source",
5889                 .count = 2,
5890                 .info = alc883_mux_enum_info,
5891                 .get = alc883_mux_enum_get,
5892                 .put = alc883_mux_enum_put,
5893         },
5894         { } /* end */
5895 };
5896
5897 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5898         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5899         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5900         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5901         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5902         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5903         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5904         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5905         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5906         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5907         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5908         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5909         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5910         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5911         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5912         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5913         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5914         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5915         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5916         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5917         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5918         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5919         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5920         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5921         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5922         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5923         {
5924                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5925                 /* .name = "Capture Source", */
5926                 .name = "Input Source",
5927                 .count = 2,
5928                 .info = alc883_mux_enum_info,
5929                 .get = alc883_mux_enum_get,
5930                 .put = alc883_mux_enum_put,
5931         },
5932         { } /* end */
5933 };
5934
5935 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5936         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5937         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5938         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5939         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5940         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5941         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5942         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5943         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5944         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5945         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5946         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5947         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5948         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5949         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5950         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5951         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5952         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5953         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5954         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5955         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5956         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5957         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5958         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5959
5960         {
5961                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5962                 /* .name = "Capture Source", */
5963                 .name = "Input Source",
5964                 .count = 1,
5965                 .info = alc883_mux_enum_info,
5966                 .get = alc883_mux_enum_get,
5967                 .put = alc883_mux_enum_put,
5968         },
5969         { } /* end */
5970 };
5971
5972 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5973         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5974         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5975         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5976         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5977         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5978         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5979         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5980         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5981         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5982         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5983         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5984         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5985         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5986         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5987         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5988         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5989         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5990         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5991         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5992         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5993         {
5994                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5995                 /* .name = "Capture Source", */
5996                 .name = "Input Source",
5997                 .count = 2,
5998                 .info = alc883_mux_enum_info,
5999                 .get = alc883_mux_enum_get,
6000                 .put = alc883_mux_enum_put,
6001         },
6002         { } /* end */
6003 };
6004
6005 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6006         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6007         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6008         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6009         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6010         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6011         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6012         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6013         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6014         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6015         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6016         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6017         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6018         {
6019                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6020                 /* .name = "Capture Source", */
6021                 .name = "Input Source",
6022                 .count = 2,
6023                 .info = alc883_mux_enum_info,
6024                 .get = alc883_mux_enum_get,
6025                 .put = alc883_mux_enum_put,
6026         },
6027         { } /* end */
6028 };
6029
6030 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6031         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6032         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6033         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6034         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6035         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6036         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6037         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6038         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6039         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6040         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6041         {
6042                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6043                 /* .name = "Capture Source", */
6044                 .name = "Input Source",
6045                 .count = 1,
6046                 .info = alc883_mux_enum_info,
6047                 .get = alc883_mux_enum_get,
6048                 .put = alc883_mux_enum_put,
6049         },
6050         { } /* end */
6051 };
6052
6053 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6054         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6055         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6056         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6057         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6058         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6059         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6060         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6061         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6062         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6063         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6064         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6065         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6066         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6067         {
6068                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6069                 /* .name = "Capture Source", */
6070                 .name = "Input Source",
6071                 .count = 2,
6072                 .info = alc883_mux_enum_info,
6073                 .get = alc883_mux_enum_get,
6074                 .put = alc883_mux_enum_put,
6075         },
6076         { } /* end */
6077 };
6078
6079 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6080         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6081         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6082         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6083         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6084         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6085         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6086         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6087         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6088         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6089         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6090         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6091         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6092         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6093         {
6094                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6095                 /* .name = "Capture Source", */
6096                 .name = "Input Source",
6097                 .count = 2,
6098                 .info = alc883_mux_enum_info,
6099                 .get = alc883_mux_enum_get,
6100                 .put = alc883_mux_enum_put,
6101         },
6102         { } /* end */
6103 };      
6104
6105 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6106         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6107         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6108         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6109         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6110         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6111         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6112         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6113         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6114         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6115         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6116         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6117         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6118         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6119         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6120         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6121         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6122         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6123         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6124         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6125         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6126         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6127         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6128         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6129         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6130         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6131         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6132         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6133         {
6134                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6135                 /* .name = "Capture Source", */
6136                 .name = "Input Source",
6137                 .count = 2,
6138                 .info = alc883_mux_enum_info,
6139                 .get = alc883_mux_enum_get,
6140                 .put = alc883_mux_enum_put,
6141         },
6142         { } /* end */
6143 };
6144
6145 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6146         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6147         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6148         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6149         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6150         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6151         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6152         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6153         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6154         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6155         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6156         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6157         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6158         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6159         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6160         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6161         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6162         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6163         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6164         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6165         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6166         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6167         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6168         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6169         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6170         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6171         {
6172                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6173                 /* .name = "Capture Source", */
6174                 .name = "Input Source",
6175                 .count = 2,
6176                 .info = alc883_mux_enum_info,
6177                 .get = alc883_mux_enum_get,
6178                 .put = alc883_mux_enum_put,
6179         },
6180         { } /* end */
6181 };
6182
6183 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6184         HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6185         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6186         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6187         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6188         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6189         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6190         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6191         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6192         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6193         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6194         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6195         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6196         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6197         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6198         {
6199                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6200                 /* .name = "Capture Source", */
6201                 .name = "Input Source",
6202                 .count = 2,
6203                 .info = alc883_mux_enum_info,
6204                 .get = alc883_mux_enum_get,
6205                 .put = alc883_mux_enum_put,
6206         },
6207         { } /* end */
6208 };      
6209
6210 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6211         {
6212                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6213                 .name = "Channel Mode",
6214                 .info = alc_ch_mode_info,
6215                 .get = alc_ch_mode_get,
6216                 .put = alc_ch_mode_put,
6217         },
6218         { } /* end */
6219 };
6220
6221 static struct hda_verb alc883_init_verbs[] = {
6222         /* ADC1: mute amp left and right */
6223         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6224         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6225         /* ADC2: mute amp left and right */
6226         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6227         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6228         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6229         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6230         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6231         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6232         /* Rear mixer */
6233         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6234         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6235         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6236         /* CLFE mixer */
6237         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6238         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6239         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6240         /* Side mixer */
6241         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6242         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6243         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6244
6245         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6246         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6247         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6248         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6249         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6250
6251         /* Front Pin: output 0 (0x0c) */
6252         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6253         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6254         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6255         /* Rear Pin: output 1 (0x0d) */
6256         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6257         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6258         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6259         /* CLFE Pin: output 2 (0x0e) */
6260         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6261         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6262         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6263         /* Side Pin: output 3 (0x0f) */
6264         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6265         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6266         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6267         /* Mic (rear) pin: input vref at 80% */
6268         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6269         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6270         /* Front Mic pin: input vref at 80% */
6271         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6272         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6273         /* Line In pin: input */
6274         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6275         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6276         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6277         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6278         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6279         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6280         /* CD pin widget for input */
6281         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6282
6283         /* FIXME: use matrix-type input source selection */
6284         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6285         /* Input mixer2 */
6286         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6287         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6288         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6289         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6290         /* Input mixer3 */
6291         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6292         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6293         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6294         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6295         { }
6296 };
6297
6298 static struct hda_verb alc883_tagra_verbs[] = {
6299         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6300         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6301
6302         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6303         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6304         
6305         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6306         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6307         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6308
6309         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6310         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6311         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6312         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6313
6314         { } /* end */
6315 };
6316
6317 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6318         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6319         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6320         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6321         { } /* end */
6322 };
6323
6324 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6325         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6326         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6327         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6328         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6329         { } /* end */
6330 };
6331
6332 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6333         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6334         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6335         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6336         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6337         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6338         { } /* end */
6339 };
6340
6341 static struct hda_verb alc888_6st_hp_verbs[] = {
6342         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6343         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6344         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6345         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6346         { }
6347 };
6348
6349 static struct hda_verb alc888_3st_hp_verbs[] = {
6350         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6351         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6352         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6353         { }
6354 };
6355
6356 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6357         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6358         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6359         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6360         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6361         { }
6362 };
6363
6364 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6365         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6366         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6367         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6368         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6369         { }
6370 };
6371
6372 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6373         { 2, alc888_3st_hp_2ch_init },
6374         { 6, alc888_3st_hp_6ch_init },
6375 };
6376
6377 /* toggle front-jack and RCA according to the hp-jack state */
6378 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6379 {
6380         unsigned int present;
6381  
6382         present = snd_hda_codec_read(codec, 0x1b, 0,
6383                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6384         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6385                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6386         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6387                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6388 }
6389
6390 /* toggle RCA according to the front-jack state */
6391 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6392 {
6393         unsigned int present;
6394  
6395         present = snd_hda_codec_read(codec, 0x14, 0,
6396                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6397         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6398                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6399 }
6400
6401 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6402                                              unsigned int res)
6403 {
6404         if ((res >> 26) == ALC880_HP_EVENT)
6405                 alc888_lenovo_ms7195_front_automute(codec);
6406         if ((res >> 26) == ALC880_FRONT_EVENT)
6407                 alc888_lenovo_ms7195_rca_automute(codec);
6408 }
6409
6410 static struct hda_verb alc883_medion_md2_verbs[] = {
6411         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6412         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6413
6414         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6415
6416         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6417         { } /* end */
6418 };
6419
6420 static struct hda_verb alc883_acer_aspire_verbs[] = {
6421         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6422         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6423         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6424         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6425
6426         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6427
6428         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6429         { } /* end */
6430 };
6431
6432 /* toggle speaker-output according to the hp-jack state */
6433 static void alc883_medion_md2_automute(struct hda_codec *codec)
6434 {
6435         unsigned int present;
6436  
6437         present = snd_hda_codec_read(codec, 0x14, 0,
6438                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6439         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6440                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6441 }
6442
6443 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6444                                           unsigned int res)
6445 {
6446         if ((res >> 26) == ALC880_HP_EVENT)
6447                 alc883_medion_md2_automute(codec);
6448 }
6449
6450 /* toggle speaker-output according to the hp-jack state */
6451 static void alc883_tagra_automute(struct hda_codec *codec)
6452 {
6453         unsigned int present;
6454         unsigned char bits;
6455
6456         present = snd_hda_codec_read(codec, 0x14, 0,
6457                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6458         bits = present ? HDA_AMP_MUTE : 0;
6459         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6460                                  HDA_AMP_MUTE, bits);
6461         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6462                                   present ? 1 : 3);
6463 }
6464
6465 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6466 {
6467         if ((res >> 26) == ALC880_HP_EVENT)
6468                 alc883_tagra_automute(codec);
6469 }
6470
6471 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6472 {
6473         unsigned int present;
6474         unsigned char bits;
6475
6476         present = snd_hda_codec_read(codec, 0x14, 0,
6477                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6478         bits = present ? HDA_AMP_MUTE : 0;
6479         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6480                                  HDA_AMP_MUTE, bits);
6481 }
6482
6483 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6484 {
6485         unsigned int present;
6486         unsigned char bits;
6487
6488         present = snd_hda_codec_read(codec, 0x1b, 0,
6489                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6490         bits = present ? HDA_AMP_MUTE : 0;
6491         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6492                                  HDA_AMP_MUTE, bits);
6493         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6494                                  HDA_AMP_MUTE, bits);
6495 }
6496
6497 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6498                                            unsigned int res)
6499 {
6500         if ((res >> 26) == ALC880_HP_EVENT)
6501                 alc883_lenovo_101e_all_automute(codec);
6502         if ((res >> 26) == ALC880_FRONT_EVENT)
6503                 alc883_lenovo_101e_ispeaker_automute(codec);
6504 }
6505
6506 /*
6507  * generic initialization of ADC, input mixers and output mixers
6508  */
6509 static struct hda_verb alc883_auto_init_verbs[] = {
6510         /*
6511          * Unmute ADC0-2 and set the default input to mic-in
6512          */
6513         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6514         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6515         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6516         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6517
6518         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6519          * mixer widget
6520          * Note: PASD motherboards uses the Line In 2 as the input for
6521          * front panel mic (mic 2)
6522          */
6523         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6524         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6525         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6526         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6527         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6528         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6529
6530         /*
6531          * Set up output mixers (0x0c - 0x0f)
6532          */
6533         /* set vol=0 to output mixers */
6534         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6535         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6536         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6537         {0x0f, 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         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6547         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6548         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6549         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6550
6551         /* FIXME: use matrix-type input source selection */
6552         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6553         /* Input mixer1 */
6554         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6555         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6556         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6557         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6558         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6559         /* Input mixer2 */
6560         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6561         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6562         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6563         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6564         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6565
6566         { }
6567 };
6568
6569 /* capture mixer elements */
6570 static struct snd_kcontrol_new alc883_capture_mixer[] = {
6571         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6572         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6573         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6574         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6575         {
6576                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6577                 /* The multiple "Capture Source" controls confuse alsamixer
6578                  * So call somewhat different..
6579                  * FIXME: the controls appear in the "playback" view!
6580                  */
6581                 /* .name = "Capture Source", */
6582                 .name = "Input Source",
6583                 .count = 2,
6584                 .info = alc882_mux_enum_info,
6585                 .get = alc882_mux_enum_get,
6586                 .put = alc882_mux_enum_put,
6587         },
6588         { } /* end */
6589 };
6590
6591 /* pcm configuration: identiacal with ALC880 */
6592 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
6593 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
6594 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
6595 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
6596
6597 /*
6598  * configuration and preset
6599  */
6600 static const char *alc883_models[ALC883_MODEL_LAST] = {
6601         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
6602         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
6603         [ALC883_3ST_6ch]        = "3stack-6ch",
6604         [ALC883_6ST_DIG]        = "6stack-dig",
6605         [ALC883_TARGA_DIG]      = "targa-dig",
6606         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
6607         [ALC883_ACER]           = "acer",
6608         [ALC883_ACER_ASPIRE]    = "acer-aspire",
6609         [ALC883_MEDION]         = "medion",
6610         [ALC883_MEDION_MD2]     = "medion-md2",
6611         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
6612         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6613         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
6614         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6615         [ALC888_6ST_HP]         = "6stack-hp",
6616         [ALC888_3ST_HP]         = "3stack-hp",
6617         [ALC883_AUTO]           = "auto",
6618 };
6619
6620 static struct snd_pci_quirk alc883_cfg_tbl[] = {
6621         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6622         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6623         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6624         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6625         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6626         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6627         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6628         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6629         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6630         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6631         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6632         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6633         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6634         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6635         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6636         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6637         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6638         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6639         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6640         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6641         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6642         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6643         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6644         SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
6645         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6646         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6647         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6648         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6649         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6650         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6651         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6652         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6653         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6654         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6655         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6656         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6657         {}
6658 };
6659
6660 static struct alc_config_preset alc883_presets[] = {
6661         [ALC883_3ST_2ch_DIG] = {
6662                 .mixers = { alc883_3ST_2ch_mixer },
6663                 .init_verbs = { alc883_init_verbs },
6664                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6665                 .dac_nids = alc883_dac_nids,
6666                 .dig_out_nid = ALC883_DIGOUT_NID,
6667                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6668                 .adc_nids = alc883_adc_nids,
6669                 .dig_in_nid = ALC883_DIGIN_NID,
6670                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6671                 .channel_mode = alc883_3ST_2ch_modes,
6672                 .input_mux = &alc883_capture_source,
6673         },
6674         [ALC883_3ST_6ch_DIG] = {
6675                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6676                 .init_verbs = { alc883_init_verbs },
6677                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6678                 .dac_nids = alc883_dac_nids,
6679                 .dig_out_nid = ALC883_DIGOUT_NID,
6680                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6681                 .adc_nids = alc883_adc_nids,
6682                 .dig_in_nid = ALC883_DIGIN_NID,
6683                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6684                 .channel_mode = alc883_3ST_6ch_modes,
6685                 .need_dac_fix = 1,
6686                 .input_mux = &alc883_capture_source,
6687         },
6688         [ALC883_3ST_6ch] = {
6689                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6690                 .init_verbs = { alc883_init_verbs },
6691                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6692                 .dac_nids = alc883_dac_nids,
6693                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6694                 .adc_nids = alc883_adc_nids,
6695                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6696                 .channel_mode = alc883_3ST_6ch_modes,
6697                 .need_dac_fix = 1,
6698                 .input_mux = &alc883_capture_source,
6699         },
6700         [ALC883_6ST_DIG] = {
6701                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
6702                 .init_verbs = { alc883_init_verbs },
6703                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6704                 .dac_nids = alc883_dac_nids,
6705                 .dig_out_nid = ALC883_DIGOUT_NID,
6706                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6707                 .adc_nids = alc883_adc_nids,
6708                 .dig_in_nid = ALC883_DIGIN_NID,
6709                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6710                 .channel_mode = alc883_sixstack_modes,
6711                 .input_mux = &alc883_capture_source,
6712         },
6713         [ALC883_TARGA_DIG] = {
6714                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6715                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6716                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6717                 .dac_nids = alc883_dac_nids,
6718                 .dig_out_nid = ALC883_DIGOUT_NID,
6719                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6720                 .adc_nids = alc883_adc_nids,
6721                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6722                 .channel_mode = alc883_3ST_6ch_modes,
6723                 .need_dac_fix = 1,
6724                 .input_mux = &alc883_capture_source,
6725                 .unsol_event = alc883_tagra_unsol_event,
6726                 .init_hook = alc883_tagra_automute,
6727         },
6728         [ALC883_TARGA_2ch_DIG] = {
6729                 .mixers = { alc883_tagra_2ch_mixer},
6730                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6731                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6732                 .dac_nids = alc883_dac_nids,
6733                 .dig_out_nid = ALC883_DIGOUT_NID,
6734                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6735                 .adc_nids = alc883_adc_nids,
6736                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6737                 .channel_mode = alc883_3ST_2ch_modes,
6738                 .input_mux = &alc883_capture_source,
6739                 .unsol_event = alc883_tagra_unsol_event,
6740                 .init_hook = alc883_tagra_automute,
6741         },
6742         [ALC883_ACER] = {
6743                 .mixers = { alc883_base_mixer,
6744                             alc883_chmode_mixer },
6745                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
6746                  * and the headphone jack.  Turn this on and rely on the
6747                  * standard mute methods whenever the user wants to turn
6748                  * these outputs off.
6749                  */
6750                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6751                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6752                 .dac_nids = alc883_dac_nids,
6753                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6754                 .adc_nids = alc883_adc_nids,
6755                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6756                 .channel_mode = alc883_3ST_2ch_modes,
6757                 .input_mux = &alc883_capture_source,
6758         },
6759         [ALC883_ACER_ASPIRE] = {
6760                 .mixers = { alc883_acer_aspire_mixer},
6761                 .init_verbs = { alc883_init_verbs, alc883_acer_aspire_verbs},
6762                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6763                 .dac_nids = alc883_dac_nids,
6764                 .dig_out_nid = ALC883_DIGOUT_NID,
6765                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6766                 .adc_nids = alc883_adc_nids,
6767                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6768                 .channel_mode = alc883_3ST_2ch_modes,
6769                 .input_mux = &alc883_capture_source,
6770                 .unsol_event = alc883_medion_md2_unsol_event,
6771                 .init_hook = alc883_medion_md2_automute,
6772         },      
6773         [ALC883_MEDION] = {
6774                 .mixers = { alc883_fivestack_mixer,
6775                             alc883_chmode_mixer },
6776                 .init_verbs = { alc883_init_verbs,
6777                                 alc883_medion_eapd_verbs },
6778                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6779                 .dac_nids = alc883_dac_nids,
6780                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6781                 .adc_nids = alc883_adc_nids,
6782                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6783                 .channel_mode = alc883_sixstack_modes,
6784                 .input_mux = &alc883_capture_source,
6785         },
6786         [ALC883_MEDION_MD2] = {
6787                 .mixers = { alc883_medion_md2_mixer},
6788                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6789                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6790                 .dac_nids = alc883_dac_nids,
6791                 .dig_out_nid = ALC883_DIGOUT_NID,
6792                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6793                 .adc_nids = alc883_adc_nids,
6794                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6795                 .channel_mode = alc883_3ST_2ch_modes,
6796                 .input_mux = &alc883_capture_source,
6797                 .unsol_event = alc883_medion_md2_unsol_event,
6798                 .init_hook = alc883_medion_md2_automute,
6799         },      
6800         [ALC883_LAPTOP_EAPD] = {
6801                 .mixers = { alc883_base_mixer,
6802                             alc883_chmode_mixer },
6803                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6804                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6805                 .dac_nids = alc883_dac_nids,
6806                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6807                 .adc_nids = alc883_adc_nids,
6808                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6809                 .channel_mode = alc883_3ST_2ch_modes,
6810                 .input_mux = &alc883_capture_source,
6811         },
6812         [ALC883_LENOVO_101E_2ch] = {
6813                 .mixers = { alc883_lenovo_101e_2ch_mixer},
6814                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6815                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6816                 .dac_nids = alc883_dac_nids,
6817                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6818                 .adc_nids = alc883_adc_nids,
6819                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6820                 .channel_mode = alc883_3ST_2ch_modes,
6821                 .input_mux = &alc883_lenovo_101e_capture_source,
6822                 .unsol_event = alc883_lenovo_101e_unsol_event,
6823                 .init_hook = alc883_lenovo_101e_all_automute,
6824         },
6825         [ALC883_LENOVO_NB0763] = {
6826                 .mixers = { alc883_lenovo_nb0763_mixer },
6827                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6828                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6829                 .dac_nids = alc883_dac_nids,
6830                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6831                 .adc_nids = alc883_adc_nids,
6832                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6833                 .channel_mode = alc883_3ST_2ch_modes,
6834                 .need_dac_fix = 1,
6835                 .input_mux = &alc883_lenovo_nb0763_capture_source,
6836                 .unsol_event = alc883_medion_md2_unsol_event,
6837                 .init_hook = alc883_medion_md2_automute,
6838         },
6839         [ALC888_LENOVO_MS7195_DIG] = {
6840                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6841                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6842                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6843                 .dac_nids = alc883_dac_nids,
6844                 .dig_out_nid = ALC883_DIGOUT_NID,
6845                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6846                 .adc_nids = alc883_adc_nids,
6847                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6848                 .channel_mode = alc883_3ST_6ch_modes,
6849                 .need_dac_fix = 1,
6850                 .input_mux = &alc883_capture_source,
6851                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
6852                 .init_hook = alc888_lenovo_ms7195_front_automute,
6853         },      
6854         [ALC888_6ST_HP] = {
6855                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
6856                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
6857                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6858                 .dac_nids = alc883_dac_nids,
6859                 .dig_out_nid = ALC883_DIGOUT_NID,
6860                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6861                 .adc_nids = alc883_adc_nids,
6862                 .dig_in_nid = ALC883_DIGIN_NID,
6863                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6864                 .channel_mode = alc883_sixstack_modes,
6865                 .input_mux = &alc883_capture_source,
6866         },
6867         [ALC888_3ST_HP] = {
6868                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
6869                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
6870                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6871                 .dac_nids = alc883_dac_nids,
6872                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6873                 .adc_nids = alc883_adc_nids,
6874                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
6875                 .channel_mode = alc888_3st_hp_modes,
6876                 .need_dac_fix = 1,
6877                 .input_mux = &alc883_capture_source,
6878         },
6879 };
6880
6881
6882 /*
6883  * BIOS auto configuration
6884  */
6885 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6886                                               hda_nid_t nid, int pin_type,
6887                                               int dac_idx)
6888 {
6889         /* set as output */
6890         struct alc_spec *spec = codec->spec;
6891         int idx;
6892
6893         if (spec->multiout.dac_nids[dac_idx] == 0x25)
6894                 idx = 4;
6895         else
6896                 idx = spec->multiout.dac_nids[dac_idx] - 2;
6897
6898         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6899                             pin_type);
6900         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6901                             AMP_OUT_UNMUTE);
6902         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6903
6904 }
6905
6906 static void alc883_auto_init_multi_out(struct hda_codec *codec)
6907 {
6908         struct alc_spec *spec = codec->spec;
6909         int i;
6910
6911         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6912         for (i = 0; i <= HDA_SIDE; i++) {
6913                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6914                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6915                 if (nid)
6916                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6917                                                           i);
6918         }
6919 }
6920
6921 static void alc883_auto_init_hp_out(struct hda_codec *codec)
6922 {
6923         struct alc_spec *spec = codec->spec;
6924         hda_nid_t pin;
6925
6926         pin = spec->autocfg.hp_pins[0];
6927         if (pin) /* connect to front */
6928                 /* use dac 0 */
6929                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6930 }
6931
6932 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
6933 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
6934
6935 static void alc883_auto_init_analog_input(struct hda_codec *codec)
6936 {
6937         struct alc_spec *spec = codec->spec;
6938         int i;
6939
6940         for (i = 0; i < AUTO_PIN_LAST; i++) {
6941                 hda_nid_t nid = spec->autocfg.input_pins[i];
6942                 if (alc883_is_input_pin(nid)) {
6943                         snd_hda_codec_write(codec, nid, 0,
6944                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
6945                                             (i <= AUTO_PIN_FRONT_MIC ?
6946                                              PIN_VREF80 : PIN_IN));
6947                         if (nid != ALC883_PIN_CD_NID)
6948                                 snd_hda_codec_write(codec, nid, 0,
6949                                                     AC_VERB_SET_AMP_GAIN_MUTE,
6950                                                     AMP_OUT_MUTE);
6951                 }
6952         }
6953 }
6954
6955 /* almost identical with ALC880 parser... */
6956 static int alc883_parse_auto_config(struct hda_codec *codec)
6957 {
6958         struct alc_spec *spec = codec->spec;
6959         int err = alc880_parse_auto_config(codec);
6960
6961         if (err < 0)
6962                 return err;
6963         else if (err > 0)
6964                 /* hack - override the init verbs */
6965                 spec->init_verbs[0] = alc883_auto_init_verbs;
6966         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
6967         spec->num_mixers++;
6968         return err;
6969 }
6970
6971 /* additional initialization for auto-configuration model */
6972 static void alc883_auto_init(struct hda_codec *codec)
6973 {
6974         alc883_auto_init_multi_out(codec);
6975         alc883_auto_init_hp_out(codec);
6976         alc883_auto_init_analog_input(codec);
6977 }
6978
6979 static int patch_alc883(struct hda_codec *codec)
6980 {
6981         struct alc_spec *spec;
6982         int err, board_config;
6983
6984         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6985         if (spec == NULL)
6986                 return -ENOMEM;
6987
6988         codec->spec = spec;
6989
6990         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
6991                                                   alc883_models,
6992                                                   alc883_cfg_tbl);
6993         if (board_config < 0) {
6994                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
6995                        "trying auto-probe from BIOS...\n");
6996                 board_config = ALC883_AUTO;
6997         }
6998
6999         if (board_config == ALC883_AUTO) {
7000                 /* automatic parse from the BIOS config */
7001                 err = alc883_parse_auto_config(codec);
7002                 if (err < 0) {
7003                         alc_free(codec);
7004                         return err;
7005                 } else if (!err) {
7006                         printk(KERN_INFO
7007                                "hda_codec: Cannot set up configuration "
7008                                "from BIOS.  Using base mode...\n");
7009                         board_config = ALC883_3ST_2ch_DIG;
7010                 }
7011         }
7012
7013         if (board_config != ALC883_AUTO)
7014                 setup_preset(spec, &alc883_presets[board_config]);
7015
7016         spec->stream_name_analog = "ALC883 Analog";
7017         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7018         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7019
7020         spec->stream_name_digital = "ALC883 Digital";
7021         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7022         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7023
7024         if (!spec->adc_nids && spec->input_mux) {
7025                 spec->adc_nids = alc883_adc_nids;
7026                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7027         }
7028
7029         codec->patch_ops = alc_patch_ops;
7030         if (board_config == ALC883_AUTO)
7031                 spec->init_hook = alc883_auto_init;
7032
7033         return 0;
7034 }
7035
7036 /*
7037  * ALC262 support
7038  */
7039
7040 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7041 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7042
7043 #define alc262_dac_nids         alc260_dac_nids
7044 #define alc262_adc_nids         alc882_adc_nids
7045 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7046
7047 #define alc262_modes            alc260_modes
7048 #define alc262_capture_source   alc882_capture_source
7049
7050 static struct snd_kcontrol_new alc262_base_mixer[] = {
7051         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7052         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7053         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7054         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7055         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7056         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7057         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7058         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7059         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7060         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7061         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7062         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7063         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7064            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7065         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7066         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7067         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7068         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7069         { } /* end */
7070 };
7071
7072 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7073         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7074         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7075         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7076         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7077         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7078         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7079         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7080         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7081         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7082         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7083         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7084         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7085         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7086            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7087         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7088         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7089         { } /* end */
7090 };
7091
7092 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7093         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7094         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7095         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7096         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7097         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7098
7099         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7100         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7101         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7102         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7103         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7104         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7105         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7106         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7107         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7108         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7109         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7110         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7111         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7112         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7113         { } /* end */
7114 };
7115
7116 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7117         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7118         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7119         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7120         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7121         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7122         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7123         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7124         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7125         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7126         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7127         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7128         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7129         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7130         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7131         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7132         { } /* end */
7133 };
7134
7135 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7136         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7137         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7138         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7139         { } /* end */
7140 };
7141
7142 static struct hda_bind_ctls alc262_sony_bind_sw = {
7143         .ops = &snd_hda_bind_sw,
7144         .values = {
7145                 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7146                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7147                 0,
7148         },
7149 };
7150
7151 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7152         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7153         HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw),
7154         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7155         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7156         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7157         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7158         { } /* end */
7159 };
7160
7161 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7162         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7163         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7164         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7165         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7166         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7167         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7168         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7169         { } /* end */
7170 };
7171
7172 #define alc262_capture_mixer            alc882_capture_mixer
7173 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7174
7175 /*
7176  * generic initialization of ADC, input mixers and output mixers
7177  */
7178 static struct hda_verb alc262_init_verbs[] = {
7179         /*
7180          * Unmute ADC0-2 and set the default input to mic-in
7181          */
7182         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7183         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7184         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7185         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7186         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7187         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7188
7189         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7190          * mixer widget
7191          * Note: PASD motherboards uses the Line In 2 as the input for
7192          * front panel mic (mic 2)
7193          */
7194         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7195         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7196         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7197         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7198         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7199         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7200
7201         /*
7202          * Set up output mixers (0x0c - 0x0e)
7203          */
7204         /* set vol=0 to output mixers */
7205         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7206         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7207         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7208         /* set up input amps for analog loopback */
7209         /* Amp Indices: DAC = 0, mixer = 1 */
7210         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7211         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7212         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7213         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7214         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7215         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7216
7217         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7218         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7219         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7220         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7221         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7222         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7223
7224         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7225         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7226         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7227         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7228         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7229         
7230         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7231         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7232         
7233         /* FIXME: use matrix-type input source selection */
7234         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7235         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7236         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7237         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7238         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7239         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7240         /* Input mixer2 */
7241         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7242         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7243         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7244         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7245         /* Input mixer3 */
7246         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7247         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7248         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7249         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7250
7251         { }
7252 };
7253
7254 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7255         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7256         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7257         {}
7258 };
7259
7260 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7261         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7262         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7263         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7264
7265         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7266         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7267         {}
7268 };
7269
7270 static struct hda_verb alc262_sony_unsol_verbs[] = {
7271         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7272         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7273         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7274
7275         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7276         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7277 };
7278
7279 /* mute/unmute internal speaker according to the hp jack and mute state */
7280 static void alc262_hippo_automute(struct hda_codec *codec)
7281 {
7282         struct alc_spec *spec = codec->spec;
7283         unsigned int mute;
7284         unsigned int present;
7285
7286         /* need to execute and sync at first */
7287         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7288         present = snd_hda_codec_read(codec, 0x15, 0,
7289                                      AC_VERB_GET_PIN_SENSE, 0);
7290         spec->jack_present = (present & 0x80000000) != 0;
7291         if (spec->jack_present) {
7292                 /* mute internal speaker */
7293                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7294                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7295         } else {
7296                 /* unmute internal speaker if necessary */
7297                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7298                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7299                                          HDA_AMP_MUTE, mute);
7300         }
7301 }
7302
7303 /* unsolicited event for HP jack sensing */
7304 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7305                                        unsigned int res)
7306 {
7307         if ((res >> 26) != ALC880_HP_EVENT)
7308                 return;
7309         alc262_hippo_automute(codec);
7310 }
7311
7312 static void alc262_hippo1_automute(struct hda_codec *codec)
7313 {
7314         unsigned int mute;
7315         unsigned int present;
7316
7317         snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7318         present = snd_hda_codec_read(codec, 0x1b, 0,
7319                                      AC_VERB_GET_PIN_SENSE, 0);
7320         present = (present & 0x80000000) != 0;
7321         if (present) {
7322                 /* mute internal speaker */
7323                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7324                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7325         } else {
7326                 /* unmute internal speaker if necessary */
7327                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7328                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7329                                          HDA_AMP_MUTE, mute);
7330         }
7331 }
7332
7333 /* unsolicited event for HP jack sensing */
7334 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7335                                        unsigned int res)
7336 {
7337         if ((res >> 26) != ALC880_HP_EVENT)
7338                 return;
7339         alc262_hippo1_automute(codec);
7340 }
7341
7342 /*
7343  * fujitsu model
7344  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7345  */
7346
7347 #define ALC_HP_EVENT    0x37
7348
7349 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7350         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7351         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7352         {}
7353 };
7354
7355 static struct hda_input_mux alc262_fujitsu_capture_source = {
7356         .num_items = 2,
7357         .items = {
7358                 { "Mic", 0x0 },
7359                 { "CD", 0x4 },
7360         },
7361 };
7362
7363 static struct hda_input_mux alc262_HP_capture_source = {
7364         .num_items = 5,
7365         .items = {
7366                 { "Mic", 0x0 },
7367                 { "Front Mic", 0x3 },
7368                 { "Line", 0x2 },
7369                 { "CD", 0x4 },
7370                 { "AUX IN", 0x6 },
7371         },
7372 };
7373
7374 /* mute/unmute internal speaker according to the hp jack and mute state */
7375 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7376 {
7377         struct alc_spec *spec = codec->spec;
7378         unsigned int mute;
7379
7380         if (force || !spec->sense_updated) {
7381                 unsigned int present;
7382                 /* need to execute and sync at first */
7383                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7384                 present = snd_hda_codec_read(codec, 0x14, 0,
7385                                          AC_VERB_GET_PIN_SENSE, 0);
7386                 spec->jack_present = (present & 0x80000000) != 0;
7387                 spec->sense_updated = 1;
7388         }
7389         if (spec->jack_present) {
7390                 /* mute internal speaker */
7391                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7392                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7393         } else {
7394                 /* unmute internal speaker if necessary */
7395                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7396                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7397                                          HDA_AMP_MUTE, mute);
7398         }
7399 }
7400
7401 /* unsolicited event for HP jack sensing */
7402 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7403                                        unsigned int res)
7404 {
7405         if ((res >> 26) != ALC_HP_EVENT)
7406                 return;
7407         alc262_fujitsu_automute(codec, 1);
7408 }
7409
7410 /* bind volumes of both NID 0x0c and 0x0d */
7411 static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
7412                                          struct snd_ctl_elem_value *ucontrol)
7413 {
7414         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7415         long *valp = ucontrol->value.integer.value;
7416         int change;
7417
7418         change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
7419                                           HDA_AMP_VOLMASK, valp[0]);
7420         change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
7421                                            HDA_AMP_VOLMASK, valp[1]);
7422         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
7423                                  HDA_AMP_VOLMASK, valp[0]);
7424         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
7425                                  HDA_AMP_VOLMASK, valp[1]);
7426         return change;
7427 }
7428
7429 /* bind hp and internal speaker mute (with plug check) */
7430 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7431                                          struct snd_ctl_elem_value *ucontrol)
7432 {
7433         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7434         long *valp = ucontrol->value.integer.value;
7435         int change;
7436
7437         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7438                                           HDA_AMP_MUTE,
7439                                           valp[0] ? 0 : HDA_AMP_MUTE);
7440         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7441                                            HDA_AMP_MUTE,
7442                                            valp[1] ? 0 : HDA_AMP_MUTE);
7443         if (change)
7444                 alc262_fujitsu_automute(codec, 0);
7445         return change;
7446 }
7447
7448 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7449         {
7450                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7451                 .name = "Master Playback Volume",
7452                 .info = snd_hda_mixer_amp_volume_info,
7453                 .get = snd_hda_mixer_amp_volume_get,
7454                 .put = alc262_fujitsu_master_vol_put,
7455                 .tlv = { .c = snd_hda_mixer_amp_tlv },
7456                 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7457         },
7458         {
7459                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7460                 .name = "Master Playback Switch",
7461                 .info = snd_hda_mixer_amp_switch_info,
7462                 .get = snd_hda_mixer_amp_switch_get,
7463                 .put = alc262_fujitsu_master_sw_put,
7464                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7465         },
7466         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7467         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7468         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7469         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7470         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7471         { } /* end */
7472 };
7473
7474 /* additional init verbs for Benq laptops */
7475 static struct hda_verb alc262_EAPD_verbs[] = {
7476         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7477         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7478         {}
7479 };
7480
7481 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7482         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7483         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7484
7485         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7486         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7487         {}
7488 };
7489
7490 /* add playback controls from the parsed DAC table */
7491 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7492                                              const struct auto_pin_cfg *cfg)
7493 {
7494         hda_nid_t nid;
7495         int err;
7496
7497         spec->multiout.num_dacs = 1;    /* only use one dac */
7498         spec->multiout.dac_nids = spec->private_dac_nids;
7499         spec->multiout.dac_nids[0] = 2;
7500
7501         nid = cfg->line_out_pins[0];
7502         if (nid) {
7503                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7504                                   "Front Playback Volume",
7505                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7506                 if (err < 0)
7507                         return err;
7508                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7509                                   "Front Playback Switch",
7510                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7511                 if (err < 0)
7512                         return err;
7513         }
7514
7515         nid = cfg->speaker_pins[0];
7516         if (nid) {
7517                 if (nid == 0x16) {
7518                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7519                                           "Speaker Playback Volume",
7520                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7521                                                               HDA_OUTPUT));
7522                         if (err < 0)
7523                                 return err;
7524                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7525                                           "Speaker Playback Switch",
7526                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7527                                                               HDA_OUTPUT));
7528                         if (err < 0)
7529                                 return err;
7530                 } else {
7531                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7532                                           "Speaker Playback Switch",
7533                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7534                                                               HDA_OUTPUT));
7535                         if (err < 0)
7536                                 return err;
7537                 }
7538         }
7539         nid = cfg->hp_pins[0];
7540         if (nid) {
7541                 /* spec->multiout.hp_nid = 2; */
7542                 if (nid == 0x16) {
7543                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7544                                           "Headphone Playback Volume",
7545                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7546                                                               HDA_OUTPUT));
7547                         if (err < 0)
7548                                 return err;
7549                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7550                                           "Headphone Playback Switch",
7551                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7552                                                               HDA_OUTPUT));
7553                         if (err < 0)
7554                                 return err;
7555                 } else {
7556                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7557                                           "Headphone Playback Switch",
7558                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7559                                                               HDA_OUTPUT));
7560                         if (err < 0)
7561                                 return err;
7562                 }
7563         }
7564         return 0;
7565 }
7566
7567 /* identical with ALC880 */
7568 #define alc262_auto_create_analog_input_ctls \
7569         alc880_auto_create_analog_input_ctls
7570
7571 /*
7572  * generic initialization of ADC, input mixers and output mixers
7573  */
7574 static struct hda_verb alc262_volume_init_verbs[] = {
7575         /*
7576          * Unmute ADC0-2 and set the default input to mic-in
7577          */
7578         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7579         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7580         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7581         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7582         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7583         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7584
7585         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7586          * mixer widget
7587          * Note: PASD motherboards uses the Line In 2 as the input for
7588          * front panel mic (mic 2)
7589          */
7590         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7591         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7592         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7593         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7594         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7595         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7596
7597         /*
7598          * Set up output mixers (0x0c - 0x0f)
7599          */
7600         /* set vol=0 to output mixers */
7601         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7602         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7603         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7604         
7605         /* set up input amps for analog loopback */
7606         /* Amp Indices: DAC = 0, mixer = 1 */
7607         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7608         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7609         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7610         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7611         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7612         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7613
7614         /* FIXME: use matrix-type input source selection */
7615         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7616         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7617         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7618         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7619         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7620         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7621         /* Input mixer2 */
7622         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7623         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7624         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7625         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7626         /* Input mixer3 */
7627         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7628         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7629         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7630         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7631
7632         { }
7633 };
7634
7635 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7636         /*
7637          * Unmute ADC0-2 and set the default input to mic-in
7638          */
7639         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7640         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7641         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7642         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7643         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7644         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7645
7646         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7647          * mixer widget
7648          * Note: PASD motherboards uses the Line In 2 as the input for
7649          * front panel mic (mic 2)
7650          */
7651         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7652         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7653         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7654         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7655         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7656         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7657         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7658         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7659         
7660         /*
7661          * Set up output mixers (0x0c - 0x0e)
7662          */
7663         /* set vol=0 to output mixers */
7664         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7665         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7666         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7667
7668         /* set up input amps for analog loopback */
7669         /* Amp Indices: DAC = 0, mixer = 1 */
7670         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7671         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7672         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7673         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7674         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7675         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7676
7677         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7678         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7679         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7680
7681         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7682         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7683
7684         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7685         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7686
7687         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7688         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7689         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7690         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7691         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7692
7693         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7694         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7695         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7696         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7697         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7698         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7699
7700
7701         /* FIXME: use matrix-type input source selection */
7702         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7703         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7704         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7705         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7706         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7707         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7708         /* Input mixer2 */
7709         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7710         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7711         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7712         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7713         /* Input mixer3 */
7714         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7715         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7716         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7717         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7718
7719         { }
7720 };
7721
7722 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7723         /*
7724          * Unmute ADC0-2 and set the default input to mic-in
7725          */
7726         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7727         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7728         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7729         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7730         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7731         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7732
7733         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7734          * mixer widget
7735          * Note: PASD motherboards uses the Line In 2 as the input for front
7736          * panel mic (mic 2)
7737          */
7738         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7739         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7740         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7741         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7742         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7743         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7744         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7745         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7746         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
7747         /*
7748          * Set up output mixers (0x0c - 0x0e)
7749          */
7750         /* set vol=0 to output mixers */
7751         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7752         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7753         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7754
7755         /* set up input amps for analog loopback */
7756         /* Amp Indices: DAC = 0, mixer = 1 */
7757         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7758         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7759         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7760         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7761         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7762         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7763
7764
7765         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
7766         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
7767         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
7768         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
7769         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
7770         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
7771         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
7772
7773         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7774         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7775
7776         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7777         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7778
7779         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7780         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7781         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7782         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7783         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7784         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7785
7786         /* FIXME: use matrix-type input source selection */
7787         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7788         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7789         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7790         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7791         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7792         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7793         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7794         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7795         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7796         /* Input mixer2 */
7797         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7798         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7799         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7800         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7801         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7802         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7803         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7804         /* Input mixer3 */
7805         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7806         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7807         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7808         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7809         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7810         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7811         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7812
7813         { }
7814 };
7815
7816 /* pcm configuration: identiacal with ALC880 */
7817 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
7818 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
7819 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
7820 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
7821
7822 /*
7823  * BIOS auto configuration
7824  */
7825 static int alc262_parse_auto_config(struct hda_codec *codec)
7826 {
7827         struct alc_spec *spec = codec->spec;
7828         int err;
7829         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7830
7831         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7832                                            alc262_ignore);
7833         if (err < 0)
7834                 return err;
7835         if (!spec->autocfg.line_outs)
7836                 return 0; /* can't find valid BIOS pin config */
7837         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7838         if (err < 0)
7839                 return err;
7840         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7841         if (err < 0)
7842                 return err;
7843
7844         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7845
7846         if (spec->autocfg.dig_out_pin)
7847                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7848         if (spec->autocfg.dig_in_pin)
7849                 spec->dig_in_nid = ALC262_DIGIN_NID;
7850
7851         if (spec->kctl_alloc)
7852                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7853
7854         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7855         spec->num_mux_defs = 1;
7856         spec->input_mux = &spec->private_imux;
7857
7858         return 1;
7859 }
7860
7861 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
7862 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
7863 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
7864
7865
7866 /* init callback for auto-configuration model -- overriding the default init */
7867 static void alc262_auto_init(struct hda_codec *codec)
7868 {
7869         alc262_auto_init_multi_out(codec);
7870         alc262_auto_init_hp_out(codec);
7871         alc262_auto_init_analog_input(codec);
7872 }
7873
7874 /*
7875  * configuration and preset
7876  */
7877 static const char *alc262_models[ALC262_MODEL_LAST] = {
7878         [ALC262_BASIC]          = "basic",
7879         [ALC262_HIPPO]          = "hippo",
7880         [ALC262_HIPPO_1]        = "hippo_1",
7881         [ALC262_FUJITSU]        = "fujitsu",
7882         [ALC262_HP_BPC]         = "hp-bpc",
7883         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7884         [ALC262_BENQ_ED8]       = "benq",
7885         [ALC262_BENQ_T31]       = "benq-t31",
7886         [ALC262_SONY_ASSAMD]    = "sony-assamd",
7887         [ALC262_AUTO]           = "auto",
7888 };
7889
7890 static struct snd_pci_quirk alc262_cfg_tbl[] = {
7891         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7892         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7893         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7894         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7895         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7896         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7897         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7898         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7899         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7900         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7901         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7902         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7903         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7904         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7905         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7906         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7907         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7908         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7909         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7910         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7911         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7912         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7913         SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7914         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7915         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7916         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7917         {}
7918 };
7919
7920 static struct alc_config_preset alc262_presets[] = {
7921         [ALC262_BASIC] = {
7922                 .mixers = { alc262_base_mixer },
7923                 .init_verbs = { alc262_init_verbs },
7924                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7925                 .dac_nids = alc262_dac_nids,
7926                 .hp_nid = 0x03,
7927                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7928                 .channel_mode = alc262_modes,
7929                 .input_mux = &alc262_capture_source,
7930         },
7931         [ALC262_HIPPO] = {
7932                 .mixers = { alc262_base_mixer },
7933                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
7934                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7935                 .dac_nids = alc262_dac_nids,
7936                 .hp_nid = 0x03,
7937                 .dig_out_nid = ALC262_DIGOUT_NID,
7938                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7939                 .channel_mode = alc262_modes,
7940                 .input_mux = &alc262_capture_source,
7941                 .unsol_event = alc262_hippo_unsol_event,
7942                 .init_hook = alc262_hippo_automute,
7943         },
7944         [ALC262_HIPPO_1] = {
7945                 .mixers = { alc262_hippo1_mixer },
7946                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
7947                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7948                 .dac_nids = alc262_dac_nids,
7949                 .hp_nid = 0x02,
7950                 .dig_out_nid = ALC262_DIGOUT_NID,
7951                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7952                 .channel_mode = alc262_modes,
7953                 .input_mux = &alc262_capture_source,
7954                 .unsol_event = alc262_hippo1_unsol_event,
7955                 .init_hook = alc262_hippo1_automute,
7956         },
7957         [ALC262_FUJITSU] = {
7958                 .mixers = { alc262_fujitsu_mixer },
7959                 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
7960                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7961                 .dac_nids = alc262_dac_nids,
7962                 .hp_nid = 0x03,
7963                 .dig_out_nid = ALC262_DIGOUT_NID,
7964                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7965                 .channel_mode = alc262_modes,
7966                 .input_mux = &alc262_fujitsu_capture_source,
7967                 .unsol_event = alc262_fujitsu_unsol_event,
7968         },
7969         [ALC262_HP_BPC] = {
7970                 .mixers = { alc262_HP_BPC_mixer },
7971                 .init_verbs = { alc262_HP_BPC_init_verbs },
7972                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7973                 .dac_nids = alc262_dac_nids,
7974                 .hp_nid = 0x03,
7975                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7976                 .channel_mode = alc262_modes,
7977                 .input_mux = &alc262_HP_capture_source,
7978         },
7979         [ALC262_HP_BPC_D7000_WF] = {
7980                 .mixers = { alc262_HP_BPC_WildWest_mixer },
7981                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7982                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7983                 .dac_nids = alc262_dac_nids,
7984                 .hp_nid = 0x03,
7985                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7986                 .channel_mode = alc262_modes,
7987                 .input_mux = &alc262_HP_capture_source,
7988         },
7989         [ALC262_HP_BPC_D7000_WL] = {
7990                 .mixers = { alc262_HP_BPC_WildWest_mixer,
7991                             alc262_HP_BPC_WildWest_option_mixer },
7992                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7993                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7994                 .dac_nids = alc262_dac_nids,
7995                 .hp_nid = 0x03,
7996                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7997                 .channel_mode = alc262_modes,
7998                 .input_mux = &alc262_HP_capture_source,
7999         },
8000         [ALC262_BENQ_ED8] = {
8001                 .mixers = { alc262_base_mixer },
8002                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8003                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8004                 .dac_nids = alc262_dac_nids,
8005                 .hp_nid = 0x03,
8006                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8007                 .channel_mode = alc262_modes,
8008                 .input_mux = &alc262_capture_source,
8009         },
8010         [ALC262_SONY_ASSAMD] = {
8011                 .mixers = { alc262_sony_mixer },
8012                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8013                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8014                 .dac_nids = alc262_dac_nids,
8015                 .hp_nid = 0x02,
8016                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8017                 .channel_mode = alc262_modes,
8018                 .input_mux = &alc262_capture_source,
8019                 .unsol_event = alc262_hippo_unsol_event,
8020                 .init_hook = alc262_hippo_automute,
8021         },
8022         [ALC262_BENQ_T31] = {
8023                 .mixers = { alc262_benq_t31_mixer },
8024                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8025                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8026                 .dac_nids = alc262_dac_nids,
8027                 .hp_nid = 0x03,
8028                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8029                 .channel_mode = alc262_modes,
8030                 .input_mux = &alc262_capture_source,
8031                 .unsol_event = alc262_hippo_unsol_event,
8032                 .init_hook = alc262_hippo_automute,
8033         },      
8034 };
8035
8036 static int patch_alc262(struct hda_codec *codec)
8037 {
8038         struct alc_spec *spec;
8039         int board_config;
8040         int err;
8041
8042         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8043         if (spec == NULL)
8044                 return -ENOMEM;
8045
8046         codec->spec = spec;
8047 #if 0
8048         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8049          * under-run
8050          */
8051         {
8052         int tmp;
8053         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8054         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8055         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8056         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8057         }
8058 #endif
8059
8060         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8061                                                   alc262_models,
8062                                                   alc262_cfg_tbl);
8063
8064         if (board_config < 0) {
8065                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8066                        "trying auto-probe from BIOS...\n");
8067                 board_config = ALC262_AUTO;
8068         }
8069
8070         if (board_config == ALC262_AUTO) {
8071                 /* automatic parse from the BIOS config */
8072                 err = alc262_parse_auto_config(codec);
8073                 if (err < 0) {
8074                         alc_free(codec);
8075                         return err;
8076                 } else if (!err) {
8077                         printk(KERN_INFO
8078                                "hda_codec: Cannot set up configuration "
8079                                "from BIOS.  Using base mode...\n");
8080                         board_config = ALC262_BASIC;
8081                 }
8082         }
8083
8084         if (board_config != ALC262_AUTO)
8085                 setup_preset(spec, &alc262_presets[board_config]);
8086
8087         spec->stream_name_analog = "ALC262 Analog";
8088         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8089         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8090                 
8091         spec->stream_name_digital = "ALC262 Digital";
8092         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8093         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8094
8095         if (!spec->adc_nids && spec->input_mux) {
8096                 /* check whether NID 0x07 is valid */
8097                 unsigned int wcap = get_wcaps(codec, 0x07);
8098
8099                 /* get type */
8100                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8101                 if (wcap != AC_WID_AUD_IN) {
8102                         spec->adc_nids = alc262_adc_nids_alt;
8103                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8104                         spec->mixers[spec->num_mixers] =
8105                                 alc262_capture_alt_mixer;
8106                         spec->num_mixers++;
8107                 } else {
8108                         spec->adc_nids = alc262_adc_nids;
8109                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8110                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8111                         spec->num_mixers++;
8112                 }
8113         }
8114
8115         codec->patch_ops = alc_patch_ops;
8116         if (board_config == ALC262_AUTO)
8117                 spec->init_hook = alc262_auto_init;
8118                 
8119         return 0;
8120 }
8121
8122 /*
8123  *  ALC268 channel source setting (2 channel)
8124  */
8125 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8126 #define alc268_modes            alc260_modes
8127         
8128 static hda_nid_t alc268_dac_nids[2] = {
8129         /* front, hp */
8130         0x02, 0x03
8131 };
8132
8133 static hda_nid_t alc268_adc_nids[2] = {
8134         /* ADC0-1 */
8135         0x08, 0x07
8136 };
8137
8138 static hda_nid_t alc268_adc_nids_alt[1] = {
8139         /* ADC0 */
8140         0x08
8141 };
8142
8143 static struct snd_kcontrol_new alc268_base_mixer[] = {
8144         /* output mixer control */
8145         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8146         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8147         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8148         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8149         { }
8150 };
8151
8152 /*
8153  * generic initialization of ADC, input mixers and output mixers
8154  */
8155 static struct hda_verb alc268_base_init_verbs[] = {
8156         /* Unmute DAC0-1 and set vol = 0 */
8157         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8158         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8159         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8160         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8161         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8162         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8163
8164         /*
8165          * Set up output mixers (0x0c - 0x0e)
8166          */
8167         /* set vol=0 to output mixers */
8168         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8169         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8170         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8171         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8172
8173         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8174         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8175
8176         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8177         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8178         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8179         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8180         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8181         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8182         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8183         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8184
8185         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8186         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8187         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8188         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8189         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8190         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8191         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8192         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8193
8194         /* FIXME: use matrix-type input source selection */
8195         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8196         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8197         /* Input mixer2 */
8198         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8199         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8200         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8201         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8202
8203         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8204         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8205         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8206         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8207         { }
8208 };
8209
8210 /*
8211  * generic initialization of ADC, input mixers and output mixers
8212  */
8213 static struct hda_verb alc268_volume_init_verbs[] = {
8214         /* set output DAC */
8215         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8216         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8217         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8218         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8219
8220         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8221         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8222         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8223         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8224         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8225
8226         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8227         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8228         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8229         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8230         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8231
8232         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8233         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8234         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8235         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8236
8237         /* set PCBEEP vol = 0 */
8238         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8239
8240         { }
8241 };
8242
8243 #define alc268_mux_enum_info alc_mux_enum_info
8244 #define alc268_mux_enum_get alc_mux_enum_get
8245
8246 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8247                                struct snd_ctl_elem_value *ucontrol)
8248 {
8249         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8250         struct alc_spec *spec = codec->spec;
8251         const struct hda_input_mux *imux = spec->input_mux;
8252         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8253         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8254         hda_nid_t nid = capture_mixers[adc_idx];
8255         unsigned int *cur_val = &spec->cur_mux[adc_idx];
8256         unsigned int i, idx;
8257
8258         idx = ucontrol->value.enumerated.item[0];
8259         if (idx >= imux->num_items)
8260                 idx = imux->num_items - 1;
8261         if (*cur_val == idx)
8262                 return 0;
8263         for (i = 0; i < imux->num_items; i++) {
8264                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
8265                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
8266                                          imux->items[i].index,
8267                                          HDA_AMP_MUTE, v);
8268                 snd_hda_codec_write_cache(codec, nid, 0,
8269                                           AC_VERB_SET_CONNECT_SEL,
8270                                           idx );
8271         }
8272         *cur_val = idx;
8273         return 1;
8274 }
8275
8276 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8277         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8278         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8279         {
8280                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8281                 /* The multiple "Capture Source" controls confuse alsamixer
8282                  * So call somewhat different..
8283                  * FIXME: the controls appear in the "playback" view!
8284                  */
8285                 /* .name = "Capture Source", */
8286                 .name = "Input Source",
8287                 .count = 1,
8288                 .info = alc268_mux_enum_info,
8289                 .get = alc268_mux_enum_get,
8290                 .put = alc268_mux_enum_put,
8291         },
8292         { } /* end */
8293 };
8294
8295 static struct snd_kcontrol_new alc268_capture_mixer[] = {
8296         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8297         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8298         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8299         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8300         {
8301                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8302                 /* The multiple "Capture Source" controls confuse alsamixer
8303                  * So call somewhat different..
8304                  * FIXME: the controls appear in the "playback" view!
8305                  */
8306                 /* .name = "Capture Source", */
8307                 .name = "Input Source",
8308                 .count = 2,
8309                 .info = alc268_mux_enum_info,
8310                 .get = alc268_mux_enum_get,
8311                 .put = alc268_mux_enum_put,
8312         },
8313         { } /* end */
8314 };
8315
8316 static struct hda_input_mux alc268_capture_source = {
8317         .num_items = 4,
8318         .items = {
8319                 { "Mic", 0x0 },
8320                 { "Front Mic", 0x1 },
8321                 { "Line", 0x2 },
8322                 { "CD", 0x3 },
8323         },
8324 };
8325
8326 /* create input playback/capture controls for the given pin */
8327 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8328                                     const char *ctlname, int idx)
8329 {
8330         char name[32];
8331         int err;
8332
8333         sprintf(name, "%s Playback Volume", ctlname);
8334         if (nid == 0x14) {
8335                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8336                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8337                                                       HDA_OUTPUT));
8338                 if (err < 0)
8339                         return err;
8340         } else if (nid == 0x15) {
8341                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8342                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8343                                                       HDA_OUTPUT));
8344                 if (err < 0)
8345                         return err;
8346         } else
8347                 return -1;
8348         sprintf(name, "%s Playback Switch", ctlname);
8349         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8350                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8351         if (err < 0)
8352                 return err;
8353         return 0;
8354 }
8355
8356 /* add playback controls from the parsed DAC table */
8357 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8358                                              const struct auto_pin_cfg *cfg)
8359 {
8360         hda_nid_t nid;
8361         int err;
8362
8363         spec->multiout.num_dacs = 2;    /* only use one dac */
8364         spec->multiout.dac_nids = spec->private_dac_nids;
8365         spec->multiout.dac_nids[0] = 2;
8366         spec->multiout.dac_nids[1] = 3;
8367
8368         nid = cfg->line_out_pins[0];
8369         if (nid)
8370                 alc268_new_analog_output(spec, nid, "Front", 0);        
8371
8372         nid = cfg->speaker_pins[0];
8373         if (nid == 0x1d) {
8374                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8375                                   "Speaker Playback Volume",
8376                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8377                 if (err < 0)
8378                         return err;
8379         }
8380         nid = cfg->hp_pins[0];
8381         if (nid)
8382                 alc268_new_analog_output(spec, nid, "Headphone", 0);
8383
8384         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8385         if (nid == 0x16) {
8386                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8387                                   "Mono Playback Switch",
8388                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8389                 if (err < 0)
8390                         return err;
8391         }
8392         return 0;       
8393 }
8394
8395 /* create playback/capture controls for input pins */
8396 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8397                                                 const struct auto_pin_cfg *cfg)
8398 {
8399         struct hda_input_mux *imux = &spec->private_imux;
8400         int i, idx1;
8401
8402         for (i = 0; i < AUTO_PIN_LAST; i++) {
8403                 switch(cfg->input_pins[i]) {
8404                 case 0x18:
8405                         idx1 = 0;       /* Mic 1 */
8406                         break;
8407                 case 0x19:
8408                         idx1 = 1;       /* Mic 2 */
8409                         break;
8410                 case 0x1a:
8411                         idx1 = 2;       /* Line In */
8412                         break;
8413                 case 0x1c:      
8414                         idx1 = 3;       /* CD */
8415                         break;
8416                 default:
8417                         continue;
8418                 }
8419                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8420                 imux->items[imux->num_items].index = idx1;
8421                 imux->num_items++;      
8422         }
8423         return 0;
8424 }
8425
8426 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8427 {
8428         struct alc_spec *spec = codec->spec;
8429         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8430         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8431         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8432         unsigned int    dac_vol1, dac_vol2;
8433
8434         if (speaker_nid) {
8435                 snd_hda_codec_write(codec, speaker_nid, 0,
8436                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8437                 snd_hda_codec_write(codec, 0x0f, 0,
8438                                     AC_VERB_SET_AMP_GAIN_MUTE,
8439                                     AMP_IN_UNMUTE(1));
8440                 snd_hda_codec_write(codec, 0x10, 0,
8441                                     AC_VERB_SET_AMP_GAIN_MUTE,
8442                                     AMP_IN_UNMUTE(1));
8443         } else {
8444                 snd_hda_codec_write(codec, 0x0f, 0,
8445                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8446                 snd_hda_codec_write(codec, 0x10, 0,
8447                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8448         }
8449
8450         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
8451         if (line_nid == 0x14)   
8452                 dac_vol2 = AMP_OUT_ZERO;
8453         else if (line_nid == 0x15)
8454                 dac_vol1 = AMP_OUT_ZERO;
8455         if (hp_nid == 0x14)     
8456                 dac_vol2 = AMP_OUT_ZERO;
8457         else if (hp_nid == 0x15)
8458                 dac_vol1 = AMP_OUT_ZERO;
8459         if (line_nid != 0x16 || hp_nid != 0x16 ||
8460             spec->autocfg.line_out_pins[1] != 0x16 ||
8461             spec->autocfg.line_out_pins[2] != 0x16)
8462                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8463
8464         snd_hda_codec_write(codec, 0x02, 0,
8465                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8466         snd_hda_codec_write(codec, 0x03, 0,
8467                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8468 }
8469
8470 /* pcm configuration: identiacal with ALC880 */
8471 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
8472 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
8473 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
8474
8475 /*
8476  * BIOS auto configuration
8477  */
8478 static int alc268_parse_auto_config(struct hda_codec *codec)
8479 {
8480         struct alc_spec *spec = codec->spec;
8481         int err;
8482         static hda_nid_t alc268_ignore[] = { 0 };
8483
8484         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8485                                            alc268_ignore);
8486         if (err < 0)
8487                 return err;
8488         if (!spec->autocfg.line_outs)
8489                 return 0; /* can't find valid BIOS pin config */
8490
8491         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8492         if (err < 0)
8493                 return err;
8494         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8495         if (err < 0)
8496                 return err;
8497
8498         spec->multiout.max_channels = 2;
8499
8500         /* digital only support output */
8501         if (spec->autocfg.dig_out_pin)
8502                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8503
8504         if (spec->kctl_alloc)
8505                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8506
8507         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8508         spec->num_mux_defs = 1;
8509         spec->input_mux = &spec->private_imux;
8510
8511         return 1;
8512 }
8513
8514 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
8515 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
8516 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
8517
8518 /* init callback for auto-configuration model -- overriding the default init */
8519 static void alc268_auto_init(struct hda_codec *codec)
8520 {
8521         alc268_auto_init_multi_out(codec);
8522         alc268_auto_init_hp_out(codec);
8523         alc268_auto_init_mono_speaker_out(codec);
8524         alc268_auto_init_analog_input(codec);
8525 }
8526
8527 /*
8528  * configuration and preset
8529  */
8530 static const char *alc268_models[ALC268_MODEL_LAST] = {
8531         [ALC268_3ST]            = "3stack",
8532         [ALC268_AUTO]           = "auto",
8533 };
8534
8535 static struct snd_pci_quirk alc268_cfg_tbl[] = {
8536         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8537         {}
8538 };
8539
8540 static struct alc_config_preset alc268_presets[] = {
8541         [ALC268_3ST] = {
8542                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8543                 .init_verbs = { alc268_base_init_verbs },
8544                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8545                 .dac_nids = alc268_dac_nids,
8546                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8547                 .adc_nids = alc268_adc_nids_alt,
8548                 .hp_nid = 0x03,
8549                 .dig_out_nid = ALC268_DIGOUT_NID,
8550                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8551                 .channel_mode = alc268_modes,
8552                 .input_mux = &alc268_capture_source,
8553         },
8554 };
8555
8556 static int patch_alc268(struct hda_codec *codec)
8557 {
8558         struct alc_spec *spec;
8559         int board_config;
8560         int err;
8561
8562         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8563         if (spec == NULL)
8564                 return -ENOMEM;
8565
8566         codec->spec = spec;
8567
8568         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8569                                                   alc268_models,
8570                                                   alc268_cfg_tbl);
8571
8572         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8573                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8574                        "trying auto-probe from BIOS...\n");
8575                 board_config = ALC268_AUTO;
8576         }
8577
8578         if (board_config == ALC268_AUTO) {
8579                 /* automatic parse from the BIOS config */
8580                 err = alc268_parse_auto_config(codec);
8581                 if (err < 0) {
8582                         alc_free(codec);
8583                         return err;
8584                 } else if (!err) {
8585                         printk(KERN_INFO
8586                                "hda_codec: Cannot set up configuration "
8587                                "from BIOS.  Using base mode...\n");
8588                         board_config = ALC268_3ST;
8589                 }
8590         }
8591
8592         if (board_config != ALC268_AUTO)
8593                 setup_preset(spec, &alc268_presets[board_config]);
8594
8595         spec->stream_name_analog = "ALC268 Analog";
8596         spec->stream_analog_playback = &alc268_pcm_analog_playback;
8597         spec->stream_analog_capture = &alc268_pcm_analog_capture;
8598
8599         spec->stream_name_digital = "ALC268 Digital";
8600         spec->stream_digital_playback = &alc268_pcm_digital_playback;
8601
8602         if (board_config == ALC268_AUTO) {
8603                 if (!spec->adc_nids && spec->input_mux) {
8604                         /* check whether NID 0x07 is valid */
8605                         unsigned int wcap = get_wcaps(codec, 0x07);
8606
8607                         /* get type */
8608                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8609                         if (wcap != AC_WID_AUD_IN) {
8610                                 spec->adc_nids = alc268_adc_nids_alt;
8611                                 spec->num_adc_nids =
8612                                         ARRAY_SIZE(alc268_adc_nids_alt);
8613                                 spec->mixers[spec->num_mixers] =
8614                                         alc268_capture_alt_mixer;
8615                                 spec->num_mixers++;
8616                         } else {
8617                                 spec->adc_nids = alc268_adc_nids;
8618                                 spec->num_adc_nids =
8619                                         ARRAY_SIZE(alc268_adc_nids);
8620                                 spec->mixers[spec->num_mixers] =
8621                                         alc268_capture_mixer;
8622                                 spec->num_mixers++;
8623                         }
8624                 }
8625         }
8626         codec->patch_ops = alc_patch_ops;
8627         if (board_config == ALC268_AUTO)
8628                 spec->init_hook = alc268_auto_init;
8629                 
8630         return 0;
8631 }
8632
8633 /*
8634  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8635  */
8636
8637 /*
8638  * set the path ways for 2 channel output
8639  * need to set the codec line out and mic 1 pin widgets to inputs
8640  */
8641 static struct hda_verb alc861_threestack_ch2_init[] = {
8642         /* set pin widget 1Ah (line in) for input */
8643         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8644         /* set pin widget 18h (mic1/2) for input, for mic also enable
8645          * the vref
8646          */
8647         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8648
8649         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8650 #if 0
8651         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8652         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8653 #endif
8654         { } /* end */
8655 };
8656 /*
8657  * 6ch mode
8658  * need to set the codec line out and mic 1 pin widgets to outputs
8659  */
8660 static struct hda_verb alc861_threestack_ch6_init[] = {
8661         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8662         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8663         /* set pin widget 18h (mic1) for output (CLFE)*/
8664         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8665
8666         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8667         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8668
8669         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8670 #if 0
8671         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8672         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8673 #endif
8674         { } /* end */
8675 };
8676
8677 static struct hda_channel_mode alc861_threestack_modes[2] = {
8678         { 2, alc861_threestack_ch2_init },
8679         { 6, alc861_threestack_ch6_init },
8680 };
8681 /* Set mic1 as input and unmute the mixer */
8682 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8683         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8684         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8685         { } /* end */
8686 };
8687 /* Set mic1 as output and mute mixer */
8688 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8689         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8690         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8691         { } /* end */
8692 };
8693
8694 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8695         { 2, alc861_uniwill_m31_ch2_init },
8696         { 4, alc861_uniwill_m31_ch4_init },
8697 };
8698
8699 /* Set mic1 and line-in as input and unmute the mixer */
8700 static struct hda_verb alc861_asus_ch2_init[] = {
8701         /* set pin widget 1Ah (line in) for input */
8702         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8703         /* set pin widget 18h (mic1/2) for input, for mic also enable
8704          * the vref
8705          */
8706         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8707
8708         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8709 #if 0
8710         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8711         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8712 #endif
8713         { } /* end */
8714 };
8715 /* Set mic1 nad line-in as output and mute mixer */
8716 static struct hda_verb alc861_asus_ch6_init[] = {
8717         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8718         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8719         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8720         /* set pin widget 18h (mic1) for output (CLFE)*/
8721         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8722         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8723         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8724         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8725
8726         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8727 #if 0
8728         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8729         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8730 #endif
8731         { } /* end */
8732 };
8733
8734 static struct hda_channel_mode alc861_asus_modes[2] = {
8735         { 2, alc861_asus_ch2_init },
8736         { 6, alc861_asus_ch6_init },
8737 };
8738
8739 /* patch-ALC861 */
8740
8741 static struct snd_kcontrol_new alc861_base_mixer[] = {
8742         /* output mixer control */
8743         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8744         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8745         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8746         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8747         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8748
8749         /*Input mixer control */
8750         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8751            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8752         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8753         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8754         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8755         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8756         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8757         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8758         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8759         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8760
8761         /* Capture mixer control */
8762         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8763         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8764         {
8765                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8766                 .name = "Capture Source",
8767                 .count = 1,
8768                 .info = alc_mux_enum_info,
8769                 .get = alc_mux_enum_get,
8770                 .put = alc_mux_enum_put,
8771         },
8772         { } /* end */
8773 };
8774
8775 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8776         /* output mixer control */
8777         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8778         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8779         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8780         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8781         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8782
8783         /* Input mixer control */
8784         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8785            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8786         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8787         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8788         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8789         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8790         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8791         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8792         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8793         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8794
8795         /* Capture mixer control */
8796         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8797         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8798         {
8799                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8800                 .name = "Capture Source",
8801                 .count = 1,
8802                 .info = alc_mux_enum_info,
8803                 .get = alc_mux_enum_get,
8804                 .put = alc_mux_enum_put,
8805         },
8806         {
8807                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8808                 .name = "Channel Mode",
8809                 .info = alc_ch_mode_info,
8810                 .get = alc_ch_mode_get,
8811                 .put = alc_ch_mode_put,
8812                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
8813         },
8814         { } /* end */
8815 };
8816
8817 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8818         /* output mixer control */
8819         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8820         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8821         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8822         
8823         /*Capture mixer control */
8824         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8825         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8826         {
8827                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8828                 .name = "Capture Source",
8829                 .count = 1,
8830                 .info = alc_mux_enum_info,
8831                 .get = alc_mux_enum_get,
8832                 .put = alc_mux_enum_put,
8833         },
8834
8835         { } /* end */
8836 };
8837
8838 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8839         /* output mixer control */
8840         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8841         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8842         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8843         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8844         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8845
8846         /* Input mixer control */
8847         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8848            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8849         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8850         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8851         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8852         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8853         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8854         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8855         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8856         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8857
8858         /* Capture mixer control */
8859         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8860         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8861         {
8862                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8863                 .name = "Capture Source",
8864                 .count = 1,
8865                 .info = alc_mux_enum_info,
8866                 .get = alc_mux_enum_get,
8867                 .put = alc_mux_enum_put,
8868         },
8869         {
8870                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8871                 .name = "Channel Mode",
8872                 .info = alc_ch_mode_info,
8873                 .get = alc_ch_mode_get,
8874                 .put = alc_ch_mode_put,
8875                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8876         },
8877         { } /* end */
8878 };
8879
8880 static struct snd_kcontrol_new alc861_asus_mixer[] = {
8881         /* output mixer control */
8882         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8883         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8884         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8885         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8886         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8887
8888         /* Input mixer control */
8889         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8890         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8891         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8892         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8893         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8894         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8895         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8896         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8897         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8898         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
8899
8900         /* Capture mixer control */
8901         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8902         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8903         {
8904                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8905                 .name = "Capture Source",
8906                 .count = 1,
8907                 .info = alc_mux_enum_info,
8908                 .get = alc_mux_enum_get,
8909                 .put = alc_mux_enum_put,
8910         },
8911         {
8912                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8913                 .name = "Channel Mode",
8914                 .info = alc_ch_mode_info,
8915                 .get = alc_ch_mode_get,
8916                 .put = alc_ch_mode_put,
8917                 .private_value = ARRAY_SIZE(alc861_asus_modes),
8918         },
8919         { }
8920 };
8921
8922 /* additional mixer */
8923 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
8924         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8925         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8926         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
8927         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
8928         { }
8929 };
8930
8931 /*
8932  * generic initialization of ADC, input mixers and output mixers
8933  */
8934 static struct hda_verb alc861_base_init_verbs[] = {
8935         /*
8936          * Unmute ADC0 and set the default input to mic-in
8937          */
8938         /* port-A for surround (rear panel) */
8939         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8940         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
8941         /* port-B for mic-in (rear panel) with vref */
8942         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8943         /* port-C for line-in (rear panel) */
8944         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8945         /* port-D for Front */
8946         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8947         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8948         /* port-E for HP out (front panel) */
8949         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8950         /* route front PCM to HP */
8951         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8952         /* port-F for mic-in (front panel) with vref */
8953         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8954         /* port-G for CLFE (rear panel) */
8955         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8956         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8957         /* port-H for side (rear panel) */
8958         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8959         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
8960         /* CD-in */
8961         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8962         /* route front mic to ADC1*/
8963         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8964         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8965         
8966         /* Unmute DAC0~3 & spdif out*/
8967         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8968         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8969         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8970         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8971         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8972         
8973         /* Unmute Mixer 14 (mic) 1c (Line in)*/
8974         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8975         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8976         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8977         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8978         
8979         /* Unmute Stereo Mixer 15 */
8980         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8981         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8982         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8983         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8984
8985         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8986         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8987         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8988         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8989         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8990         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8991         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8992         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8993         /* hp used DAC 3 (Front) */
8994         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8995         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8996
8997         { }
8998 };
8999
9000 static struct hda_verb alc861_threestack_init_verbs[] = {
9001         /*
9002          * Unmute ADC0 and set the default input to mic-in
9003          */
9004         /* port-A for surround (rear panel) */
9005         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9006         /* port-B for mic-in (rear panel) with vref */
9007         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9008         /* port-C for line-in (rear panel) */
9009         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9010         /* port-D for Front */
9011         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9012         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9013         /* port-E for HP out (front panel) */
9014         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9015         /* route front PCM to HP */
9016         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9017         /* port-F for mic-in (front panel) with vref */
9018         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9019         /* port-G for CLFE (rear panel) */
9020         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9021         /* port-H for side (rear panel) */
9022         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9023         /* CD-in */
9024         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9025         /* route front mic to ADC1*/
9026         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9027         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9028         /* Unmute DAC0~3 & spdif out*/
9029         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9030         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9031         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9032         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9033         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9034         
9035         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9036         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9037         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9038         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9039         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9040         
9041         /* Unmute Stereo Mixer 15 */
9042         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9043         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9044         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9045         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9046
9047         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9048         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9049         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9050         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9051         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9052         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9053         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9054         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9055         /* hp used DAC 3 (Front) */
9056         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9057         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9058         { }
9059 };
9060
9061 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9062         /*
9063          * Unmute ADC0 and set the default input to mic-in
9064          */
9065         /* port-A for surround (rear panel) */
9066         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9067         /* port-B for mic-in (rear panel) with vref */
9068         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9069         /* port-C for line-in (rear panel) */
9070         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9071         /* port-D for Front */
9072         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9073         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9074         /* port-E for HP out (front panel) */
9075         /* this has to be set to VREF80 */
9076         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9077         /* route front PCM to HP */
9078         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9079         /* port-F for mic-in (front panel) with vref */
9080         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9081         /* port-G for CLFE (rear panel) */
9082         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9083         /* port-H for side (rear panel) */
9084         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9085         /* CD-in */
9086         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9087         /* route front mic to ADC1*/
9088         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9089         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9090         /* Unmute DAC0~3 & spdif out*/
9091         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9092         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9093         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9094         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9095         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9096         
9097         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9098         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9099         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9100         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9101         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9102         
9103         /* Unmute Stereo Mixer 15 */
9104         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9105         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9106         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9107         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9108
9109         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9110         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9111         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9112         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9113         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9114         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9115         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9116         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9117         /* hp used DAC 3 (Front) */
9118         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9119         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9120         { }
9121 };
9122
9123 static struct hda_verb alc861_asus_init_verbs[] = {
9124         /*
9125          * Unmute ADC0 and set the default input to mic-in
9126          */
9127         /* port-A for surround (rear panel)
9128          * according to codec#0 this is the HP jack
9129          */
9130         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9131         /* route front PCM to HP */
9132         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9133         /* port-B for mic-in (rear panel) with vref */
9134         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9135         /* port-C for line-in (rear panel) */
9136         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9137         /* port-D for Front */
9138         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9139         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9140         /* port-E for HP out (front panel) */
9141         /* this has to be set to VREF80 */
9142         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9143         /* route front PCM to HP */
9144         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9145         /* port-F for mic-in (front panel) with vref */
9146         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9147         /* port-G for CLFE (rear panel) */
9148         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9149         /* port-H for side (rear panel) */
9150         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9151         /* CD-in */
9152         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9153         /* route front mic to ADC1*/
9154         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9155         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9156         /* Unmute DAC0~3 & spdif out*/
9157         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9158         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9159         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9160         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9161         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9162         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9163         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9164         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9165         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9166         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9167         
9168         /* Unmute Stereo Mixer 15 */
9169         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9170         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9171         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9172         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9173
9174         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9175         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9176         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9177         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9178         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9179         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9180         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9181         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9182         /* hp used DAC 3 (Front) */
9183         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9184         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9185         { }
9186 };
9187
9188 /* additional init verbs for ASUS laptops */
9189 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9190         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9191         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9192         { }
9193 };
9194
9195 /*
9196  * generic initialization of ADC, input mixers and output mixers
9197  */
9198 static struct hda_verb alc861_auto_init_verbs[] = {
9199         /*
9200          * Unmute ADC0 and set the default input to mic-in
9201          */
9202         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9203         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9204         
9205         /* Unmute DAC0~3 & spdif out*/
9206         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9207         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9208         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9209         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9210         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9211         
9212         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9213         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9214         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9215         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9216         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9217         
9218         /* Unmute Stereo Mixer 15 */
9219         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9220         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9221         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9222         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9223
9224         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9225         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9226         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9227         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9228         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9229         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9230         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9231         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9232
9233         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9234         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9235         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9236         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9237         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9238         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9239         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9240         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9241
9242         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
9243
9244         { }
9245 };
9246
9247 static struct hda_verb alc861_toshiba_init_verbs[] = {
9248         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9249
9250         { }
9251 };
9252
9253 /* toggle speaker-output according to the hp-jack state */
9254 static void alc861_toshiba_automute(struct hda_codec *codec)
9255 {
9256         unsigned int present;
9257
9258         present = snd_hda_codec_read(codec, 0x0f, 0,
9259                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9260         snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
9261                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9262         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
9263                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
9264 }
9265
9266 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9267                                        unsigned int res)
9268 {
9269         if ((res >> 26) == ALC880_HP_EVENT)
9270                 alc861_toshiba_automute(codec);
9271 }
9272
9273 /* pcm configuration: identiacal with ALC880 */
9274 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
9275 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
9276 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
9277 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
9278
9279
9280 #define ALC861_DIGOUT_NID       0x07
9281
9282 static struct hda_channel_mode alc861_8ch_modes[1] = {
9283         { 8, NULL }
9284 };
9285
9286 static hda_nid_t alc861_dac_nids[4] = {
9287         /* front, surround, clfe, side */
9288         0x03, 0x06, 0x05, 0x04
9289 };
9290
9291 static hda_nid_t alc660_dac_nids[3] = {
9292         /* front, clfe, surround */
9293         0x03, 0x05, 0x06
9294 };
9295
9296 static hda_nid_t alc861_adc_nids[1] = {
9297         /* ADC0-2 */
9298         0x08,
9299 };
9300
9301 static struct hda_input_mux alc861_capture_source = {
9302         .num_items = 5,
9303         .items = {
9304                 { "Mic", 0x0 },
9305                 { "Front Mic", 0x3 },
9306                 { "Line", 0x1 },
9307                 { "CD", 0x4 },
9308                 { "Mixer", 0x5 },
9309         },
9310 };
9311
9312 /* fill in the dac_nids table from the parsed pin configuration */
9313 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9314                                      const struct auto_pin_cfg *cfg)
9315 {
9316         int i;
9317         hda_nid_t nid;
9318
9319         spec->multiout.dac_nids = spec->private_dac_nids;
9320         for (i = 0; i < cfg->line_outs; i++) {
9321                 nid = cfg->line_out_pins[i];
9322                 if (nid) {
9323                         if (i >= ARRAY_SIZE(alc861_dac_nids))
9324                                 continue;
9325                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9326                 }
9327         }
9328         spec->multiout.num_dacs = cfg->line_outs;
9329         return 0;
9330 }
9331
9332 /* add playback controls from the parsed DAC table */
9333 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9334                                              const struct auto_pin_cfg *cfg)
9335 {
9336         char name[32];
9337         static const char *chname[4] = {
9338                 "Front", "Surround", NULL /*CLFE*/, "Side"
9339         };
9340         hda_nid_t nid;
9341         int i, idx, err;
9342
9343         for (i = 0; i < cfg->line_outs; i++) {
9344                 nid = spec->multiout.dac_nids[i];
9345                 if (!nid)
9346                         continue;
9347                 if (nid == 0x05) {
9348                         /* Center/LFE */
9349                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9350                                           "Center Playback Switch",
9351                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9352                                                               HDA_OUTPUT));
9353                         if (err < 0)
9354                                 return err;
9355                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9356                                           "LFE Playback Switch",
9357                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9358                                                               HDA_OUTPUT));
9359                         if (err < 0)
9360                                 return err;
9361                 } else {
9362                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9363                              idx++)
9364                                 if (nid == alc861_dac_nids[idx])
9365                                         break;
9366                         sprintf(name, "%s Playback Switch", chname[idx]);
9367                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9368                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9369                                                               HDA_OUTPUT));
9370                         if (err < 0)
9371                                 return err;
9372                 }
9373         }
9374         return 0;
9375 }
9376
9377 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9378 {
9379         int err;
9380         hda_nid_t nid;
9381
9382         if (!pin)
9383                 return 0;
9384
9385         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9386                 nid = 0x03;
9387                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9388                                   "Headphone Playback Switch",
9389                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9390                 if (err < 0)
9391                         return err;
9392                 spec->multiout.hp_nid = nid;
9393         }
9394         return 0;
9395 }
9396
9397 /* create playback/capture controls for input pins */
9398 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9399                                                 const struct auto_pin_cfg *cfg)
9400 {
9401         struct hda_input_mux *imux = &spec->private_imux;
9402         int i, err, idx, idx1;
9403
9404         for (i = 0; i < AUTO_PIN_LAST; i++) {
9405                 switch (cfg->input_pins[i]) {
9406                 case 0x0c:
9407                         idx1 = 1;
9408                         idx = 2;        /* Line In */
9409                         break;
9410                 case 0x0f:
9411                         idx1 = 2;
9412                         idx = 2;        /* Line In */
9413                         break;
9414                 case 0x0d:
9415                         idx1 = 0;
9416                         idx = 1;        /* Mic In */
9417                         break;
9418                 case 0x10:
9419                         idx1 = 3;
9420                         idx = 1;        /* Mic In */
9421                         break;
9422                 case 0x11:
9423                         idx1 = 4;
9424                         idx = 0;        /* CD */
9425                         break;
9426                 default:
9427                         continue;
9428                 }
9429
9430                 err = new_analog_input(spec, cfg->input_pins[i],
9431                                        auto_pin_cfg_labels[i], idx, 0x15);
9432                 if (err < 0)
9433                         return err;
9434
9435                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9436                 imux->items[imux->num_items].index = idx1;
9437                 imux->num_items++;
9438         }
9439         return 0;
9440 }
9441
9442 static struct snd_kcontrol_new alc861_capture_mixer[] = {
9443         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9444         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9445
9446         {
9447                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9448                 /* The multiple "Capture Source" controls confuse alsamixer
9449                  * So call somewhat different..
9450                  *FIXME: the controls appear in the "playback" view!
9451                  */
9452                 /* .name = "Capture Source", */
9453                 .name = "Input Source",
9454                 .count = 1,
9455                 .info = alc_mux_enum_info,
9456                 .get = alc_mux_enum_get,
9457                 .put = alc_mux_enum_put,
9458         },
9459         { } /* end */
9460 };
9461
9462 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9463                                               hda_nid_t nid,
9464                                               int pin_type, int dac_idx)
9465 {
9466         /* set as output */
9467
9468         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9469                             pin_type);
9470         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9471                             AMP_OUT_UNMUTE);
9472
9473 }
9474
9475 static void alc861_auto_init_multi_out(struct hda_codec *codec)
9476 {
9477         struct alc_spec *spec = codec->spec;
9478         int i;
9479
9480         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9481         for (i = 0; i < spec->autocfg.line_outs; i++) {
9482                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9483                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9484                 if (nid)
9485                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9486                                                           spec->multiout.dac_nids[i]);
9487         }
9488 }
9489
9490 static void alc861_auto_init_hp_out(struct hda_codec *codec)
9491 {
9492         struct alc_spec *spec = codec->spec;
9493         hda_nid_t pin;
9494
9495         pin = spec->autocfg.hp_pins[0];
9496         if (pin) /* connect to front */
9497                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9498                                                   spec->multiout.dac_nids[0]);
9499 }
9500
9501 static void alc861_auto_init_analog_input(struct hda_codec *codec)
9502 {
9503         struct alc_spec *spec = codec->spec;
9504         int i;
9505
9506         for (i = 0; i < AUTO_PIN_LAST; i++) {
9507                 hda_nid_t nid = spec->autocfg.input_pins[i];
9508                 if (nid >= 0x0c && nid <= 0x11) {
9509                         snd_hda_codec_write(codec, nid, 0,
9510                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
9511                                             i <= AUTO_PIN_FRONT_MIC ?
9512                                             PIN_VREF80 : PIN_IN);
9513                 }
9514         }
9515 }
9516
9517 /* parse the BIOS configuration and set up the alc_spec */
9518 /* return 1 if successful, 0 if the proper config is not found,
9519  * or a negative error code
9520  */
9521 static int alc861_parse_auto_config(struct hda_codec *codec)
9522 {
9523         struct alc_spec *spec = codec->spec;
9524         int err;
9525         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9526
9527         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9528                                            alc861_ignore);
9529         if (err < 0)
9530                 return err;
9531         if (!spec->autocfg.line_outs)
9532                 return 0; /* can't find valid BIOS pin config */
9533
9534         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9535         if (err < 0)
9536                 return err;
9537         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9538         if (err < 0)
9539                 return err;
9540         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9541         if (err < 0)
9542                 return err;
9543         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9544         if (err < 0)
9545                 return err;
9546
9547         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9548
9549         if (spec->autocfg.dig_out_pin)
9550                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9551
9552         if (spec->kctl_alloc)
9553                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9554
9555         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9556
9557         spec->num_mux_defs = 1;
9558         spec->input_mux = &spec->private_imux;
9559
9560         spec->adc_nids = alc861_adc_nids;
9561         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9562         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9563         spec->num_mixers++;
9564
9565         return 1;
9566 }
9567
9568 /* additional initialization for auto-configuration model */
9569 static void alc861_auto_init(struct hda_codec *codec)
9570 {
9571         alc861_auto_init_multi_out(codec);
9572         alc861_auto_init_hp_out(codec);
9573         alc861_auto_init_analog_input(codec);
9574 }
9575
9576
9577 /*
9578  * configuration and preset
9579  */
9580 static const char *alc861_models[ALC861_MODEL_LAST] = {
9581         [ALC861_3ST]            = "3stack",
9582         [ALC660_3ST]            = "3stack-660",
9583         [ALC861_3ST_DIG]        = "3stack-dig",
9584         [ALC861_6ST_DIG]        = "6stack-dig",
9585         [ALC861_UNIWILL_M31]    = "uniwill-m31",
9586         [ALC861_TOSHIBA]        = "toshiba",
9587         [ALC861_ASUS]           = "asus",
9588         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
9589         [ALC861_AUTO]           = "auto",
9590 };
9591
9592 static struct snd_pci_quirk alc861_cfg_tbl[] = {
9593         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9594         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9595         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9596         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9597         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9598         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9599         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9600         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9601         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9602          *        Any other models that need this preset?
9603          */
9604         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9605         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9606         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9607         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9608         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9609         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9610         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9611         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9612         {}
9613 };
9614
9615 static struct alc_config_preset alc861_presets[] = {
9616         [ALC861_3ST] = {
9617                 .mixers = { alc861_3ST_mixer },
9618                 .init_verbs = { alc861_threestack_init_verbs },
9619                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9620                 .dac_nids = alc861_dac_nids,
9621                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9622                 .channel_mode = alc861_threestack_modes,
9623                 .need_dac_fix = 1,
9624                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9625                 .adc_nids = alc861_adc_nids,
9626                 .input_mux = &alc861_capture_source,
9627         },
9628         [ALC861_3ST_DIG] = {
9629                 .mixers = { alc861_base_mixer },
9630                 .init_verbs = { alc861_threestack_init_verbs },
9631                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9632                 .dac_nids = alc861_dac_nids,
9633                 .dig_out_nid = ALC861_DIGOUT_NID,
9634                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9635                 .channel_mode = alc861_threestack_modes,
9636                 .need_dac_fix = 1,
9637                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9638                 .adc_nids = alc861_adc_nids,
9639                 .input_mux = &alc861_capture_source,
9640         },
9641         [ALC861_6ST_DIG] = {
9642                 .mixers = { alc861_base_mixer },
9643                 .init_verbs = { alc861_base_init_verbs },
9644                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9645                 .dac_nids = alc861_dac_nids,
9646                 .dig_out_nid = ALC861_DIGOUT_NID,
9647                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9648                 .channel_mode = alc861_8ch_modes,
9649                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9650                 .adc_nids = alc861_adc_nids,
9651                 .input_mux = &alc861_capture_source,
9652         },
9653         [ALC660_3ST] = {
9654                 .mixers = { alc861_3ST_mixer },
9655                 .init_verbs = { alc861_threestack_init_verbs },
9656                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
9657                 .dac_nids = alc660_dac_nids,
9658                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9659                 .channel_mode = alc861_threestack_modes,
9660                 .need_dac_fix = 1,
9661                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9662                 .adc_nids = alc861_adc_nids,
9663                 .input_mux = &alc861_capture_source,
9664         },
9665         [ALC861_UNIWILL_M31] = {
9666                 .mixers = { alc861_uniwill_m31_mixer },
9667                 .init_verbs = { alc861_uniwill_m31_init_verbs },
9668                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9669                 .dac_nids = alc861_dac_nids,
9670                 .dig_out_nid = ALC861_DIGOUT_NID,
9671                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9672                 .channel_mode = alc861_uniwill_m31_modes,
9673                 .need_dac_fix = 1,
9674                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9675                 .adc_nids = alc861_adc_nids,
9676                 .input_mux = &alc861_capture_source,
9677         },
9678         [ALC861_TOSHIBA] = {
9679                 .mixers = { alc861_toshiba_mixer },
9680                 .init_verbs = { alc861_base_init_verbs,
9681                                 alc861_toshiba_init_verbs },
9682                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9683                 .dac_nids = alc861_dac_nids,
9684                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9685                 .channel_mode = alc883_3ST_2ch_modes,
9686                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9687                 .adc_nids = alc861_adc_nids,
9688                 .input_mux = &alc861_capture_source,
9689                 .unsol_event = alc861_toshiba_unsol_event,
9690                 .init_hook = alc861_toshiba_automute,
9691         },
9692         [ALC861_ASUS] = {
9693                 .mixers = { alc861_asus_mixer },
9694                 .init_verbs = { alc861_asus_init_verbs },
9695                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9696                 .dac_nids = alc861_dac_nids,
9697                 .dig_out_nid = ALC861_DIGOUT_NID,
9698                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9699                 .channel_mode = alc861_asus_modes,
9700                 .need_dac_fix = 1,
9701                 .hp_nid = 0x06,
9702                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9703                 .adc_nids = alc861_adc_nids,
9704                 .input_mux = &alc861_capture_source,
9705         },
9706         [ALC861_ASUS_LAPTOP] = {
9707                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9708                 .init_verbs = { alc861_asus_init_verbs,
9709                                 alc861_asus_laptop_init_verbs },
9710                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9711                 .dac_nids = alc861_dac_nids,
9712                 .dig_out_nid = ALC861_DIGOUT_NID,
9713                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9714                 .channel_mode = alc883_3ST_2ch_modes,
9715                 .need_dac_fix = 1,
9716                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9717                 .adc_nids = alc861_adc_nids,
9718                 .input_mux = &alc861_capture_source,
9719         },
9720 };
9721
9722
9723 static int patch_alc861(struct hda_codec *codec)
9724 {
9725         struct alc_spec *spec;
9726         int board_config;
9727         int err;
9728
9729         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9730         if (spec == NULL)
9731                 return -ENOMEM;
9732
9733         codec->spec = spec;
9734
9735         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9736                                                   alc861_models,
9737                                                   alc861_cfg_tbl);
9738
9739         if (board_config < 0) {
9740                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9741                        "trying auto-probe from BIOS...\n");
9742                 board_config = ALC861_AUTO;
9743         }
9744
9745         if (board_config == ALC861_AUTO) {
9746                 /* automatic parse from the BIOS config */
9747                 err = alc861_parse_auto_config(codec);
9748                 if (err < 0) {
9749                         alc_free(codec);
9750                         return err;
9751                 } else if (!err) {
9752                         printk(KERN_INFO
9753                                "hda_codec: Cannot set up configuration "
9754                                "from BIOS.  Using base mode...\n");
9755                    board_config = ALC861_3ST_DIG;
9756                 }
9757         }
9758
9759         if (board_config != ALC861_AUTO)
9760                 setup_preset(spec, &alc861_presets[board_config]);
9761
9762         spec->stream_name_analog = "ALC861 Analog";
9763         spec->stream_analog_playback = &alc861_pcm_analog_playback;
9764         spec->stream_analog_capture = &alc861_pcm_analog_capture;
9765
9766         spec->stream_name_digital = "ALC861 Digital";
9767         spec->stream_digital_playback = &alc861_pcm_digital_playback;
9768         spec->stream_digital_capture = &alc861_pcm_digital_capture;
9769
9770         codec->patch_ops = alc_patch_ops;
9771         if (board_config == ALC861_AUTO)
9772                 spec->init_hook = alc861_auto_init;
9773                 
9774         return 0;
9775 }
9776
9777 /*
9778  * ALC861-VD support
9779  *
9780  * Based on ALC882
9781  *
9782  * In addition, an independent DAC
9783  */
9784 #define ALC861VD_DIGOUT_NID     0x06
9785
9786 static hda_nid_t alc861vd_dac_nids[4] = {
9787         /* front, surr, clfe, side surr */
9788         0x02, 0x03, 0x04, 0x05
9789 };
9790
9791 /* dac_nids for ALC660vd are in a different order - according to
9792  * Realtek's driver.
9793  * This should probably tesult in a different mixer for 6stack models
9794  * of ALC660vd codecs, but for now there is only 3stack mixer
9795  * - and it is the same as in 861vd.
9796  * adc_nids in ALC660vd are (is) the same as in 861vd
9797  */
9798 static hda_nid_t alc660vd_dac_nids[3] = {
9799         /* front, rear, clfe, rear_surr */
9800         0x02, 0x04, 0x03
9801 };
9802
9803 static hda_nid_t alc861vd_adc_nids[1] = {
9804         /* ADC0 */
9805         0x09,
9806 };
9807
9808 /* input MUX */
9809 /* FIXME: should be a matrix-type input source selection */
9810 static struct hda_input_mux alc861vd_capture_source = {
9811         .num_items = 4,
9812         .items = {
9813                 { "Mic", 0x0 },
9814                 { "Front Mic", 0x1 },
9815                 { "Line", 0x2 },
9816                 { "CD", 0x4 },
9817         },
9818 };
9819
9820 static struct hda_input_mux alc861vd_dallas_capture_source = {
9821         .num_items = 3,
9822         .items = {
9823                 { "Front Mic", 0x0 },
9824                 { "ATAPI Mic", 0x1 },
9825                 { "Line In", 0x5 },
9826         },
9827 };
9828
9829 #define alc861vd_mux_enum_info alc_mux_enum_info
9830 #define alc861vd_mux_enum_get alc_mux_enum_get
9831
9832 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9833                                 struct snd_ctl_elem_value *ucontrol)
9834 {
9835         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9836         struct alc_spec *spec = codec->spec;
9837         const struct hda_input_mux *imux = spec->input_mux;
9838         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9839         static hda_nid_t capture_mixers[1] = { 0x22 };
9840         hda_nid_t nid = capture_mixers[adc_idx];
9841         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9842         unsigned int i, idx;
9843
9844         idx = ucontrol->value.enumerated.item[0];
9845         if (idx >= imux->num_items)
9846                 idx = imux->num_items - 1;
9847         if (*cur_val == idx)
9848                 return 0;
9849         for (i = 0; i < imux->num_items; i++) {
9850                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
9851                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
9852                                          imux->items[i].index,
9853                                          HDA_AMP_MUTE, v);
9854         }
9855         *cur_val = idx;
9856         return 1;
9857 }
9858
9859 /*
9860  * 2ch mode
9861  */
9862 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9863         { 2, NULL }
9864 };
9865
9866 /*
9867  * 6ch mode
9868  */
9869 static struct hda_verb alc861vd_6stack_ch6_init[] = {
9870         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9871         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9872         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9873         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9874         { } /* end */
9875 };
9876
9877 /*
9878  * 8ch mode
9879  */
9880 static struct hda_verb alc861vd_6stack_ch8_init[] = {
9881         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9882         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9883         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9884         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9885         { } /* end */
9886 };
9887
9888 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
9889         { 6, alc861vd_6stack_ch6_init },
9890         { 8, alc861vd_6stack_ch8_init },
9891 };
9892
9893 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
9894         {
9895                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9896                 .name = "Channel Mode",
9897                 .info = alc_ch_mode_info,
9898                 .get = alc_ch_mode_get,
9899                 .put = alc_ch_mode_put,
9900         },
9901         { } /* end */
9902 };
9903
9904 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
9905         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9906         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9907
9908         {
9909                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9910                 /* The multiple "Capture Source" controls confuse alsamixer
9911                  * So call somewhat different..
9912                  *FIXME: the controls appear in the "playback" view!
9913                  */
9914                 /* .name = "Capture Source", */
9915                 .name = "Input Source",
9916                 .count = 1,
9917                 .info = alc861vd_mux_enum_info,
9918                 .get = alc861vd_mux_enum_get,
9919                 .put = alc861vd_mux_enum_put,
9920         },
9921         { } /* end */
9922 };
9923
9924 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9925  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9926  */
9927 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
9928         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9929         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9930
9931         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9932         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9933
9934         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
9935                                 HDA_OUTPUT),
9936         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
9937                                 HDA_OUTPUT),
9938         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9939         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9940
9941         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
9942         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9943
9944         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9945
9946         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9947         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9948         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9949
9950         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9951         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9952         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9953
9954         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9955         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9956
9957         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9958         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9959
9960         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9961         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9962
9963         { } /* end */
9964 };
9965
9966 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
9967         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9968         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9969
9970         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9971
9972         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9973         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9974         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9975
9976         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9977         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9978         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9979
9980         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9981         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9982
9983         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9984         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9985
9986         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9987         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9988
9989         { } /* end */
9990 };
9991
9992 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
9993         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9994         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
9995         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9996
9997         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9998
9999         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10000         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10001         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10002
10003         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10004         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10005         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10006
10007         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10008         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10009
10010         { } /* end */
10011 };
10012
10013 /* Pin assignment: Front=0x14, HP = 0x15,
10014  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10015  */
10016 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10017         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10018         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10019         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10020         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10021         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10022         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10023         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10024         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10025         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10026         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10027         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10028         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10029         {
10030                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10031                 /* .name = "Capture Source", */
10032                 .name = "Input Source",
10033                 .count = 1,
10034                 .info = alc882_mux_enum_info,
10035                 .get = alc882_mux_enum_get,
10036                 .put = alc882_mux_enum_put,
10037         },
10038         { } /* end */
10039 };
10040
10041 /*
10042  * generic initialization of ADC, input mixers and output mixers
10043  */
10044 static struct hda_verb alc861vd_volume_init_verbs[] = {
10045         /*
10046          * Unmute ADC0 and set the default input to mic-in
10047          */
10048         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10049         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10050
10051         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10052          * the analog-loopback mixer widget
10053          */
10054         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10055         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10056         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10057         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10058         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10059         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10060
10061         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10062         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10063         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10064         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10065         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10066
10067         /*
10068          * Set up output mixers (0x02 - 0x05)
10069          */
10070         /* set vol=0 to output mixers */
10071         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10072         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10073         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10074         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10075
10076         /* set up input amps for analog loopback */
10077         /* Amp Indices: DAC = 0, mixer = 1 */
10078         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10079         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10080         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10081         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10082         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10083         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10084         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10085         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10086
10087         { }
10088 };
10089
10090 /*
10091  * 3-stack pin configuration:
10092  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10093  */
10094 static struct hda_verb alc861vd_3stack_init_verbs[] = {
10095         /*
10096          * Set pin mode and muting
10097          */
10098         /* set front pin widgets 0x14 for output */
10099         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10100         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10101         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10102
10103         /* Mic (rear) pin: input vref at 80% */
10104         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10105         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10106         /* Front Mic pin: input vref at 80% */
10107         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10108         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10109         /* Line In pin: input */
10110         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10111         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10112         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10113         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10114         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10115         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10116         /* CD pin widget for input */
10117         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10118
10119         { }
10120 };
10121
10122 /*
10123  * 6-stack pin configuration:
10124  */
10125 static struct hda_verb alc861vd_6stack_init_verbs[] = {
10126         /*
10127          * Set pin mode and muting
10128          */
10129         /* set front pin widgets 0x14 for output */
10130         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10131         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10132         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10133
10134         /* Rear Pin: output 1 (0x0d) */
10135         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10136         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10137         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10138         /* CLFE Pin: output 2 (0x0e) */
10139         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10140         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10141         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10142         /* Side Pin: output 3 (0x0f) */
10143         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10144         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10145         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10146
10147         /* Mic (rear) pin: input vref at 80% */
10148         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10149         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10150         /* Front Mic pin: input vref at 80% */
10151         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10152         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10153         /* Line In pin: input */
10154         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10155         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10156         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10157         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10158         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10159         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10160         /* CD pin widget for input */
10161         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10162
10163         { }
10164 };
10165
10166 static struct hda_verb alc861vd_eapd_verbs[] = {
10167         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10168         { }
10169 };
10170
10171 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10172         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10173         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10174         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10175         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10176         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
10177         {}
10178 };
10179
10180 /* toggle speaker-output according to the hp-jack state */
10181 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10182 {
10183         unsigned int present;
10184         unsigned char bits;
10185
10186         present = snd_hda_codec_read(codec, 0x1b, 0,
10187                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10188         bits = present ? HDA_AMP_MUTE : 0;
10189         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10190                                  HDA_AMP_MUTE, bits);
10191 }
10192
10193 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10194 {
10195         unsigned int present;
10196         unsigned char bits;
10197
10198         present = snd_hda_codec_read(codec, 0x18, 0,
10199                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10200         bits = present ? HDA_AMP_MUTE : 0;
10201         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
10202                                  HDA_AMP_MUTE, bits);
10203 }
10204
10205 static void alc861vd_lenovo_automute(struct hda_codec *codec)
10206 {
10207         alc861vd_lenovo_hp_automute(codec);
10208         alc861vd_lenovo_mic_automute(codec);
10209 }
10210
10211 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10212                                         unsigned int res)
10213 {
10214         switch (res >> 26) {
10215         case ALC880_HP_EVENT:
10216                 alc861vd_lenovo_hp_automute(codec);
10217                 break;
10218         case ALC880_MIC_EVENT:
10219                 alc861vd_lenovo_mic_automute(codec);
10220                 break;
10221         }
10222 }
10223
10224 static struct hda_verb alc861vd_dallas_verbs[] = {
10225         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10226         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10227         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10228         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10229
10230         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10231         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10232         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10233         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10234         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10235         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10236         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10237         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10238         
10239         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10240         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10241         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10242         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10243         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10244         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10245         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10246         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10247
10248         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10249         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10250         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10251         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10252         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10253         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10254         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10255         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10256
10257         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10258         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10259         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10260         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10261
10262         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10263         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
10264         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10265
10266         { } /* end */
10267 };
10268
10269 /* toggle speaker-output according to the hp-jack state */
10270 static void alc861vd_dallas_automute(struct hda_codec *codec)
10271 {
10272         unsigned int present;
10273
10274         present = snd_hda_codec_read(codec, 0x15, 0,
10275                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10276         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10277                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10278 }
10279
10280 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10281 {
10282         if ((res >> 26) == ALC880_HP_EVENT)
10283                 alc861vd_dallas_automute(codec);
10284 }
10285
10286 /* pcm configuration: identiacal with ALC880 */
10287 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
10288 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
10289 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
10290 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
10291
10292 /*
10293  * configuration and preset
10294  */
10295 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10296         [ALC660VD_3ST]          = "3stack-660",
10297         [ALC660VD_3ST_DIG]= "3stack-660-digout",
10298         [ALC861VD_3ST]          = "3stack",
10299         [ALC861VD_3ST_DIG]      = "3stack-digout",
10300         [ALC861VD_6ST_DIG]      = "6stack-digout",
10301         [ALC861VD_LENOVO]       = "lenovo",
10302         [ALC861VD_DALLAS]       = "dallas",
10303         [ALC861VD_AUTO]         = "auto",
10304 };
10305
10306 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10307         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10308         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10309         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10310         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10311         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10312
10313         SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10314         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10315         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10316         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10317         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10318         SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
10319         {}
10320 };
10321
10322 static struct alc_config_preset alc861vd_presets[] = {
10323         [ALC660VD_3ST] = {
10324                 .mixers = { alc861vd_3st_mixer },
10325                 .init_verbs = { alc861vd_volume_init_verbs,
10326                                  alc861vd_3stack_init_verbs },
10327                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10328                 .dac_nids = alc660vd_dac_nids,
10329                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10330                 .adc_nids = alc861vd_adc_nids,
10331                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10332                 .channel_mode = alc861vd_3stack_2ch_modes,
10333                 .input_mux = &alc861vd_capture_source,
10334         },
10335         [ALC660VD_3ST_DIG] = {
10336                 .mixers = { alc861vd_3st_mixer },
10337                 .init_verbs = { alc861vd_volume_init_verbs,
10338                                  alc861vd_3stack_init_verbs },
10339                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10340                 .dac_nids = alc660vd_dac_nids,
10341                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10342                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10343                 .adc_nids = alc861vd_adc_nids,
10344                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10345                 .channel_mode = alc861vd_3stack_2ch_modes,
10346                 .input_mux = &alc861vd_capture_source,
10347         },
10348         [ALC861VD_3ST] = {
10349                 .mixers = { alc861vd_3st_mixer },
10350                 .init_verbs = { alc861vd_volume_init_verbs,
10351                                  alc861vd_3stack_init_verbs },
10352                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10353                 .dac_nids = alc861vd_dac_nids,
10354                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10355                 .channel_mode = alc861vd_3stack_2ch_modes,
10356                 .input_mux = &alc861vd_capture_source,
10357         },
10358         [ALC861VD_3ST_DIG] = {
10359                 .mixers = { alc861vd_3st_mixer },
10360                 .init_verbs = { alc861vd_volume_init_verbs,
10361                                  alc861vd_3stack_init_verbs },
10362                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10363                 .dac_nids = alc861vd_dac_nids,
10364                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10365                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10366                 .channel_mode = alc861vd_3stack_2ch_modes,
10367                 .input_mux = &alc861vd_capture_source,
10368         },
10369         [ALC861VD_6ST_DIG] = {
10370                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10371                 .init_verbs = { alc861vd_volume_init_verbs,
10372                                 alc861vd_6stack_init_verbs },
10373                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10374                 .dac_nids = alc861vd_dac_nids,
10375                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10376                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10377                 .channel_mode = alc861vd_6stack_modes,
10378                 .input_mux = &alc861vd_capture_source,
10379         },
10380         [ALC861VD_LENOVO] = {
10381                 .mixers = { alc861vd_lenovo_mixer },
10382                 .init_verbs = { alc861vd_volume_init_verbs,
10383                                 alc861vd_3stack_init_verbs,
10384                                 alc861vd_eapd_verbs,
10385                                 alc861vd_lenovo_unsol_verbs },
10386                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10387                 .dac_nids = alc660vd_dac_nids,
10388                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10389                 .adc_nids = alc861vd_adc_nids,
10390                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10391                 .channel_mode = alc861vd_3stack_2ch_modes,
10392                 .input_mux = &alc861vd_capture_source,
10393                 .unsol_event = alc861vd_lenovo_unsol_event,
10394                 .init_hook = alc861vd_lenovo_automute,
10395         },
10396         [ALC861VD_DALLAS] = {
10397                 .mixers = { alc861vd_dallas_mixer },
10398                 .init_verbs = { alc861vd_dallas_verbs },
10399                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10400                 .dac_nids = alc861vd_dac_nids,
10401                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10402                 .adc_nids = alc861vd_adc_nids,
10403                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10404                 .channel_mode = alc861vd_3stack_2ch_modes,
10405                 .input_mux = &alc861vd_dallas_capture_source,
10406                 .unsol_event = alc861vd_dallas_unsol_event,
10407                 .init_hook = alc861vd_dallas_automute,
10408         },      
10409 };
10410
10411 /*
10412  * BIOS auto configuration
10413  */
10414 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10415                                 hda_nid_t nid, int pin_type, int dac_idx)
10416 {
10417         /* set as output */
10418         snd_hda_codec_write(codec, nid, 0,
10419                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10420         snd_hda_codec_write(codec, nid, 0,
10421                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10422 }
10423
10424 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10425 {
10426         struct alc_spec *spec = codec->spec;
10427         int i;
10428
10429         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10430         for (i = 0; i <= HDA_SIDE; i++) {
10431                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10432                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10433                 if (nid)
10434                         alc861vd_auto_set_output_and_unmute(codec, nid,
10435                                                             pin_type, i);
10436         }
10437 }
10438
10439
10440 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10441 {
10442         struct alc_spec *spec = codec->spec;
10443         hda_nid_t pin;
10444
10445         pin = spec->autocfg.hp_pins[0];
10446         if (pin) /* connect to front and  use dac 0 */
10447                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10448 }
10449
10450 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
10451 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
10452
10453 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10454 {
10455         struct alc_spec *spec = codec->spec;
10456         int i;
10457
10458         for (i = 0; i < AUTO_PIN_LAST; i++) {
10459                 hda_nid_t nid = spec->autocfg.input_pins[i];
10460                 if (alc861vd_is_input_pin(nid)) {
10461                         snd_hda_codec_write(codec, nid, 0,
10462                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
10463                                         i <= AUTO_PIN_FRONT_MIC ?
10464                                                         PIN_VREF80 : PIN_IN);
10465                         if (nid != ALC861VD_PIN_CD_NID)
10466                                 snd_hda_codec_write(codec, nid, 0,
10467                                                 AC_VERB_SET_AMP_GAIN_MUTE,
10468                                                 AMP_OUT_MUTE);
10469                 }
10470         }
10471 }
10472
10473 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
10474 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
10475
10476 /* add playback controls from the parsed DAC table */
10477 /* Based on ALC880 version. But ALC861VD has separate,
10478  * different NIDs for mute/unmute switch and volume control */
10479 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10480                                              const struct auto_pin_cfg *cfg)
10481 {
10482         char name[32];
10483         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10484         hda_nid_t nid_v, nid_s;
10485         int i, err;
10486
10487         for (i = 0; i < cfg->line_outs; i++) {
10488                 if (!spec->multiout.dac_nids[i])
10489                         continue;
10490                 nid_v = alc861vd_idx_to_mixer_vol(
10491                                 alc880_dac_to_idx(
10492                                         spec->multiout.dac_nids[i]));
10493                 nid_s = alc861vd_idx_to_mixer_switch(
10494                                 alc880_dac_to_idx(
10495                                         spec->multiout.dac_nids[i]));
10496
10497                 if (i == 2) {
10498                         /* Center/LFE */
10499                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10500                                           "Center Playback Volume",
10501                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10502                                                               HDA_OUTPUT));
10503                         if (err < 0)
10504                                 return err;
10505                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10506                                           "LFE Playback Volume",
10507                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10508                                                               HDA_OUTPUT));
10509                         if (err < 0)
10510                                 return err;
10511                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10512                                           "Center Playback Switch",
10513                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10514                                                               HDA_INPUT));
10515                         if (err < 0)
10516                                 return err;
10517                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10518                                           "LFE Playback Switch",
10519                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10520                                                               HDA_INPUT));
10521                         if (err < 0)
10522                                 return err;
10523                 } else {
10524                         sprintf(name, "%s Playback Volume", chname[i]);
10525                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10526                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10527                                                               HDA_OUTPUT));
10528                         if (err < 0)
10529                                 return err;
10530                         sprintf(name, "%s Playback Switch", chname[i]);
10531                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10532                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10533                                                               HDA_INPUT));
10534                         if (err < 0)
10535                                 return err;
10536                 }
10537         }
10538         return 0;
10539 }
10540
10541 /* add playback controls for speaker and HP outputs */
10542 /* Based on ALC880 version. But ALC861VD has separate,
10543  * different NIDs for mute/unmute switch and volume control */
10544 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10545                                         hda_nid_t pin, const char *pfx)
10546 {
10547         hda_nid_t nid_v, nid_s;
10548         int err;
10549         char name[32];
10550
10551         if (!pin)
10552                 return 0;
10553
10554         if (alc880_is_fixed_pin(pin)) {
10555                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10556                 /* specify the DAC as the extra output */
10557                 if (!spec->multiout.hp_nid)
10558                         spec->multiout.hp_nid = nid_v;
10559                 else
10560                         spec->multiout.extra_out_nid[0] = nid_v;
10561                 /* control HP volume/switch on the output mixer amp */
10562                 nid_v = alc861vd_idx_to_mixer_vol(
10563                                 alc880_fixed_pin_idx(pin));
10564                 nid_s = alc861vd_idx_to_mixer_switch(
10565                                 alc880_fixed_pin_idx(pin));
10566
10567                 sprintf(name, "%s Playback Volume", pfx);
10568                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10569                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10570                 if (err < 0)
10571                         return err;
10572                 sprintf(name, "%s Playback Switch", pfx);
10573                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10574                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10575                 if (err < 0)
10576                         return err;
10577         } else if (alc880_is_multi_pin(pin)) {
10578                 /* set manual connection */
10579                 /* we have only a switch on HP-out PIN */
10580                 sprintf(name, "%s Playback Switch", pfx);
10581                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10582                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10583                 if (err < 0)
10584                         return err;
10585         }
10586         return 0;
10587 }
10588
10589 /* parse the BIOS configuration and set up the alc_spec
10590  * return 1 if successful, 0 if the proper config is not found,
10591  * or a negative error code
10592  * Based on ALC880 version - had to change it to override
10593  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10594 static int alc861vd_parse_auto_config(struct hda_codec *codec)
10595 {
10596         struct alc_spec *spec = codec->spec;
10597         int err;
10598         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10599
10600         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10601                                            alc861vd_ignore);
10602         if (err < 0)
10603                 return err;
10604         if (!spec->autocfg.line_outs)
10605                 return 0; /* can't find valid BIOS pin config */
10606
10607         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10608         if (err < 0)
10609                 return err;
10610         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10611         if (err < 0)
10612                 return err;
10613         err = alc861vd_auto_create_extra_out(spec,
10614                                              spec->autocfg.speaker_pins[0],
10615                                              "Speaker");
10616         if (err < 0)
10617                 return err;
10618         err = alc861vd_auto_create_extra_out(spec,
10619                                              spec->autocfg.hp_pins[0],
10620                                              "Headphone");
10621         if (err < 0)
10622                 return err;
10623         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10624         if (err < 0)
10625                 return err;
10626
10627         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10628
10629         if (spec->autocfg.dig_out_pin)
10630                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10631
10632         if (spec->kctl_alloc)
10633                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10634
10635         spec->init_verbs[spec->num_init_verbs++]
10636                 = alc861vd_volume_init_verbs;
10637
10638         spec->num_mux_defs = 1;
10639         spec->input_mux = &spec->private_imux;
10640
10641         return 1;
10642 }
10643
10644 /* additional initialization for auto-configuration model */
10645 static void alc861vd_auto_init(struct hda_codec *codec)
10646 {
10647         alc861vd_auto_init_multi_out(codec);
10648         alc861vd_auto_init_hp_out(codec);
10649         alc861vd_auto_init_analog_input(codec);
10650 }
10651
10652 static int patch_alc861vd(struct hda_codec *codec)
10653 {
10654         struct alc_spec *spec;
10655         int err, board_config;
10656
10657         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10658         if (spec == NULL)
10659                 return -ENOMEM;
10660
10661         codec->spec = spec;
10662
10663         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10664                                                   alc861vd_models,
10665                                                   alc861vd_cfg_tbl);
10666
10667         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10668                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10669                         "ALC861VD, trying auto-probe from BIOS...\n");
10670                 board_config = ALC861VD_AUTO;
10671         }
10672
10673         if (board_config == ALC861VD_AUTO) {
10674                 /* automatic parse from the BIOS config */
10675                 err = alc861vd_parse_auto_config(codec);
10676                 if (err < 0) {
10677                         alc_free(codec);
10678                         return err;
10679                 } else if (!err) {
10680                         printk(KERN_INFO
10681                                "hda_codec: Cannot set up configuration "
10682                                "from BIOS.  Using base mode...\n");
10683                         board_config = ALC861VD_3ST;
10684                 }
10685         }
10686
10687         if (board_config != ALC861VD_AUTO)
10688                 setup_preset(spec, &alc861vd_presets[board_config]);
10689
10690         spec->stream_name_analog = "ALC861VD Analog";
10691         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10692         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10693
10694         spec->stream_name_digital = "ALC861VD Digital";
10695         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10696         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10697
10698         spec->adc_nids = alc861vd_adc_nids;
10699         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10700
10701         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10702         spec->num_mixers++;
10703
10704         codec->patch_ops = alc_patch_ops;
10705
10706         if (board_config == ALC861VD_AUTO)
10707                 spec->init_hook = alc861vd_auto_init;
10708
10709         return 0;
10710 }
10711
10712 /*
10713  * ALC662 support
10714  *
10715  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10716  * configuration.  Each pin widget can choose any input DACs and a mixer.
10717  * Each ADC is connected from a mixer of all inputs.  This makes possible
10718  * 6-channel independent captures.
10719  *
10720  * In addition, an independent DAC for the multi-playback (not used in this
10721  * driver yet).
10722  */
10723 #define ALC662_DIGOUT_NID       0x06
10724 #define ALC662_DIGIN_NID        0x0a
10725
10726 static hda_nid_t alc662_dac_nids[4] = {
10727         /* front, rear, clfe, rear_surr */
10728         0x02, 0x03, 0x04
10729 };
10730
10731 static hda_nid_t alc662_adc_nids[1] = {
10732         /* ADC1-2 */
10733         0x09,
10734 };
10735 /* input MUX */
10736 /* FIXME: should be a matrix-type input source selection */
10737
10738 static struct hda_input_mux alc662_capture_source = {
10739         .num_items = 4,
10740         .items = {
10741                 { "Mic", 0x0 },
10742                 { "Front Mic", 0x1 },
10743                 { "Line", 0x2 },
10744                 { "CD", 0x4 },
10745         },
10746 };
10747
10748 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10749         .num_items = 2,
10750         .items = {
10751                 { "Mic", 0x1 },
10752                 { "Line", 0x2 },
10753         },
10754 };
10755 #define alc662_mux_enum_info alc_mux_enum_info
10756 #define alc662_mux_enum_get alc_mux_enum_get
10757
10758 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10759                                struct snd_ctl_elem_value *ucontrol)
10760 {
10761         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10762         struct alc_spec *spec = codec->spec;
10763         const struct hda_input_mux *imux = spec->input_mux;
10764         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10765         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
10766         hda_nid_t nid = capture_mixers[adc_idx];
10767         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10768         unsigned int i, idx;
10769
10770         idx = ucontrol->value.enumerated.item[0];
10771         if (idx >= imux->num_items)
10772                 idx = imux->num_items - 1;
10773         if (*cur_val == idx)
10774                 return 0;
10775         for (i = 0; i < imux->num_items; i++) {
10776                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10777                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10778                                          imux->items[i].index,
10779                                          HDA_AMP_MUTE, v);
10780         }
10781         *cur_val = idx;
10782         return 1;
10783 }
10784 /*
10785  * 2ch mode
10786  */
10787 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10788         { 2, NULL }
10789 };
10790
10791 /*
10792  * 2ch mode
10793  */
10794 static struct hda_verb alc662_3ST_ch2_init[] = {
10795         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10796         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10797         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10798         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10799         { } /* end */
10800 };
10801
10802 /*
10803  * 6ch mode
10804  */
10805 static struct hda_verb alc662_3ST_ch6_init[] = {
10806         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10807         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10808         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10809         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10810         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10811         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10812         { } /* end */
10813 };
10814
10815 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10816         { 2, alc662_3ST_ch2_init },
10817         { 6, alc662_3ST_ch6_init },
10818 };
10819
10820 /*
10821  * 2ch mode
10822  */
10823 static struct hda_verb alc662_sixstack_ch6_init[] = {
10824         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10825         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10826         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10827         { } /* end */
10828 };
10829
10830 /*
10831  * 6ch mode
10832  */
10833 static struct hda_verb alc662_sixstack_ch8_init[] = {
10834         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10835         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10836         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10837         { } /* end */
10838 };
10839
10840 static struct hda_channel_mode alc662_5stack_modes[2] = {
10841         { 2, alc662_sixstack_ch6_init },
10842         { 6, alc662_sixstack_ch8_init },
10843 };
10844
10845 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10846  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10847  */
10848
10849 static struct snd_kcontrol_new alc662_base_mixer[] = {
10850         /* output mixer control */
10851         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10852         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
10853         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10854         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10855         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10856         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10857         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10858         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10859         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10860
10861         /*Input mixer control */
10862         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
10863         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
10864         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
10865         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
10866         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
10867         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
10868         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
10869         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
10870
10871         /* Capture mixer control */
10872         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10873         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10874         {
10875                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10876                 .name = "Capture Source",
10877                 .count = 1,
10878                 .info = alc_mux_enum_info,
10879                 .get = alc_mux_enum_get,
10880                 .put = alc_mux_enum_put,
10881         },
10882         { } /* end */
10883 };
10884
10885 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
10886         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10887         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10888         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10889         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10890         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10891         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10892         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10893         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10894         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10895         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10896         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10897         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10898         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10899         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10900         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10901         {
10902                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10903                 /* .name = "Capture Source", */
10904                 .name = "Input Source",
10905                 .count = 1,
10906                 .info = alc662_mux_enum_info,
10907                 .get = alc662_mux_enum_get,
10908                 .put = alc662_mux_enum_put,
10909         },
10910         { } /* end */
10911 };
10912
10913 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
10914         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10915         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10916         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10917         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
10918         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10919         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10920         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10921         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10922         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10923         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10924         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10925         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10926         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10927         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10928         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10929         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10930         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10931         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10932         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10933         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10934         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10935         {
10936                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10937                 /* .name = "Capture Source", */
10938                 .name = "Input Source",
10939                 .count = 1,
10940                 .info = alc662_mux_enum_info,
10941                 .get = alc662_mux_enum_get,
10942                 .put = alc662_mux_enum_put,
10943         },
10944         { } /* end */
10945 };
10946
10947 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
10948         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10949         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10950         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10951         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
10952         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10953         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10954         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10955         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10956         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10957         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10958         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10959         {
10960                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10961                 /* .name = "Capture Source", */
10962                 .name = "Input Source",
10963                 .count = 1,
10964                 .info = alc662_mux_enum_info,
10965                 .get = alc662_mux_enum_get,
10966                 .put = alc662_mux_enum_put,
10967         },
10968         { } /* end */
10969 };
10970
10971 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
10972         {
10973                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10974                 .name = "Channel Mode",
10975                 .info = alc_ch_mode_info,
10976                 .get = alc_ch_mode_get,
10977                 .put = alc_ch_mode_put,
10978         },
10979         { } /* end */
10980 };
10981
10982 static struct hda_verb alc662_init_verbs[] = {
10983         /* ADC: mute amp left and right */
10984         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10985         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10986         /* Front mixer: unmute input/output amp left and right (volume = 0) */
10987
10988         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10989         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10990         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10991         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10992         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10993
10994         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10995         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10996         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10997         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10998         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10999         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11000
11001         /* Front Pin: output 0 (0x0c) */
11002         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11003         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11004
11005         /* Rear Pin: output 1 (0x0d) */
11006         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11007         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11008
11009         /* CLFE Pin: output 2 (0x0e) */
11010         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11011         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11012
11013         /* Mic (rear) pin: input vref at 80% */
11014         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11015         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11016         /* Front Mic pin: input vref at 80% */
11017         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11018         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11019         /* Line In pin: input */
11020         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11021         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11022         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11023         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11024         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11025         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11026         /* CD pin widget for input */
11027         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11028
11029         /* FIXME: use matrix-type input source selection */
11030         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11031         /* Input mixer */
11032         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11033         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11034         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11035         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11036         { }
11037 };
11038
11039 static struct hda_verb alc662_sue_init_verbs[] = {
11040         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11041         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11042         {}
11043 };
11044
11045 /*
11046  * generic initialization of ADC, input mixers and output mixers
11047  */
11048 static struct hda_verb alc662_auto_init_verbs[] = {
11049         /*
11050          * Unmute ADC and set the default input to mic-in
11051          */
11052         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11053         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11054
11055         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11056          * mixer widget
11057          * Note: PASD motherboards uses the Line In 2 as the input for front
11058          * panel mic (mic 2)
11059          */
11060         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11061         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11062         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11063         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11064         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11065         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11066
11067         /*
11068          * Set up output mixers (0x0c - 0x0f)
11069          */
11070         /* set vol=0 to output mixers */
11071         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11072         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11073         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11074
11075         /* set up input amps for analog loopback */
11076         /* Amp Indices: DAC = 0, mixer = 1 */
11077         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11078         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11079         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11080         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11081         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11082         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11083
11084
11085         /* FIXME: use matrix-type input source selection */
11086         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11087         /* Input mixer */
11088         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11089         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11090         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11091         /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
11092         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11093
11094         { }
11095 };
11096
11097 /* capture mixer elements */
11098 static struct snd_kcontrol_new alc662_capture_mixer[] = {
11099         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11100         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11101         {
11102                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11103                 /* The multiple "Capture Source" controls confuse alsamixer
11104                  * So call somewhat different..
11105                  * FIXME: the controls appear in the "playback" view!
11106                  */
11107                 /* .name = "Capture Source", */
11108                 .name = "Input Source",
11109                 .count = 1,
11110                 .info = alc882_mux_enum_info,
11111                 .get = alc882_mux_enum_get,
11112                 .put = alc882_mux_enum_put,
11113         },
11114         { } /* end */
11115 };
11116
11117 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11118 {
11119         unsigned int present;
11120         unsigned char bits;
11121
11122         present = snd_hda_codec_read(codec, 0x14, 0,
11123                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11124         bits = present ? HDA_AMP_MUTE : 0;
11125         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11126                                  HDA_AMP_MUTE, bits);
11127 }
11128
11129 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11130 {
11131         unsigned int present;
11132         unsigned char bits;
11133
11134         present = snd_hda_codec_read(codec, 0x1b, 0,
11135                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11136         bits = present ? HDA_AMP_MUTE : 0;
11137         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11138                                  HDA_AMP_MUTE, bits);
11139         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11140                                  HDA_AMP_MUTE, bits);
11141 }
11142
11143 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11144                                            unsigned int res)
11145 {
11146         if ((res >> 26) == ALC880_HP_EVENT)
11147                 alc662_lenovo_101e_all_automute(codec);
11148         if ((res >> 26) == ALC880_FRONT_EVENT)
11149                 alc662_lenovo_101e_ispeaker_automute(codec);
11150 }
11151
11152
11153 /* pcm configuration: identiacal with ALC880 */
11154 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
11155 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
11156 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
11157 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
11158
11159 /*
11160  * configuration and preset
11161  */
11162 static const char *alc662_models[ALC662_MODEL_LAST] = {
11163         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
11164         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
11165         [ALC662_3ST_6ch]        = "3stack-6ch",
11166         [ALC662_5ST_DIG]        = "6stack-dig",
11167         [ALC662_LENOVO_101E]    = "lenovo-101e",
11168         [ALC662_AUTO]           = "auto",
11169 };
11170
11171 static struct snd_pci_quirk alc662_cfg_tbl[] = {
11172         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11173         {}
11174 };
11175
11176 static struct alc_config_preset alc662_presets[] = {
11177         [ALC662_3ST_2ch_DIG] = {
11178                 .mixers = { alc662_3ST_2ch_mixer },
11179                 .init_verbs = { alc662_init_verbs },
11180                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11181                 .dac_nids = alc662_dac_nids,
11182                 .dig_out_nid = ALC662_DIGOUT_NID,
11183                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11184                 .adc_nids = alc662_adc_nids,
11185                 .dig_in_nid = ALC662_DIGIN_NID,
11186                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11187                 .channel_mode = alc662_3ST_2ch_modes,
11188                 .input_mux = &alc662_capture_source,
11189         },
11190         [ALC662_3ST_6ch_DIG] = {
11191                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11192                 .init_verbs = { alc662_init_verbs },
11193                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11194                 .dac_nids = alc662_dac_nids,
11195                 .dig_out_nid = ALC662_DIGOUT_NID,
11196                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11197                 .adc_nids = alc662_adc_nids,
11198                 .dig_in_nid = ALC662_DIGIN_NID,
11199                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11200                 .channel_mode = alc662_3ST_6ch_modes,
11201                 .need_dac_fix = 1,
11202                 .input_mux = &alc662_capture_source,
11203         },
11204         [ALC662_3ST_6ch] = {
11205                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11206                 .init_verbs = { alc662_init_verbs },
11207                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11208                 .dac_nids = alc662_dac_nids,
11209                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11210                 .adc_nids = alc662_adc_nids,
11211                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11212                 .channel_mode = alc662_3ST_6ch_modes,
11213                 .need_dac_fix = 1,
11214                 .input_mux = &alc662_capture_source,
11215         },
11216         [ALC662_5ST_DIG] = {
11217                 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
11218                 .init_verbs = { alc662_init_verbs },
11219                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11220                 .dac_nids = alc662_dac_nids,
11221                 .dig_out_nid = ALC662_DIGOUT_NID,
11222                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11223                 .adc_nids = alc662_adc_nids,
11224                 .dig_in_nid = ALC662_DIGIN_NID,
11225                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11226                 .channel_mode = alc662_5stack_modes,
11227                 .input_mux = &alc662_capture_source,
11228         },
11229         [ALC662_LENOVO_101E] = {
11230                 .mixers = { alc662_lenovo_101e_mixer },
11231                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11232                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11233                 .dac_nids = alc662_dac_nids,
11234                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11235                 .adc_nids = alc662_adc_nids,
11236                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11237                 .channel_mode = alc662_3ST_2ch_modes,
11238                 .input_mux = &alc662_lenovo_101e_capture_source,
11239                 .unsol_event = alc662_lenovo_101e_unsol_event,
11240                 .init_hook = alc662_lenovo_101e_all_automute,
11241         },
11242
11243 };
11244
11245
11246 /*
11247  * BIOS auto configuration
11248  */
11249
11250 /* add playback controls from the parsed DAC table */
11251 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11252                                              const struct auto_pin_cfg *cfg)
11253 {
11254         char name[32];
11255         static const char *chname[4] = {
11256                 "Front", "Surround", NULL /*CLFE*/, "Side"
11257         };
11258         hda_nid_t nid;
11259         int i, err;
11260
11261         for (i = 0; i < cfg->line_outs; i++) {
11262                 if (!spec->multiout.dac_nids[i])
11263                         continue;
11264                 nid = alc880_idx_to_mixer(i);
11265                 if (i == 2) {
11266                         /* Center/LFE */
11267                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11268                                           "Center Playback Volume",
11269                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11270                                                               HDA_OUTPUT));
11271                         if (err < 0)
11272                                 return err;
11273                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11274                                           "LFE Playback Volume",
11275                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11276                                                               HDA_OUTPUT));
11277                         if (err < 0)
11278                                 return err;
11279                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11280                                           "Center Playback Switch",
11281                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11282                                                               HDA_INPUT));
11283                         if (err < 0)
11284                                 return err;
11285                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11286                                           "LFE Playback Switch",
11287                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11288                                                               HDA_INPUT));
11289                         if (err < 0)
11290                                 return err;
11291                 } else {
11292                         sprintf(name, "%s Playback Volume", chname[i]);
11293                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11294                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11295                                                               HDA_OUTPUT));
11296                         if (err < 0)
11297                                 return err;
11298                         sprintf(name, "%s Playback Switch", chname[i]);
11299                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11300                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11301                                                               HDA_INPUT));
11302                         if (err < 0)
11303                                 return err;
11304                 }
11305         }
11306         return 0;
11307 }
11308
11309 /* add playback controls for speaker and HP outputs */
11310 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11311                                         const char *pfx)
11312 {
11313         hda_nid_t nid;
11314         int err;
11315         char name[32];
11316
11317         if (!pin)
11318                 return 0;
11319
11320         if (alc880_is_fixed_pin(pin)) {
11321                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11322                 /* printk("DAC nid=%x\n",nid); */
11323                 /* specify the DAC as the extra output */
11324                 if (!spec->multiout.hp_nid)
11325                         spec->multiout.hp_nid = nid;
11326                 else
11327                         spec->multiout.extra_out_nid[0] = nid;
11328                 /* control HP volume/switch on the output mixer amp */
11329                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11330                 sprintf(name, "%s Playback Volume", pfx);
11331                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11332                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11333                 if (err < 0)
11334                         return err;
11335                 sprintf(name, "%s Playback Switch", pfx);
11336                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11337                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11338                 if (err < 0)
11339                         return err;
11340         } else if (alc880_is_multi_pin(pin)) {
11341                 /* set manual connection */
11342                 /* we have only a switch on HP-out PIN */
11343                 sprintf(name, "%s Playback Switch", pfx);
11344                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11345                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11346                 if (err < 0)
11347                         return err;
11348         }
11349         return 0;
11350 }
11351
11352 /* create playback/capture controls for input pins */
11353 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11354                                                 const struct auto_pin_cfg *cfg)
11355 {
11356         struct hda_input_mux *imux = &spec->private_imux;
11357         int i, err, idx;
11358
11359         for (i = 0; i < AUTO_PIN_LAST; i++) {
11360                 if (alc880_is_input_pin(cfg->input_pins[i])) {
11361                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
11362                         err = new_analog_input(spec, cfg->input_pins[i],
11363                                                auto_pin_cfg_labels[i],
11364                                                idx, 0x0b);
11365                         if (err < 0)
11366                                 return err;
11367                         imux->items[imux->num_items].label =
11368                                 auto_pin_cfg_labels[i];
11369                         imux->items[imux->num_items].index =
11370                                 alc880_input_pin_idx(cfg->input_pins[i]);
11371                         imux->num_items++;
11372                 }
11373         }
11374         return 0;
11375 }
11376
11377 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11378                                               hda_nid_t nid, int pin_type,
11379                                               int dac_idx)
11380 {
11381         /* set as output */
11382         snd_hda_codec_write(codec, nid, 0,
11383                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11384         snd_hda_codec_write(codec, nid, 0,
11385                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11386         /* need the manual connection? */
11387         if (alc880_is_multi_pin(nid)) {
11388                 struct alc_spec *spec = codec->spec;
11389                 int idx = alc880_multi_pin_idx(nid);
11390                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11391                                     AC_VERB_SET_CONNECT_SEL,
11392                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11393         }
11394 }
11395
11396 static void alc662_auto_init_multi_out(struct hda_codec *codec)
11397 {
11398         struct alc_spec *spec = codec->spec;
11399         int i;
11400
11401         for (i = 0; i <= HDA_SIDE; i++) {
11402                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11403                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11404                 if (nid)
11405                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11406                                                           i);
11407         }
11408 }
11409
11410 static void alc662_auto_init_hp_out(struct hda_codec *codec)
11411 {
11412         struct alc_spec *spec = codec->spec;
11413         hda_nid_t pin;
11414
11415         pin = spec->autocfg.hp_pins[0];
11416         if (pin) /* connect to front */
11417                 /* use dac 0 */
11418                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11419 }
11420
11421 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
11422 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
11423
11424 static void alc662_auto_init_analog_input(struct hda_codec *codec)
11425 {
11426         struct alc_spec *spec = codec->spec;
11427         int i;
11428
11429         for (i = 0; i < AUTO_PIN_LAST; i++) {
11430                 hda_nid_t nid = spec->autocfg.input_pins[i];
11431                 if (alc662_is_input_pin(nid)) {
11432                         snd_hda_codec_write(codec, nid, 0,
11433                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
11434                                             (i <= AUTO_PIN_FRONT_MIC ?
11435                                              PIN_VREF80 : PIN_IN));
11436                         if (nid != ALC662_PIN_CD_NID)
11437                                 snd_hda_codec_write(codec, nid, 0,
11438                                                     AC_VERB_SET_AMP_GAIN_MUTE,
11439                                                     AMP_OUT_MUTE);
11440                 }
11441         }
11442 }
11443
11444 static int alc662_parse_auto_config(struct hda_codec *codec)
11445 {
11446         struct alc_spec *spec = codec->spec;
11447         int err;
11448         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11449
11450         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11451                                            alc662_ignore);
11452         if (err < 0)
11453                 return err;
11454         if (!spec->autocfg.line_outs)
11455                 return 0; /* can't find valid BIOS pin config */
11456
11457         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11458         if (err < 0)
11459                 return err;
11460         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11461         if (err < 0)
11462                 return err;
11463         err = alc662_auto_create_extra_out(spec,
11464                                            spec->autocfg.speaker_pins[0],
11465                                            "Speaker");
11466         if (err < 0)
11467                 return err;
11468         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11469                                            "Headphone");
11470         if (err < 0)
11471                 return err;
11472         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11473         if (err < 0)
11474                 return err;
11475
11476         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11477
11478         if (spec->autocfg.dig_out_pin)
11479                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11480
11481         if (spec->kctl_alloc)
11482                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11483
11484         spec->num_mux_defs = 1;
11485         spec->input_mux = &spec->private_imux;
11486         
11487         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11488         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11489         spec->num_mixers++;
11490         return 1;
11491 }
11492
11493 /* additional initialization for auto-configuration model */
11494 static void alc662_auto_init(struct hda_codec *codec)
11495 {
11496         alc662_auto_init_multi_out(codec);
11497         alc662_auto_init_hp_out(codec);
11498         alc662_auto_init_analog_input(codec);
11499 }
11500
11501 static int patch_alc662(struct hda_codec *codec)
11502 {
11503         struct alc_spec *spec;
11504         int err, board_config;
11505
11506         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11507         if (!spec)
11508                 return -ENOMEM;
11509
11510         codec->spec = spec;
11511
11512         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11513                                                   alc662_models,
11514                                                   alc662_cfg_tbl);
11515         if (board_config < 0) {
11516                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11517                        "trying auto-probe from BIOS...\n");
11518                 board_config = ALC662_AUTO;
11519         }
11520
11521         if (board_config == ALC662_AUTO) {
11522                 /* automatic parse from the BIOS config */
11523                 err = alc662_parse_auto_config(codec);
11524                 if (err < 0) {
11525                         alc_free(codec);
11526                         return err;
11527                 } else if (!err) {
11528                         printk(KERN_INFO
11529                                "hda_codec: Cannot set up configuration "
11530                                "from BIOS.  Using base mode...\n");
11531                         board_config = ALC662_3ST_2ch_DIG;
11532                 }
11533         }
11534
11535         if (board_config != ALC662_AUTO)
11536                 setup_preset(spec, &alc662_presets[board_config]);
11537
11538         spec->stream_name_analog = "ALC662 Analog";
11539         spec->stream_analog_playback = &alc662_pcm_analog_playback;
11540         spec->stream_analog_capture = &alc662_pcm_analog_capture;
11541
11542         spec->stream_name_digital = "ALC662 Digital";
11543         spec->stream_digital_playback = &alc662_pcm_digital_playback;
11544         spec->stream_digital_capture = &alc662_pcm_digital_capture;
11545
11546         if (!spec->adc_nids && spec->input_mux) {
11547                 spec->adc_nids = alc662_adc_nids;
11548                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11549         }
11550
11551         codec->patch_ops = alc_patch_ops;
11552         if (board_config == ALC662_AUTO)
11553                 spec->init_hook = alc662_auto_init;
11554
11555         return 0;
11556 }
11557
11558 /*
11559  * patch entries
11560  */
11561 struct hda_codec_preset snd_hda_preset_realtek[] = {
11562         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11563         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11564         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11565         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11566           .patch = patch_alc861 },
11567         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11568         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11569         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11570         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11571           .patch = patch_alc883 },
11572         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11573           .patch = patch_alc662 },
11574         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11575         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11576         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11577         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11578         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11579         {} /* terminator */
11580 };