[ALSA] hda-codec - sort pci quirk list
[pandora-kernel.git] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_HP_TC_T5735,
96         ALC262_BENQ_ED8,
97         ALC262_SONY_ASSAMD,
98         ALC262_BENQ_T31,
99         ALC262_ULTRA,
100         ALC262_AUTO,
101         ALC262_MODEL_LAST /* last tag */
102 };
103
104 /* ALC268 models */
105 enum {
106         ALC268_3ST,
107         ALC268_TOSHIBA,
108         ALC268_ACER,
109         ALC268_AUTO,
110         ALC268_MODEL_LAST /* last tag */
111 };
112
113 /* ALC269 models */
114 enum {
115         ALC269_BASIC,
116         ALC269_AUTO,
117         ALC269_MODEL_LAST /* last tag */
118 };
119
120 /* ALC861 models */
121 enum {
122         ALC861_3ST,
123         ALC660_3ST,
124         ALC861_3ST_DIG,
125         ALC861_6ST_DIG,
126         ALC861_UNIWILL_M31,
127         ALC861_TOSHIBA,
128         ALC861_ASUS,
129         ALC861_ASUS_LAPTOP,
130         ALC861_AUTO,
131         ALC861_MODEL_LAST,
132 };
133
134 /* ALC861-VD models */
135 enum {
136         ALC660VD_3ST,
137         ALC660VD_3ST_DIG,
138         ALC861VD_3ST,
139         ALC861VD_3ST_DIG,
140         ALC861VD_6ST_DIG,
141         ALC861VD_LENOVO,
142         ALC861VD_DALLAS,
143         ALC861VD_HP,
144         ALC861VD_AUTO,
145         ALC861VD_MODEL_LAST,
146 };
147
148 /* ALC662 models */
149 enum {
150         ALC662_3ST_2ch_DIG,
151         ALC662_3ST_6ch_DIG,
152         ALC662_3ST_6ch,
153         ALC662_5ST_DIG,
154         ALC662_LENOVO_101E,
155         ALC662_ASUS_EEEPC_P701,
156         ALC662_AUTO,
157         ALC662_MODEL_LAST,
158 };
159
160 /* ALC882 models */
161 enum {
162         ALC882_3ST_DIG,
163         ALC882_6ST_DIG,
164         ALC882_ARIMA,
165         ALC882_W2JC,
166         ALC882_TARGA,
167         ALC882_ASUS_A7J,
168         ALC882_ASUS_A7M,
169         ALC885_MACPRO,
170         ALC885_MBP3,
171         ALC885_IMAC24,
172         ALC882_AUTO,
173         ALC882_MODEL_LAST,
174 };
175
176 /* ALC883 models */
177 enum {
178         ALC883_3ST_2ch_DIG,
179         ALC883_3ST_6ch_DIG,
180         ALC883_3ST_6ch,
181         ALC883_6ST_DIG,
182         ALC883_TARGA_DIG,
183         ALC883_TARGA_2ch_DIG,
184         ALC883_ACER,
185         ALC883_ACER_ASPIRE,
186         ALC883_MEDION,
187         ALC883_MEDION_MD2,      
188         ALC883_LAPTOP_EAPD,
189         ALC883_LENOVO_101E_2ch,
190         ALC883_LENOVO_NB0763,
191         ALC888_LENOVO_MS7195_DIG,
192         ALC883_HAIER_W66,               
193         ALC888_6ST_HP,
194         ALC888_3ST_HP,
195         ALC883_MITAC,
196         ALC883_AUTO,
197         ALC883_MODEL_LAST,
198 };
199
200 /* for GPIO Poll */
201 #define GPIO_MASK       0x03
202
203 struct alc_spec {
204         /* codec parameterization */
205         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
206         unsigned int num_mixers;
207
208         const struct hda_verb *init_verbs[5];   /* initialization verbs
209                                                  * don't forget NULL
210                                                  * termination!
211                                                  */
212         unsigned int num_init_verbs;
213
214         char *stream_name_analog;       /* analog PCM stream */
215         struct hda_pcm_stream *stream_analog_playback;
216         struct hda_pcm_stream *stream_analog_capture;
217
218         char *stream_name_digital;      /* digital PCM stream */
219         struct hda_pcm_stream *stream_digital_playback;
220         struct hda_pcm_stream *stream_digital_capture;
221
222         /* playback */
223         struct hda_multi_out multiout;  /* playback set-up
224                                          * max_channels, dacs must be set
225                                          * dig_out_nid and hp_nid are optional
226                                          */
227
228         /* capture */
229         unsigned int num_adc_nids;
230         hda_nid_t *adc_nids;
231         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
232
233         /* capture source */
234         unsigned int num_mux_defs;
235         const struct hda_input_mux *input_mux;
236         unsigned int cur_mux[3];
237
238         /* channel model */
239         const struct hda_channel_mode *channel_mode;
240         int num_channel_mode;
241         int need_dac_fix;
242
243         /* PCM information */
244         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
245
246         /* dynamic controls, init_verbs and input_mux */
247         struct auto_pin_cfg autocfg;
248         unsigned int num_kctl_alloc, num_kctl_used;
249         struct snd_kcontrol_new *kctl_alloc;
250         struct hda_input_mux private_imux;
251         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
252
253         /* hooks */
254         void (*init_hook)(struct hda_codec *codec);
255         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
256
257         /* for pin sensing */
258         unsigned int sense_updated: 1;
259         unsigned int jack_present: 1;
260
261 #ifdef CONFIG_SND_HDA_POWER_SAVE
262         struct hda_loopback_check loopback;
263 #endif
264 };
265
266 /*
267  * configuration template - to be copied to the spec instance
268  */
269 struct alc_config_preset {
270         struct snd_kcontrol_new *mixers[5]; /* should be identical size
271                                              * with spec
272                                              */
273         const struct hda_verb *init_verbs[5];
274         unsigned int num_dacs;
275         hda_nid_t *dac_nids;
276         hda_nid_t dig_out_nid;          /* optional */
277         hda_nid_t hp_nid;               /* optional */
278         unsigned int num_adc_nids;
279         hda_nid_t *adc_nids;
280         hda_nid_t dig_in_nid;
281         unsigned int num_channel_mode;
282         const struct hda_channel_mode *channel_mode;
283         int need_dac_fix;
284         unsigned int num_mux_defs;
285         const struct hda_input_mux *input_mux;
286         void (*unsol_event)(struct hda_codec *, unsigned int);
287         void (*init_hook)(struct hda_codec *);
288 #ifdef CONFIG_SND_HDA_POWER_SAVE
289         struct hda_amp_list *loopbacks;
290 #endif
291 };
292
293
294 /*
295  * input MUX handling
296  */
297 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
298                              struct snd_ctl_elem_info *uinfo)
299 {
300         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
301         struct alc_spec *spec = codec->spec;
302         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
303         if (mux_idx >= spec->num_mux_defs)
304                 mux_idx = 0;
305         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
306 }
307
308 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
309                             struct snd_ctl_elem_value *ucontrol)
310 {
311         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
312         struct alc_spec *spec = codec->spec;
313         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
314
315         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
316         return 0;
317 }
318
319 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
320                             struct snd_ctl_elem_value *ucontrol)
321 {
322         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
323         struct alc_spec *spec = codec->spec;
324         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
325         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
326         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
327                                      spec->adc_nids[adc_idx],
328                                      &spec->cur_mux[adc_idx]);
329 }
330
331
332 /*
333  * channel mode setting
334  */
335 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
336                             struct snd_ctl_elem_info *uinfo)
337 {
338         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
339         struct alc_spec *spec = codec->spec;
340         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
341                                     spec->num_channel_mode);
342 }
343
344 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
345                            struct snd_ctl_elem_value *ucontrol)
346 {
347         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
348         struct alc_spec *spec = codec->spec;
349         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
350                                    spec->num_channel_mode,
351                                    spec->multiout.max_channels);
352 }
353
354 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
355                            struct snd_ctl_elem_value *ucontrol)
356 {
357         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
358         struct alc_spec *spec = codec->spec;
359         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
360                                       spec->num_channel_mode,
361                                       &spec->multiout.max_channels);
362         if (err >= 0 && spec->need_dac_fix)
363                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
364         return err;
365 }
366
367 /*
368  * Control the mode of pin widget settings via the mixer.  "pc" is used
369  * instead of "%" to avoid consequences of accidently treating the % as 
370  * being part of a format specifier.  Maximum allowed length of a value is
371  * 63 characters plus NULL terminator.
372  *
373  * Note: some retasking pin complexes seem to ignore requests for input
374  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
375  * are requested.  Therefore order this list so that this behaviour will not
376  * cause problems when mixer clients move through the enum sequentially.
377  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
378  * March 2006.
379  */
380 static char *alc_pin_mode_names[] = {
381         "Mic 50pc bias", "Mic 80pc bias",
382         "Line in", "Line out", "Headphone out",
383 };
384 static unsigned char alc_pin_mode_values[] = {
385         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
386 };
387 /* The control can present all 5 options, or it can limit the options based
388  * in the pin being assumed to be exclusively an input or an output pin.  In
389  * addition, "input" pins may or may not process the mic bias option
390  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
391  * accept requests for bias as of chip versions up to March 2006) and/or
392  * wiring in the computer.
393  */
394 #define ALC_PIN_DIR_IN              0x00
395 #define ALC_PIN_DIR_OUT             0x01
396 #define ALC_PIN_DIR_INOUT           0x02
397 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
398 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
399
400 /* Info about the pin modes supported by the different pin direction modes. 
401  * For each direction the minimum and maximum values are given.
402  */
403 static signed char alc_pin_mode_dir_info[5][2] = {
404         { 0, 2 },    /* ALC_PIN_DIR_IN */
405         { 3, 4 },    /* ALC_PIN_DIR_OUT */
406         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
407         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
408         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
409 };
410 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
411 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
412 #define alc_pin_mode_n_items(_dir) \
413         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
414
415 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
416                              struct snd_ctl_elem_info *uinfo)
417 {
418         unsigned int item_num = uinfo->value.enumerated.item;
419         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
420
421         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
422         uinfo->count = 1;
423         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
424
425         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
426                 item_num = alc_pin_mode_min(dir);
427         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
428         return 0;
429 }
430
431 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
432                             struct snd_ctl_elem_value *ucontrol)
433 {
434         unsigned int i;
435         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
436         hda_nid_t nid = kcontrol->private_value & 0xffff;
437         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
438         long *valp = ucontrol->value.integer.value;
439         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
440                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
441                                                  0x00);
442
443         /* Find enumerated value for current pinctl setting */
444         i = alc_pin_mode_min(dir);
445         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
446                 i++;
447         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
448         return 0;
449 }
450
451 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
452                             struct snd_ctl_elem_value *ucontrol)
453 {
454         signed int change;
455         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
456         hda_nid_t nid = kcontrol->private_value & 0xffff;
457         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
458         long val = *ucontrol->value.integer.value;
459         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
460                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
461                                                  0x00);
462
463         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
464                 val = alc_pin_mode_min(dir);
465
466         change = pinctl != alc_pin_mode_values[val];
467         if (change) {
468                 /* Set pin mode to that requested */
469                 snd_hda_codec_write_cache(codec, nid, 0,
470                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
471                                           alc_pin_mode_values[val]);
472
473                 /* Also enable the retasking pin's input/output as required 
474                  * for the requested pin mode.  Enum values of 2 or less are
475                  * input modes.
476                  *
477                  * Dynamically switching the input/output buffers probably
478                  * reduces noise slightly (particularly on input) so we'll
479                  * do it.  However, having both input and output buffers
480                  * enabled simultaneously doesn't seem to be problematic if
481                  * this turns out to be necessary in the future.
482                  */
483                 if (val <= 2) {
484                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
485                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
486                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
487                                                  HDA_AMP_MUTE, 0);
488                 } else {
489                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
490                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
491                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
492                                                  HDA_AMP_MUTE, 0);
493                 }
494         }
495         return change;
496 }
497
498 #define ALC_PIN_MODE(xname, nid, dir) \
499         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
500           .info = alc_pin_mode_info, \
501           .get = alc_pin_mode_get, \
502           .put = alc_pin_mode_put, \
503           .private_value = nid | (dir<<16) }
504
505 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
506  * together using a mask with more than one bit set.  This control is
507  * currently used only by the ALC260 test model.  At this stage they are not
508  * needed for any "production" models.
509  */
510 #ifdef CONFIG_SND_DEBUG
511 #define alc_gpio_data_info      snd_ctl_boolean_mono_info
512
513 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
514                              struct snd_ctl_elem_value *ucontrol)
515 {
516         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517         hda_nid_t nid = kcontrol->private_value & 0xffff;
518         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
519         long *valp = ucontrol->value.integer.value;
520         unsigned int val = snd_hda_codec_read(codec, nid, 0,
521                                               AC_VERB_GET_GPIO_DATA, 0x00);
522
523         *valp = (val & mask) != 0;
524         return 0;
525 }
526 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
527                              struct snd_ctl_elem_value *ucontrol)
528 {
529         signed int change;
530         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
531         hda_nid_t nid = kcontrol->private_value & 0xffff;
532         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
533         long val = *ucontrol->value.integer.value;
534         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
535                                                     AC_VERB_GET_GPIO_DATA,
536                                                     0x00);
537
538         /* Set/unset the masked GPIO bit(s) as needed */
539         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
540         if (val == 0)
541                 gpio_data &= ~mask;
542         else
543                 gpio_data |= mask;
544         snd_hda_codec_write_cache(codec, nid, 0,
545                                   AC_VERB_SET_GPIO_DATA, gpio_data);
546
547         return change;
548 }
549 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
550         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
551           .info = alc_gpio_data_info, \
552           .get = alc_gpio_data_get, \
553           .put = alc_gpio_data_put, \
554           .private_value = nid | (mask<<16) }
555 #endif   /* CONFIG_SND_DEBUG */
556
557 /* A switch control to allow the enabling of the digital IO pins on the
558  * ALC260.  This is incredibly simplistic; the intention of this control is
559  * to provide something in the test model allowing digital outputs to be
560  * identified if present.  If models are found which can utilise these
561  * outputs a more complete mixer control can be devised for those models if
562  * necessary.
563  */
564 #ifdef CONFIG_SND_DEBUG
565 #define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
566
567 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
568                               struct snd_ctl_elem_value *ucontrol)
569 {
570         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
571         hda_nid_t nid = kcontrol->private_value & 0xffff;
572         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
573         long *valp = ucontrol->value.integer.value;
574         unsigned int val = snd_hda_codec_read(codec, nid, 0,
575                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
576
577         *valp = (val & mask) != 0;
578         return 0;
579 }
580 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
581                               struct snd_ctl_elem_value *ucontrol)
582 {
583         signed int change;
584         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585         hda_nid_t nid = kcontrol->private_value & 0xffff;
586         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
587         long val = *ucontrol->value.integer.value;
588         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
589                                                     AC_VERB_GET_DIGI_CONVERT,
590                                                     0x00);
591
592         /* Set/unset the masked control bit(s) as needed */
593         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
594         if (val==0)
595                 ctrl_data &= ~mask;
596         else
597                 ctrl_data |= mask;
598         snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
599                                   ctrl_data);
600
601         return change;
602 }
603 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
604         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
605           .info = alc_spdif_ctrl_info, \
606           .get = alc_spdif_ctrl_get, \
607           .put = alc_spdif_ctrl_put, \
608           .private_value = nid | (mask<<16) }
609 #endif   /* CONFIG_SND_DEBUG */
610
611 /*
612  * set up from the preset table
613  */
614 static void setup_preset(struct alc_spec *spec,
615                          const struct alc_config_preset *preset)
616 {
617         int i;
618
619         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
620                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
621         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
622              i++)
623                 spec->init_verbs[spec->num_init_verbs++] =
624                         preset->init_verbs[i];
625         
626         spec->channel_mode = preset->channel_mode;
627         spec->num_channel_mode = preset->num_channel_mode;
628         spec->need_dac_fix = preset->need_dac_fix;
629
630         spec->multiout.max_channels = spec->channel_mode[0].channels;
631
632         spec->multiout.num_dacs = preset->num_dacs;
633         spec->multiout.dac_nids = preset->dac_nids;
634         spec->multiout.dig_out_nid = preset->dig_out_nid;
635         spec->multiout.hp_nid = preset->hp_nid;
636         
637         spec->num_mux_defs = preset->num_mux_defs;
638         if (!spec->num_mux_defs)
639                 spec->num_mux_defs = 1;
640         spec->input_mux = preset->input_mux;
641
642         spec->num_adc_nids = preset->num_adc_nids;
643         spec->adc_nids = preset->adc_nids;
644         spec->dig_in_nid = preset->dig_in_nid;
645
646         spec->unsol_event = preset->unsol_event;
647         spec->init_hook = preset->init_hook;
648 #ifdef CONFIG_SND_HDA_POWER_SAVE
649         spec->loopback.amplist = preset->loopbacks;
650 #endif
651 }
652
653 /* Enable GPIO mask and set output */
654 static struct hda_verb alc_gpio1_init_verbs[] = {
655         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
656         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
657         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
658         { }
659 };
660
661 static struct hda_verb alc_gpio2_init_verbs[] = {
662         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
663         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
664         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
665         { }
666 };
667
668 static struct hda_verb alc_gpio3_init_verbs[] = {
669         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
670         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
671         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
672         { }
673 };
674
675 static void alc_sku_automute(struct hda_codec *codec)
676 {
677         struct alc_spec *spec = codec->spec;
678         unsigned int mute;
679         unsigned int present;
680         unsigned int hp_nid = spec->autocfg.hp_pins[0];
681         unsigned int sp_nid = spec->autocfg.speaker_pins[0];
682
683         /* need to execute and sync at first */
684         snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
685         present = snd_hda_codec_read(codec, hp_nid, 0,
686                                      AC_VERB_GET_PIN_SENSE, 0);
687         spec->jack_present = (present & 0x80000000) != 0;
688         if (spec->jack_present) {
689                 /* mute internal speaker */
690                 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
691                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
692         } else {
693                 /* unmute internal speaker if necessary */
694                 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
695                 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
696                                          HDA_AMP_MUTE, mute);
697         }
698 }
699
700 /* unsolicited event for HP jack sensing */
701 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
702 {
703         if (codec->vendor_id == 0x10ec0880)
704                 res >>= 28;
705         else
706                 res >>= 26;
707         if (res != ALC880_HP_EVENT)
708                 return;
709
710         alc_sku_automute(codec);
711 }
712
713 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
714  *      31 ~ 16 :       Manufacture ID
715  *      15 ~ 8  :       SKU ID
716  *      7  ~ 0  :       Assembly ID
717  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
718  */
719 static void alc_subsystem_id(struct hda_codec *codec,
720                              unsigned int porta, unsigned int porte,
721                              unsigned int portd)
722 {
723         unsigned int ass, tmp, i;
724         unsigned nid;
725         struct alc_spec *spec = codec->spec;
726
727         ass = codec->subsystem_id & 0xffff;
728         if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
729                 goto do_sku;
730
731         /*      
732          * 31~30        : port conetcivity
733          * 29~21        : reserve
734          * 20           : PCBEEP input
735          * 19~16        : Check sum (15:1)
736          * 15~1         : Custom
737          * 0            : override
738         */
739         nid = 0x1d;
740         if (codec->vendor_id == 0x10ec0260)
741                 nid = 0x17;
742         ass = snd_hda_codec_read(codec, nid, 0,
743                                  AC_VERB_GET_CONFIG_DEFAULT, 0);
744         if (!(ass & 1) && !(ass & 0x100000))
745                 return;
746         if ((ass >> 30) != 1)   /* no physical connection */
747                 return;
748
749         /* check sum */
750         tmp = 0;
751         for (i = 1; i < 16; i++) {
752                 if ((ass >> i) && 1)
753                         tmp++;
754         }
755         if (((ass >> 16) & 0xf) != tmp)
756                 return;
757 do_sku:
758         /*
759          * 0 : override
760          * 1 :  Swap Jack
761          * 2 : 0 --> Desktop, 1 --> Laptop
762          * 3~5 : External Amplifier control
763          * 7~6 : Reserved
764         */
765         tmp = (ass & 0x38) >> 3;        /* external Amp control */
766         switch (tmp) {
767         case 1:
768                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
769                 break;
770         case 3:
771                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
772                 break;
773         case 7:
774                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
775                 break;
776         case 5: /* set EAPD output high */
777                 switch (codec->vendor_id) {
778                 case 0x10ec0260:
779                         snd_hda_codec_write(codec, 0x0f, 0,
780                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
781                         snd_hda_codec_write(codec, 0x10, 0,
782                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
783                         break;
784                 case 0x10ec0262:
785                 case 0x10ec0267:
786                 case 0x10ec0268:
787                 case 0x10ec0269:
788                 case 0x10ec0862:
789                 case 0x10ec0662:        
790                         snd_hda_codec_write(codec, 0x14, 0,
791                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
792                         snd_hda_codec_write(codec, 0x15, 0,
793                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
794                         break;
795                 }
796                 switch (codec->vendor_id) {
797                 case 0x10ec0260:
798                         snd_hda_codec_write(codec, 0x1a, 0,
799                                             AC_VERB_SET_COEF_INDEX, 7);
800                         tmp = snd_hda_codec_read(codec, 0x1a, 0,
801                                                  AC_VERB_GET_PROC_COEF, 0);
802                         snd_hda_codec_write(codec, 0x1a, 0,
803                                             AC_VERB_SET_COEF_INDEX, 7);
804                         snd_hda_codec_write(codec, 0x1a, 0,
805                                             AC_VERB_SET_PROC_COEF,
806                                             tmp | 0x2010);
807                         break;
808                 case 0x10ec0262:
809                 case 0x10ec0880:
810                 case 0x10ec0882:
811                 case 0x10ec0883:
812                 case 0x10ec0885:
813                 case 0x10ec0888:
814                         snd_hda_codec_write(codec, 0x20, 0,
815                                             AC_VERB_SET_COEF_INDEX, 7);
816                         tmp = snd_hda_codec_read(codec, 0x20, 0,
817                                                  AC_VERB_GET_PROC_COEF, 0);
818                         snd_hda_codec_write(codec, 0x20, 0,
819                                             AC_VERB_SET_COEF_INDEX, 7); 
820                         snd_hda_codec_write(codec, 0x20, 0,
821                                             AC_VERB_SET_PROC_COEF,
822                                             tmp | 0x2010);
823                         break;
824                 case 0x10ec0267:
825                 case 0x10ec0268:
826                         snd_hda_codec_write(codec, 0x20, 0,
827                                             AC_VERB_SET_COEF_INDEX, 7);
828                         tmp = snd_hda_codec_read(codec, 0x20, 0,
829                                                  AC_VERB_GET_PROC_COEF, 0);
830                         snd_hda_codec_write(codec, 0x20, 0,
831                                             AC_VERB_SET_COEF_INDEX, 7); 
832                         snd_hda_codec_write(codec, 0x20, 0,
833                                             AC_VERB_SET_PROC_COEF,
834                                             tmp | 0x3000);
835                         break;
836                 }
837         default:
838                 break;
839         }
840         
841         /* is laptop and enable the function "Mute internal speaker
842          * when the external headphone out jack is plugged"
843          */
844         if (!(ass & 0x4) || !(ass & 0x8000))
845                 return;
846         /*
847          * 10~8 : Jack location
848          * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
849          * 14~13: Resvered
850          * 15   : 1 --> enable the function "Mute internal speaker
851          *              when the external headphone out jack is plugged"
852          */
853         if (!spec->autocfg.speaker_pins[0]) {
854                 if (spec->multiout.dac_nids[0])
855                         spec->autocfg.speaker_pins[0] =
856                                 spec->multiout.dac_nids[0];
857                 else
858                         return;
859         }
860
861         if (!spec->autocfg.hp_pins[0]) {
862                 tmp = (ass >> 11) & 0x3;        /* HP to chassis */
863                 if (tmp == 0)
864                         spec->autocfg.hp_pins[0] = porta;
865                 else if (tmp == 1)
866                         spec->autocfg.hp_pins[0] = porte;
867                 else if (tmp == 2)
868                         spec->autocfg.hp_pins[0] = portd;
869                 else
870                         return;
871         }
872
873         snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
874                             AC_VERB_SET_UNSOLICITED_ENABLE,
875                             AC_USRSP_EN | ALC880_HP_EVENT);
876         spec->unsol_event = alc_sku_unsol_event;
877         spec->init_hook = alc_sku_automute;     
878 }
879
880 /*
881  * Fix-up pin default configurations
882  */
883
884 struct alc_pincfg {
885         hda_nid_t nid;
886         u32 val;
887 };
888
889 static void alc_fix_pincfg(struct hda_codec *codec,
890                            const struct snd_pci_quirk *quirk,
891                            const struct alc_pincfg **pinfix)
892 {
893         const struct alc_pincfg *cfg;
894
895         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
896         if (!quirk)
897                 return;
898
899         cfg = pinfix[quirk->value];
900         for (; cfg->nid; cfg++) {
901                 int i;
902                 u32 val = cfg->val;
903                 for (i = 0; i < 4; i++) {
904                         snd_hda_codec_write(codec, cfg->nid, 0,
905                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
906                                     val & 0xff);
907                         val >>= 8;
908                 }
909         }
910 }
911
912 /*
913  * ALC880 3-stack model
914  *
915  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
916  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
917  *                 F-Mic = 0x1b, HP = 0x19
918  */
919
920 static hda_nid_t alc880_dac_nids[4] = {
921         /* front, rear, clfe, rear_surr */
922         0x02, 0x05, 0x04, 0x03
923 };
924
925 static hda_nid_t alc880_adc_nids[3] = {
926         /* ADC0-2 */
927         0x07, 0x08, 0x09,
928 };
929
930 /* The datasheet says the node 0x07 is connected from inputs,
931  * but it shows zero connection in the real implementation on some devices.
932  * Note: this is a 915GAV bug, fixed on 915GLV
933  */
934 static hda_nid_t alc880_adc_nids_alt[2] = {
935         /* ADC1-2 */
936         0x08, 0x09,
937 };
938
939 #define ALC880_DIGOUT_NID       0x06
940 #define ALC880_DIGIN_NID        0x0a
941
942 static struct hda_input_mux alc880_capture_source = {
943         .num_items = 4,
944         .items = {
945                 { "Mic", 0x0 },
946                 { "Front Mic", 0x3 },
947                 { "Line", 0x2 },
948                 { "CD", 0x4 },
949         },
950 };
951
952 /* channel source setting (2/6 channel selection for 3-stack) */
953 /* 2ch mode */
954 static struct hda_verb alc880_threestack_ch2_init[] = {
955         /* set line-in to input, mute it */
956         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
957         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
958         /* set mic-in to input vref 80%, mute it */
959         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
960         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
961         { } /* end */
962 };
963
964 /* 6ch mode */
965 static struct hda_verb alc880_threestack_ch6_init[] = {
966         /* set line-in to output, unmute it */
967         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
968         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
969         /* set mic-in to output, unmute it */
970         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
971         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
972         { } /* end */
973 };
974
975 static struct hda_channel_mode alc880_threestack_modes[2] = {
976         { 2, alc880_threestack_ch2_init },
977         { 6, alc880_threestack_ch6_init },
978 };
979
980 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
981         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
982         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
983         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
984         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
985         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
986         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
987         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
988         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
989         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
990         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
991         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
992         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
993         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
994         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
995         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
996         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
997         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
998         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
999         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1000         {
1001                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1002                 .name = "Channel Mode",
1003                 .info = alc_ch_mode_info,
1004                 .get = alc_ch_mode_get,
1005                 .put = alc_ch_mode_put,
1006         },
1007         { } /* end */
1008 };
1009
1010 /* capture mixer elements */
1011 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1012         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1013         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1014         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1015         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1016         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1017         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1018         {
1019                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1020                 /* The multiple "Capture Source" controls confuse alsamixer
1021                  * So call somewhat different..
1022                  * FIXME: the controls appear in the "playback" view!
1023                  */
1024                 /* .name = "Capture Source", */
1025                 .name = "Input Source",
1026                 .count = 3,
1027                 .info = alc_mux_enum_info,
1028                 .get = alc_mux_enum_get,
1029                 .put = alc_mux_enum_put,
1030         },
1031         { } /* end */
1032 };
1033
1034 /* capture mixer elements (in case NID 0x07 not available) */
1035 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1036         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1037         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1038         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1039         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1040         {
1041                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1042                 /* The multiple "Capture Source" controls confuse alsamixer
1043                  * So call somewhat different..
1044                  * FIXME: the controls appear in the "playback" view!
1045                  */
1046                 /* .name = "Capture Source", */
1047                 .name = "Input Source",
1048                 .count = 2,
1049                 .info = alc_mux_enum_info,
1050                 .get = alc_mux_enum_get,
1051                 .put = alc_mux_enum_put,
1052         },
1053         { } /* end */
1054 };
1055
1056
1057
1058 /*
1059  * ALC880 5-stack model
1060  *
1061  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1062  *      Side = 0x02 (0xd)
1063  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1064  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1065  */
1066
1067 /* additional mixers to alc880_three_stack_mixer */
1068 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1069         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1070         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1071         { } /* end */
1072 };
1073
1074 /* channel source setting (6/8 channel selection for 5-stack) */
1075 /* 6ch mode */
1076 static struct hda_verb alc880_fivestack_ch6_init[] = {
1077         /* set line-in to input, mute it */
1078         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1079         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1080         { } /* end */
1081 };
1082
1083 /* 8ch mode */
1084 static struct hda_verb alc880_fivestack_ch8_init[] = {
1085         /* set line-in to output, unmute it */
1086         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1087         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1088         { } /* end */
1089 };
1090
1091 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1092         { 6, alc880_fivestack_ch6_init },
1093         { 8, alc880_fivestack_ch8_init },
1094 };
1095
1096
1097 /*
1098  * ALC880 6-stack model
1099  *
1100  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1101  *      Side = 0x05 (0x0f)
1102  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1103  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1104  */
1105
1106 static hda_nid_t alc880_6st_dac_nids[4] = {
1107         /* front, rear, clfe, rear_surr */
1108         0x02, 0x03, 0x04, 0x05
1109 };
1110
1111 static struct hda_input_mux alc880_6stack_capture_source = {
1112         .num_items = 4,
1113         .items = {
1114                 { "Mic", 0x0 },
1115                 { "Front Mic", 0x1 },
1116                 { "Line", 0x2 },
1117                 { "CD", 0x4 },
1118         },
1119 };
1120
1121 /* fixed 8-channels */
1122 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1123         { 8, NULL },
1124 };
1125
1126 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1127         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1128         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1129         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1130         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1131         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1132         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1133         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1134         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1135         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1136         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1137         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1138         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1139         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1140         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1141         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1142         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1143         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1144         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1145         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1146         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1147         {
1148                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1149                 .name = "Channel Mode",
1150                 .info = alc_ch_mode_info,
1151                 .get = alc_ch_mode_get,
1152                 .put = alc_ch_mode_put,
1153         },
1154         { } /* end */
1155 };
1156
1157
1158 /*
1159  * ALC880 W810 model
1160  *
1161  * W810 has rear IO for:
1162  * Front (DAC 02)
1163  * Surround (DAC 03)
1164  * Center/LFE (DAC 04)
1165  * Digital out (06)
1166  *
1167  * The system also has a pair of internal speakers, and a headphone jack.
1168  * These are both connected to Line2 on the codec, hence to DAC 02.
1169  * 
1170  * There is a variable resistor to control the speaker or headphone
1171  * volume. This is a hardware-only device without a software API.
1172  *
1173  * Plugging headphones in will disable the internal speakers. This is
1174  * implemented in hardware, not via the driver using jack sense. In
1175  * a similar fashion, plugging into the rear socket marked "front" will
1176  * disable both the speakers and headphones.
1177  *
1178  * For input, there's a microphone jack, and an "audio in" jack.
1179  * These may not do anything useful with this driver yet, because I
1180  * haven't setup any initialization verbs for these yet...
1181  */
1182
1183 static hda_nid_t alc880_w810_dac_nids[3] = {
1184         /* front, rear/surround, clfe */
1185         0x02, 0x03, 0x04
1186 };
1187
1188 /* fixed 6 channels */
1189 static struct hda_channel_mode alc880_w810_modes[1] = {
1190         { 6, NULL }
1191 };
1192
1193 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1194 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1195         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1196         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1197         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1198         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1199         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1200         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1201         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1202         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1203         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1204         { } /* end */
1205 };
1206
1207
1208 /*
1209  * Z710V model
1210  *
1211  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1212  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1213  *                 Line = 0x1a
1214  */
1215
1216 static hda_nid_t alc880_z71v_dac_nids[1] = {
1217         0x02
1218 };
1219 #define ALC880_Z71V_HP_DAC      0x03
1220
1221 /* fixed 2 channels */
1222 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1223         { 2, NULL }
1224 };
1225
1226 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1227         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1228         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1229         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1230         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1231         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1232         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1233         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1234         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1235         { } /* end */
1236 };
1237
1238
1239 /* FIXME! */
1240 /*
1241  * ALC880 F1734 model
1242  *
1243  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1244  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1245  */
1246
1247 static hda_nid_t alc880_f1734_dac_nids[1] = {
1248         0x03
1249 };
1250 #define ALC880_F1734_HP_DAC     0x02
1251
1252 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1253         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1254         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1255         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1256         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1257         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1258         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1259         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1260         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1261         { } /* end */
1262 };
1263
1264
1265 /* FIXME! */
1266 /*
1267  * ALC880 ASUS model
1268  *
1269  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1270  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1271  *  Mic = 0x18, Line = 0x1a
1272  */
1273
1274 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1275 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1276
1277 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1278         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1279         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1280         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1281         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1282         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1283         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1284         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1285         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1286         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1287         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1288         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1289         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1290         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1291         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1292         {
1293                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1294                 .name = "Channel Mode",
1295                 .info = alc_ch_mode_info,
1296                 .get = alc_ch_mode_get,
1297                 .put = alc_ch_mode_put,
1298         },
1299         { } /* end */
1300 };
1301
1302 /* FIXME! */
1303 /*
1304  * ALC880 ASUS W1V model
1305  *
1306  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1307  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1308  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1309  */
1310
1311 /* additional mixers to alc880_asus_mixer */
1312 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1313         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1314         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1315         { } /* end */
1316 };
1317
1318 /* additional mixers to alc880_asus_mixer */
1319 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1320         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1321         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1322         { } /* end */
1323 };
1324
1325 /* TCL S700 */
1326 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1327         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1328         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1329         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1330         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1331         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1332         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1333         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1334         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1335         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1336         {
1337                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1338                 /* The multiple "Capture Source" controls confuse alsamixer
1339                  * So call somewhat different..
1340                  * FIXME: the controls appear in the "playback" view!
1341                  */
1342                 /* .name = "Capture Source", */
1343                 .name = "Input Source",
1344                 .count = 1,
1345                 .info = alc_mux_enum_info,
1346                 .get = alc_mux_enum_get,
1347                 .put = alc_mux_enum_put,
1348         },
1349         { } /* end */
1350 };
1351
1352 /* Uniwill */
1353 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1354         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1355         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1356         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1357         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1358         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1359         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1360         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1361         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1362         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1363         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1364         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1365         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1366         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1367         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1368         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1369         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1370         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1371         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1372         {
1373                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1374                 .name = "Channel Mode",
1375                 .info = alc_ch_mode_info,
1376                 .get = alc_ch_mode_get,
1377                 .put = alc_ch_mode_put,
1378         },
1379         { } /* end */
1380 };
1381
1382 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1383         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1384         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1385         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1386         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1387         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1388         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1389         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1390         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1391         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1392         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1393         { } /* end */
1394 };
1395
1396 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1397         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1398         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1399         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1400         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1401         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1402         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1403         { } /* end */
1404 };
1405
1406 /*
1407  * build control elements
1408  */
1409 static int alc_build_controls(struct hda_codec *codec)
1410 {
1411         struct alc_spec *spec = codec->spec;
1412         int err;
1413         int i;
1414
1415         for (i = 0; i < spec->num_mixers; i++) {
1416                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1417                 if (err < 0)
1418                         return err;
1419         }
1420
1421         if (spec->multiout.dig_out_nid) {
1422                 err = snd_hda_create_spdif_out_ctls(codec,
1423                                                     spec->multiout.dig_out_nid);
1424                 if (err < 0)
1425                         return err;
1426         }
1427         if (spec->dig_in_nid) {
1428                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1429                 if (err < 0)
1430                         return err;
1431         }
1432         return 0;
1433 }
1434
1435
1436 /*
1437  * initialize the codec volumes, etc
1438  */
1439
1440 /*
1441  * generic initialization of ADC, input mixers and output mixers
1442  */
1443 static struct hda_verb alc880_volume_init_verbs[] = {
1444         /*
1445          * Unmute ADC0-2 and set the default input to mic-in
1446          */
1447         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1448         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1449         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1450         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1451         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1452         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1453
1454         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1455          * mixer widget
1456          * Note: PASD motherboards uses the Line In 2 as the input for front
1457          * panel mic (mic 2)
1458          */
1459         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1460         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1461         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1462         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1463         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1464         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1465         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1466         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1467
1468         /*
1469          * Set up output mixers (0x0c - 0x0f)
1470          */
1471         /* set vol=0 to output mixers */
1472         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1473         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1474         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1475         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1476         /* set up input amps for analog loopback */
1477         /* Amp Indices: DAC = 0, mixer = 1 */
1478         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1479         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1480         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1481         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1482         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1483         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1484         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1485         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1486
1487         { }
1488 };
1489
1490 /*
1491  * 3-stack pin configuration:
1492  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1493  */
1494 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1495         /*
1496          * preset connection lists of input pins
1497          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1498          */
1499         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1500         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1501         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1502
1503         /*
1504          * Set pin mode and muting
1505          */
1506         /* set front pin widgets 0x14 for output */
1507         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1508         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1509         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1510         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1511         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1512         /* Mic2 (as headphone out) for HP output */
1513         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1514         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1515         /* Line In pin widget for input */
1516         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1517         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1518         /* Line2 (as front mic) pin widget for input and vref at 80% */
1519         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1520         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1521         /* CD pin widget for input */
1522         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1523
1524         { }
1525 };
1526
1527 /*
1528  * 5-stack pin configuration:
1529  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1530  * line-in/side = 0x1a, f-mic = 0x1b
1531  */
1532 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1533         /*
1534          * preset connection lists of input pins
1535          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1536          */
1537         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1538         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1539
1540         /*
1541          * Set pin mode and muting
1542          */
1543         /* set pin widgets 0x14-0x17 for output */
1544         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1545         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1546         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1547         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1548         /* unmute pins for output (no gain on this amp) */
1549         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1550         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1551         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1552         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1553
1554         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1555         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1556         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1557         /* Mic2 (as headphone out) for HP output */
1558         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1559         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1560         /* Line In pin widget for input */
1561         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1562         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1563         /* Line2 (as front mic) pin widget for input and vref at 80% */
1564         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1565         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1566         /* CD pin widget for input */
1567         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1568
1569         { }
1570 };
1571
1572 /*
1573  * W810 pin configuration:
1574  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1575  */
1576 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1577         /* hphone/speaker input selector: front DAC */
1578         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1579
1580         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1581         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1582         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1583         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1584         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1585         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1586
1587         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1588         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1589
1590         { }
1591 };
1592
1593 /*
1594  * Z71V pin configuration:
1595  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1596  */
1597 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1598         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1599         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1600         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1601         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1602
1603         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1604         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1605         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1606         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1607
1608         { }
1609 };
1610
1611 /*
1612  * 6-stack pin configuration:
1613  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1614  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1615  */
1616 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1617         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1618
1619         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1620         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1621         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1622         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1623         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1624         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1625         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1626         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1627
1628         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1629         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1630         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1631         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1632         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1633         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1634         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1635         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1636         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1637         
1638         { }
1639 };
1640
1641 /*
1642  * Uniwill pin configuration:
1643  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1644  * line = 0x1a
1645  */
1646 static struct hda_verb alc880_uniwill_init_verbs[] = {
1647         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1648
1649         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1650         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1651         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1652         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1653         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1654         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1655         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1656         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1657         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1658         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1659         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1660         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1661         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1662         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1663
1664         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1665         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1666         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1667         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1668         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1669         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1670         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1671         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1672         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1673
1674         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1675         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1676
1677         { }
1678 };
1679
1680 /*
1681 * Uniwill P53
1682 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1683  */
1684 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1685         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1686
1687         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1688         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1689         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1690         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1692         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1694         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1695         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1696         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1697         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1698         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1699
1700         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1701         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1702         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1703         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1704         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1705         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1706
1707         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1708         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1709
1710         { }
1711 };
1712
1713 static struct hda_verb alc880_beep_init_verbs[] = {
1714         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1715         { }
1716 };
1717
1718 /* toggle speaker-output according to the hp-jack state */
1719 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1720 {
1721         unsigned int present;
1722         unsigned char bits;
1723
1724         present = snd_hda_codec_read(codec, 0x14, 0,
1725                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1726         bits = present ? HDA_AMP_MUTE : 0;
1727         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1728                                  HDA_AMP_MUTE, bits);
1729         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1730                                  HDA_AMP_MUTE, bits);
1731 }
1732
1733 /* auto-toggle front mic */
1734 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1735 {
1736         unsigned int present;
1737         unsigned char bits;
1738
1739         present = snd_hda_codec_read(codec, 0x18, 0,
1740                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1741         bits = present ? HDA_AMP_MUTE : 0;
1742         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1743 }
1744
1745 static void alc880_uniwill_automute(struct hda_codec *codec)
1746 {
1747         alc880_uniwill_hp_automute(codec);
1748         alc880_uniwill_mic_automute(codec);
1749 }
1750
1751 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1752                                        unsigned int res)
1753 {
1754         /* Looks like the unsol event is incompatible with the standard
1755          * definition.  4bit tag is placed at 28 bit!
1756          */
1757         switch (res >> 28) {
1758         case ALC880_HP_EVENT:
1759                 alc880_uniwill_hp_automute(codec);
1760                 break;
1761         case ALC880_MIC_EVENT:
1762                 alc880_uniwill_mic_automute(codec);
1763                 break;
1764         }
1765 }
1766
1767 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1768 {
1769         unsigned int present;
1770         unsigned char bits;
1771
1772         present = snd_hda_codec_read(codec, 0x14, 0,
1773                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1774         bits = present ? HDA_AMP_MUTE : 0;
1775         snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1776 }
1777
1778 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1779 {
1780         unsigned int present;
1781         
1782         present = snd_hda_codec_read(codec, 0x21, 0,
1783                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1784         present &= HDA_AMP_VOLMASK;
1785         snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1786                                  HDA_AMP_VOLMASK, present);
1787         snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1788                                  HDA_AMP_VOLMASK, present);
1789 }
1790
1791 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1792                                            unsigned int res)
1793 {
1794         /* Looks like the unsol event is incompatible with the standard
1795          * definition.  4bit tag is placed at 28 bit!
1796          */
1797         if ((res >> 28) == ALC880_HP_EVENT)
1798                 alc880_uniwill_p53_hp_automute(codec);
1799         if ((res >> 28) == ALC880_DCVOL_EVENT)
1800                 alc880_uniwill_p53_dcvol_automute(codec);
1801 }
1802
1803 /* FIXME! */
1804 /*
1805  * F1734 pin configuration:
1806  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1807  */
1808 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1809         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1810         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1811         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1812         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1813
1814         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1815         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1816         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1817         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1818
1819         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1820         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1821         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1822         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1823         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1824         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1825         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1826         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1827         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1828
1829         { }
1830 };
1831
1832 /* FIXME! */
1833 /*
1834  * ASUS pin configuration:
1835  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1836  */
1837 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1838         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1839         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1840         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1841         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1842
1843         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1844         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1845         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1846         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1847         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1848         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1849         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1850         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1851
1852         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1853         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1854         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1855         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1856         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1857         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1858         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1859         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1860         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1861         
1862         { }
1863 };
1864
1865 /* Enable GPIO mask and set output */
1866 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1867 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1868
1869 /* Clevo m520g init */
1870 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1871         /* headphone output */
1872         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1873         /* line-out */
1874         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1875         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1876         /* Line-in */
1877         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1878         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1879         /* CD */
1880         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1881         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1882         /* Mic1 (rear panel) */
1883         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1884         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1885         /* Mic2 (front panel) */
1886         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1887         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1888         /* headphone */
1889         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1890         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1891         /* change to EAPD mode */
1892         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1893         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1894
1895         { }
1896 };
1897
1898 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1899         /* change to EAPD mode */
1900         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1901         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1902
1903         /* Headphone output */
1904         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1905         /* Front output*/
1906         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1907         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1908
1909         /* Line In pin widget for input */
1910         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1911         /* CD pin widget for input */
1912         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1913         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1914         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1915
1916         /* change to EAPD mode */
1917         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1918         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1919
1920         { }
1921 };
1922
1923 /*
1924  * LG m1 express dual
1925  *
1926  * Pin assignment:
1927  *   Rear Line-In/Out (blue): 0x14
1928  *   Build-in Mic-In: 0x15
1929  *   Speaker-out: 0x17
1930  *   HP-Out (green): 0x1b
1931  *   Mic-In/Out (red): 0x19
1932  *   SPDIF-Out: 0x1e
1933  */
1934
1935 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1936 static hda_nid_t alc880_lg_dac_nids[3] = {
1937         0x05, 0x02, 0x03
1938 };
1939
1940 /* seems analog CD is not working */
1941 static struct hda_input_mux alc880_lg_capture_source = {
1942         .num_items = 3,
1943         .items = {
1944                 { "Mic", 0x1 },
1945                 { "Line", 0x5 },
1946                 { "Internal Mic", 0x6 },
1947         },
1948 };
1949
1950 /* 2,4,6 channel modes */
1951 static struct hda_verb alc880_lg_ch2_init[] = {
1952         /* set line-in and mic-in to input */
1953         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1954         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1955         { }
1956 };
1957
1958 static struct hda_verb alc880_lg_ch4_init[] = {
1959         /* set line-in to out and mic-in to input */
1960         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1961         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1962         { }
1963 };
1964
1965 static struct hda_verb alc880_lg_ch6_init[] = {
1966         /* set line-in and mic-in to output */
1967         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1968         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1969         { }
1970 };
1971
1972 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1973         { 2, alc880_lg_ch2_init },
1974         { 4, alc880_lg_ch4_init },
1975         { 6, alc880_lg_ch6_init },
1976 };
1977
1978 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1979         /* FIXME: it's not really "master" but front channels */
1980         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1981         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1982         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1983         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1984         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1985         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1986         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1987         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1988         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1989         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1990         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1991         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1992         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1993         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1994         {
1995                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1996                 .name = "Channel Mode",
1997                 .info = alc_ch_mode_info,
1998                 .get = alc_ch_mode_get,
1999                 .put = alc_ch_mode_put,
2000         },
2001         { } /* end */
2002 };
2003
2004 static struct hda_verb alc880_lg_init_verbs[] = {
2005         /* set capture source to mic-in */
2006         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2007         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2008         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2009         /* mute all amp mixer inputs */
2010         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2011         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2012         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2013         /* line-in to input */
2014         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2015         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2016         /* built-in mic */
2017         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2018         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2019         /* speaker-out */
2020         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2021         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2022         /* mic-in to input */
2023         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2024         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2025         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2026         /* HP-out */
2027         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2028         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2029         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2030         /* jack sense */
2031         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2032         { }
2033 };
2034
2035 /* toggle speaker-output according to the hp-jack state */
2036 static void alc880_lg_automute(struct hda_codec *codec)
2037 {
2038         unsigned int present;
2039         unsigned char bits;
2040
2041         present = snd_hda_codec_read(codec, 0x1b, 0,
2042                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2043         bits = present ? HDA_AMP_MUTE : 0;
2044         snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2045                                  HDA_AMP_MUTE, bits);
2046 }
2047
2048 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2049 {
2050         /* Looks like the unsol event is incompatible with the standard
2051          * definition.  4bit tag is placed at 28 bit!
2052          */
2053         if ((res >> 28) == 0x01)
2054                 alc880_lg_automute(codec);
2055 }
2056
2057 /*
2058  * LG LW20
2059  *
2060  * Pin assignment:
2061  *   Speaker-out: 0x14
2062  *   Mic-In: 0x18
2063  *   Built-in Mic-In: 0x19
2064  *   Line-In: 0x1b
2065  *   HP-Out: 0x1a
2066  *   SPDIF-Out: 0x1e
2067  */
2068
2069 static struct hda_input_mux alc880_lg_lw_capture_source = {
2070         .num_items = 3,
2071         .items = {
2072                 { "Mic", 0x0 },
2073                 { "Internal Mic", 0x1 },
2074                 { "Line In", 0x2 },
2075         },
2076 };
2077
2078 #define alc880_lg_lw_modes alc880_threestack_modes
2079
2080 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2081         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2082         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2083         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2084         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2085         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2086         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2087         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2088         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2089         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2090         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2091         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2092         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2093         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2094         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2095         {
2096                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2097                 .name = "Channel Mode",
2098                 .info = alc_ch_mode_info,
2099                 .get = alc_ch_mode_get,
2100                 .put = alc_ch_mode_put,
2101         },
2102         { } /* end */
2103 };
2104
2105 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2106         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2107         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2108         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2109
2110         /* set capture source to mic-in */
2111         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2112         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2113         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2114         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2115         /* speaker-out */
2116         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2117         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2118         /* HP-out */
2119         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2120         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2121         /* mic-in to input */
2122         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2123         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2124         /* built-in mic */
2125         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2126         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2127         /* jack sense */
2128         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2129         { }
2130 };
2131
2132 /* toggle speaker-output according to the hp-jack state */
2133 static void alc880_lg_lw_automute(struct hda_codec *codec)
2134 {
2135         unsigned int present;
2136         unsigned char bits;
2137
2138         present = snd_hda_codec_read(codec, 0x1b, 0,
2139                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2140         bits = present ? HDA_AMP_MUTE : 0;
2141         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2142                                  HDA_AMP_MUTE, bits);
2143 }
2144
2145 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2146 {
2147         /* Looks like the unsol event is incompatible with the standard
2148          * definition.  4bit tag is placed at 28 bit!
2149          */
2150         if ((res >> 28) == 0x01)
2151                 alc880_lg_lw_automute(codec);
2152 }
2153
2154 #ifdef CONFIG_SND_HDA_POWER_SAVE
2155 static struct hda_amp_list alc880_loopbacks[] = {
2156         { 0x0b, HDA_INPUT, 0 },
2157         { 0x0b, HDA_INPUT, 1 },
2158         { 0x0b, HDA_INPUT, 2 },
2159         { 0x0b, HDA_INPUT, 3 },
2160         { 0x0b, HDA_INPUT, 4 },
2161         { } /* end */
2162 };
2163
2164 static struct hda_amp_list alc880_lg_loopbacks[] = {
2165         { 0x0b, HDA_INPUT, 1 },
2166         { 0x0b, HDA_INPUT, 6 },
2167         { 0x0b, HDA_INPUT, 7 },
2168         { } /* end */
2169 };
2170 #endif
2171
2172 /*
2173  * Common callbacks
2174  */
2175
2176 static int alc_init(struct hda_codec *codec)
2177 {
2178         struct alc_spec *spec = codec->spec;
2179         unsigned int i;
2180
2181         for (i = 0; i < spec->num_init_verbs; i++)
2182                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2183
2184         if (spec->init_hook)
2185                 spec->init_hook(codec);
2186
2187         return 0;
2188 }
2189
2190 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2191 {
2192         struct alc_spec *spec = codec->spec;
2193
2194         if (spec->unsol_event)
2195                 spec->unsol_event(codec, res);
2196 }
2197
2198 #ifdef CONFIG_SND_HDA_POWER_SAVE
2199 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2200 {
2201         struct alc_spec *spec = codec->spec;
2202         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2203 }
2204 #endif
2205
2206 /*
2207  * Analog playback callbacks
2208  */
2209 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2210                                     struct hda_codec *codec,
2211                                     struct snd_pcm_substream *substream)
2212 {
2213         struct alc_spec *spec = codec->spec;
2214         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2215 }
2216
2217 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2218                                        struct hda_codec *codec,
2219                                        unsigned int stream_tag,
2220                                        unsigned int format,
2221                                        struct snd_pcm_substream *substream)
2222 {
2223         struct alc_spec *spec = codec->spec;
2224         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2225                                                 stream_tag, format, substream);
2226 }
2227
2228 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2229                                        struct hda_codec *codec,
2230                                        struct snd_pcm_substream *substream)
2231 {
2232         struct alc_spec *spec = codec->spec;
2233         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2234 }
2235
2236 /*
2237  * Digital out
2238  */
2239 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2240                                         struct hda_codec *codec,
2241                                         struct snd_pcm_substream *substream)
2242 {
2243         struct alc_spec *spec = codec->spec;
2244         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2245 }
2246
2247 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2248                                            struct hda_codec *codec,
2249                                            unsigned int stream_tag,
2250                                            unsigned int format,
2251                                            struct snd_pcm_substream *substream)
2252 {
2253         struct alc_spec *spec = codec->spec;
2254         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2255                                              stream_tag, format, substream);
2256 }
2257
2258 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2259                                          struct hda_codec *codec,
2260                                          struct snd_pcm_substream *substream)
2261 {
2262         struct alc_spec *spec = codec->spec;
2263         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2264 }
2265
2266 /*
2267  * Analog capture
2268  */
2269 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2270                                       struct hda_codec *codec,
2271                                       unsigned int stream_tag,
2272                                       unsigned int format,
2273                                       struct snd_pcm_substream *substream)
2274 {
2275         struct alc_spec *spec = codec->spec;
2276
2277         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2278                                    stream_tag, 0, format);
2279         return 0;
2280 }
2281
2282 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2283                                       struct hda_codec *codec,
2284                                       struct snd_pcm_substream *substream)
2285 {
2286         struct alc_spec *spec = codec->spec;
2287
2288         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2289                                    0, 0, 0);
2290         return 0;
2291 }
2292
2293
2294 /*
2295  */
2296 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2297         .substreams = 1,
2298         .channels_min = 2,
2299         .channels_max = 8,
2300         /* NID is set in alc_build_pcms */
2301         .ops = {
2302                 .open = alc880_playback_pcm_open,
2303                 .prepare = alc880_playback_pcm_prepare,
2304                 .cleanup = alc880_playback_pcm_cleanup
2305         },
2306 };
2307
2308 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2309         .substreams = 2,
2310         .channels_min = 2,
2311         .channels_max = 2,
2312         /* NID is set in alc_build_pcms */
2313         .ops = {
2314                 .prepare = alc880_capture_pcm_prepare,
2315                 .cleanup = alc880_capture_pcm_cleanup
2316         },
2317 };
2318
2319 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2320         .substreams = 1,
2321         .channels_min = 2,
2322         .channels_max = 2,
2323         /* NID is set in alc_build_pcms */
2324         .ops = {
2325                 .open = alc880_dig_playback_pcm_open,
2326                 .close = alc880_dig_playback_pcm_close,
2327                 .prepare = alc880_dig_playback_pcm_prepare
2328         },
2329 };
2330
2331 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2332         .substreams = 1,
2333         .channels_min = 2,
2334         .channels_max = 2,
2335         /* NID is set in alc_build_pcms */
2336 };
2337
2338 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2339 static struct hda_pcm_stream alc_pcm_null_playback = {
2340         .substreams = 0,
2341         .channels_min = 0,
2342         .channels_max = 0,
2343 };
2344
2345 static int alc_build_pcms(struct hda_codec *codec)
2346 {
2347         struct alc_spec *spec = codec->spec;
2348         struct hda_pcm *info = spec->pcm_rec;
2349         int i;
2350
2351         codec->num_pcms = 1;
2352         codec->pcm_info = info;
2353
2354         info->name = spec->stream_name_analog;
2355         if (spec->stream_analog_playback) {
2356                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2357                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2358                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2359         }
2360         if (spec->stream_analog_capture) {
2361                 snd_assert(spec->adc_nids, return -EINVAL);
2362                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2363                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2364         }
2365
2366         if (spec->channel_mode) {
2367                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2368                 for (i = 0; i < spec->num_channel_mode; i++) {
2369                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2370                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2371                         }
2372                 }
2373         }
2374
2375         /* SPDIF for stream index #1 */
2376         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2377                 codec->num_pcms = 2;
2378                 info = spec->pcm_rec + 1;
2379                 info->name = spec->stream_name_digital;
2380                 if (spec->multiout.dig_out_nid &&
2381                     spec->stream_digital_playback) {
2382                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2383                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2384                 }
2385                 if (spec->dig_in_nid &&
2386                     spec->stream_digital_capture) {
2387                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2388                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2389                 }
2390         }
2391
2392         /* If the use of more than one ADC is requested for the current
2393          * model, configure a second analog capture-only PCM.
2394          */
2395         /* Additional Analaog capture for index #2 */
2396         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2397             spec->adc_nids) {
2398                 codec->num_pcms = 3;
2399                 info = spec->pcm_rec + 2;
2400                 info->name = spec->stream_name_analog;
2401                 /* No playback stream for second PCM */
2402                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2403                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2404                 if (spec->stream_analog_capture) {
2405                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2406                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2407                 }
2408         }
2409
2410         return 0;
2411 }
2412
2413 static void alc_free(struct hda_codec *codec)
2414 {
2415         struct alc_spec *spec = codec->spec;
2416         unsigned int i;
2417
2418         if (!spec)
2419                 return;
2420
2421         if (spec->kctl_alloc) {
2422                 for (i = 0; i < spec->num_kctl_used; i++)
2423                         kfree(spec->kctl_alloc[i].name);
2424                 kfree(spec->kctl_alloc);
2425         }
2426         kfree(spec);
2427 }
2428
2429 /*
2430  */
2431 static struct hda_codec_ops alc_patch_ops = {
2432         .build_controls = alc_build_controls,
2433         .build_pcms = alc_build_pcms,
2434         .init = alc_init,
2435         .free = alc_free,
2436         .unsol_event = alc_unsol_event,
2437 #ifdef CONFIG_SND_HDA_POWER_SAVE
2438         .check_power_status = alc_check_power_status,
2439 #endif
2440 };
2441
2442
2443 /*
2444  * Test configuration for debugging
2445  *
2446  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2447  * enum controls.
2448  */
2449 #ifdef CONFIG_SND_DEBUG
2450 static hda_nid_t alc880_test_dac_nids[4] = {
2451         0x02, 0x03, 0x04, 0x05
2452 };
2453
2454 static struct hda_input_mux alc880_test_capture_source = {
2455         .num_items = 7,
2456         .items = {
2457                 { "In-1", 0x0 },
2458                 { "In-2", 0x1 },
2459                 { "In-3", 0x2 },
2460                 { "In-4", 0x3 },
2461                 { "CD", 0x4 },
2462                 { "Front", 0x5 },
2463                 { "Surround", 0x6 },
2464         },
2465 };
2466
2467 static struct hda_channel_mode alc880_test_modes[4] = {
2468         { 2, NULL },
2469         { 4, NULL },
2470         { 6, NULL },
2471         { 8, NULL },
2472 };
2473
2474 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2475                                  struct snd_ctl_elem_info *uinfo)
2476 {
2477         static char *texts[] = {
2478                 "N/A", "Line Out", "HP Out",
2479                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2480         };
2481         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2482         uinfo->count = 1;
2483         uinfo->value.enumerated.items = 8;
2484         if (uinfo->value.enumerated.item >= 8)
2485                 uinfo->value.enumerated.item = 7;
2486         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2487         return 0;
2488 }
2489
2490 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2491                                 struct snd_ctl_elem_value *ucontrol)
2492 {
2493         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2494         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2495         unsigned int pin_ctl, item = 0;
2496
2497         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2498                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2499         if (pin_ctl & AC_PINCTL_OUT_EN) {
2500                 if (pin_ctl & AC_PINCTL_HP_EN)
2501                         item = 2;
2502                 else
2503                         item = 1;
2504         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2505                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2506                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2507                 case AC_PINCTL_VREF_50:  item = 4; break;
2508                 case AC_PINCTL_VREF_GRD: item = 5; break;
2509                 case AC_PINCTL_VREF_80:  item = 6; break;
2510                 case AC_PINCTL_VREF_100: item = 7; break;
2511                 }
2512         }
2513         ucontrol->value.enumerated.item[0] = item;
2514         return 0;
2515 }
2516
2517 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2518                                 struct snd_ctl_elem_value *ucontrol)
2519 {
2520         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2521         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2522         static unsigned int ctls[] = {
2523                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2524                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2525                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2526                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2527                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2528                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2529         };
2530         unsigned int old_ctl, new_ctl;
2531
2532         old_ctl = snd_hda_codec_read(codec, nid, 0,
2533                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2534         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2535         if (old_ctl != new_ctl) {
2536                 int val;
2537                 snd_hda_codec_write_cache(codec, nid, 0,
2538                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
2539                                           new_ctl);
2540                 val = ucontrol->value.enumerated.item[0] >= 3 ?
2541                         HDA_AMP_MUTE : 0;
2542                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2543                                          HDA_AMP_MUTE, val);
2544                 return 1;
2545         }
2546         return 0;
2547 }
2548
2549 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2550                                  struct snd_ctl_elem_info *uinfo)
2551 {
2552         static char *texts[] = {
2553                 "Front", "Surround", "CLFE", "Side"
2554         };
2555         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2556         uinfo->count = 1;
2557         uinfo->value.enumerated.items = 4;
2558         if (uinfo->value.enumerated.item >= 4)
2559                 uinfo->value.enumerated.item = 3;
2560         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2561         return 0;
2562 }
2563
2564 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2565                                 struct snd_ctl_elem_value *ucontrol)
2566 {
2567         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2568         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2569         unsigned int sel;
2570
2571         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2572         ucontrol->value.enumerated.item[0] = sel & 3;
2573         return 0;
2574 }
2575
2576 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2577                                 struct snd_ctl_elem_value *ucontrol)
2578 {
2579         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2580         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2581         unsigned int sel;
2582
2583         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2584         if (ucontrol->value.enumerated.item[0] != sel) {
2585                 sel = ucontrol->value.enumerated.item[0] & 3;
2586                 snd_hda_codec_write_cache(codec, nid, 0,
2587                                           AC_VERB_SET_CONNECT_SEL, sel);
2588                 return 1;
2589         }
2590         return 0;
2591 }
2592
2593 #define PIN_CTL_TEST(xname,nid) {                       \
2594                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2595                         .name = xname,                 \
2596                         .info = alc_test_pin_ctl_info, \
2597                         .get = alc_test_pin_ctl_get,   \
2598                         .put = alc_test_pin_ctl_put,   \
2599                         .private_value = nid           \
2600                         }
2601
2602 #define PIN_SRC_TEST(xname,nid) {                       \
2603                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2604                         .name = xname,                 \
2605                         .info = alc_test_pin_src_info, \
2606                         .get = alc_test_pin_src_get,   \
2607                         .put = alc_test_pin_src_put,   \
2608                         .private_value = nid           \
2609                         }
2610
2611 static struct snd_kcontrol_new alc880_test_mixer[] = {
2612         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2613         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2614         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2615         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2616         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2617         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2618         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2619         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2620         PIN_CTL_TEST("Front Pin Mode", 0x14),
2621         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2622         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2623         PIN_CTL_TEST("Side Pin Mode", 0x17),
2624         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2625         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2626         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2627         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2628         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2629         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2630         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2631         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2632         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2633         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2634         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2635         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2636         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2637         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2638         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2639         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2640         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2641         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2642         {
2643                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2644                 .name = "Channel Mode",
2645                 .info = alc_ch_mode_info,
2646                 .get = alc_ch_mode_get,
2647                 .put = alc_ch_mode_put,
2648         },
2649         { } /* end */
2650 };
2651
2652 static struct hda_verb alc880_test_init_verbs[] = {
2653         /* Unmute inputs of 0x0c - 0x0f */
2654         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2655         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2656         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2657         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2658         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2659         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2660         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2661         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2662         /* Vol output for 0x0c-0x0f */
2663         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2664         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2665         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2666         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2667         /* Set output pins 0x14-0x17 */
2668         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2669         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2670         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2671         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2672         /* Unmute output pins 0x14-0x17 */
2673         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2674         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2675         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2676         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2677         /* Set input pins 0x18-0x1c */
2678         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2679         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2680         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2681         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2682         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2683         /* Mute input pins 0x18-0x1b */
2684         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2685         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2686         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2687         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2688         /* ADC set up */
2689         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2690         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2691         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2692         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2693         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2694         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2695         /* Analog input/passthru */
2696         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2697         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2698         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2699         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2700         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2701         { }
2702 };
2703 #endif
2704
2705 /*
2706  */
2707
2708 static const char *alc880_models[ALC880_MODEL_LAST] = {
2709         [ALC880_3ST]            = "3stack",
2710         [ALC880_TCL_S700]       = "tcl",
2711         [ALC880_3ST_DIG]        = "3stack-digout",
2712         [ALC880_CLEVO]          = "clevo",
2713         [ALC880_5ST]            = "5stack",
2714         [ALC880_5ST_DIG]        = "5stack-digout",
2715         [ALC880_W810]           = "w810",
2716         [ALC880_Z71V]           = "z71v",
2717         [ALC880_6ST]            = "6stack",
2718         [ALC880_6ST_DIG]        = "6stack-digout",
2719         [ALC880_ASUS]           = "asus",
2720         [ALC880_ASUS_W1V]       = "asus-w1v",
2721         [ALC880_ASUS_DIG]       = "asus-dig",
2722         [ALC880_ASUS_DIG2]      = "asus-dig2",
2723         [ALC880_UNIWILL_DIG]    = "uniwill",
2724         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2725         [ALC880_FUJITSU]        = "fujitsu",
2726         [ALC880_F1734]          = "F1734",
2727         [ALC880_LG]             = "lg",
2728         [ALC880_LG_LW]          = "lg-lw",
2729 #ifdef CONFIG_SND_DEBUG
2730         [ALC880_TEST]           = "test",
2731 #endif
2732         [ALC880_AUTO]           = "auto",
2733 };
2734
2735 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2736         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2737         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2738         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2739         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2740         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2741         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2742         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2743         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2744         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2745         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2746         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2747         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2748         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2749         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2750         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2751         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2752         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2753         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2754         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2755         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2756         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2757         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2758         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2759         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2760         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2761         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
2762         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2763         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2764         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2765         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2766         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2767         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2768         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2769         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2770         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2771         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2772         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2773         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2774         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2775         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2776         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2777         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2778         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2779         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2780         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2781         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2782         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2783         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2784         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2785         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2786         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2787         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2788         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2789         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2790         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2791         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2792         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2793         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2794         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2795         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2796         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2797         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2798         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2799         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2800         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2801         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2802         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2803         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2804         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2805         {}
2806 };
2807
2808 /*
2809  * ALC880 codec presets
2810  */
2811 static struct alc_config_preset alc880_presets[] = {
2812         [ALC880_3ST] = {
2813                 .mixers = { alc880_three_stack_mixer },
2814                 .init_verbs = { alc880_volume_init_verbs,
2815                                 alc880_pin_3stack_init_verbs },
2816                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2817                 .dac_nids = alc880_dac_nids,
2818                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2819                 .channel_mode = alc880_threestack_modes,
2820                 .need_dac_fix = 1,
2821                 .input_mux = &alc880_capture_source,
2822         },
2823         [ALC880_3ST_DIG] = {
2824                 .mixers = { alc880_three_stack_mixer },
2825                 .init_verbs = { alc880_volume_init_verbs,
2826                                 alc880_pin_3stack_init_verbs },
2827                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2828                 .dac_nids = alc880_dac_nids,
2829                 .dig_out_nid = ALC880_DIGOUT_NID,
2830                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2831                 .channel_mode = alc880_threestack_modes,
2832                 .need_dac_fix = 1,
2833                 .input_mux = &alc880_capture_source,
2834         },
2835         [ALC880_TCL_S700] = {
2836                 .mixers = { alc880_tcl_s700_mixer },
2837                 .init_verbs = { alc880_volume_init_verbs,
2838                                 alc880_pin_tcl_S700_init_verbs,
2839                                 alc880_gpio2_init_verbs },
2840                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2841                 .dac_nids = alc880_dac_nids,
2842                 .hp_nid = 0x03,
2843                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2844                 .channel_mode = alc880_2_jack_modes,
2845                 .input_mux = &alc880_capture_source,
2846         },
2847         [ALC880_5ST] = {
2848                 .mixers = { alc880_three_stack_mixer,
2849                             alc880_five_stack_mixer},
2850                 .init_verbs = { alc880_volume_init_verbs,
2851                                 alc880_pin_5stack_init_verbs },
2852                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2853                 .dac_nids = alc880_dac_nids,
2854                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2855                 .channel_mode = alc880_fivestack_modes,
2856                 .input_mux = &alc880_capture_source,
2857         },
2858         [ALC880_5ST_DIG] = {
2859                 .mixers = { alc880_three_stack_mixer,
2860                             alc880_five_stack_mixer },
2861                 .init_verbs = { alc880_volume_init_verbs,
2862                                 alc880_pin_5stack_init_verbs },
2863                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2864                 .dac_nids = alc880_dac_nids,
2865                 .dig_out_nid = ALC880_DIGOUT_NID,
2866                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2867                 .channel_mode = alc880_fivestack_modes,
2868                 .input_mux = &alc880_capture_source,
2869         },
2870         [ALC880_6ST] = {
2871                 .mixers = { alc880_six_stack_mixer },
2872                 .init_verbs = { alc880_volume_init_verbs,
2873                                 alc880_pin_6stack_init_verbs },
2874                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2875                 .dac_nids = alc880_6st_dac_nids,
2876                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2877                 .channel_mode = alc880_sixstack_modes,
2878                 .input_mux = &alc880_6stack_capture_source,
2879         },
2880         [ALC880_6ST_DIG] = {
2881                 .mixers = { alc880_six_stack_mixer },
2882                 .init_verbs = { alc880_volume_init_verbs,
2883                                 alc880_pin_6stack_init_verbs },
2884                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2885                 .dac_nids = alc880_6st_dac_nids,
2886                 .dig_out_nid = ALC880_DIGOUT_NID,
2887                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2888                 .channel_mode = alc880_sixstack_modes,
2889                 .input_mux = &alc880_6stack_capture_source,
2890         },
2891         [ALC880_W810] = {
2892                 .mixers = { alc880_w810_base_mixer },
2893                 .init_verbs = { alc880_volume_init_verbs,
2894                                 alc880_pin_w810_init_verbs,
2895                                 alc880_gpio2_init_verbs },
2896                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2897                 .dac_nids = alc880_w810_dac_nids,
2898                 .dig_out_nid = ALC880_DIGOUT_NID,
2899                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2900                 .channel_mode = alc880_w810_modes,
2901                 .input_mux = &alc880_capture_source,
2902         },
2903         [ALC880_Z71V] = {
2904                 .mixers = { alc880_z71v_mixer },
2905                 .init_verbs = { alc880_volume_init_verbs,
2906                                 alc880_pin_z71v_init_verbs },
2907                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2908                 .dac_nids = alc880_z71v_dac_nids,
2909                 .dig_out_nid = ALC880_DIGOUT_NID,
2910                 .hp_nid = 0x03,
2911                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2912                 .channel_mode = alc880_2_jack_modes,
2913                 .input_mux = &alc880_capture_source,
2914         },
2915         [ALC880_F1734] = {
2916                 .mixers = { alc880_f1734_mixer },
2917                 .init_verbs = { alc880_volume_init_verbs,
2918                                 alc880_pin_f1734_init_verbs },
2919                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2920                 .dac_nids = alc880_f1734_dac_nids,
2921                 .hp_nid = 0x02,
2922                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2923                 .channel_mode = alc880_2_jack_modes,
2924                 .input_mux = &alc880_capture_source,
2925         },
2926         [ALC880_ASUS] = {
2927                 .mixers = { alc880_asus_mixer },
2928                 .init_verbs = { alc880_volume_init_verbs,
2929                                 alc880_pin_asus_init_verbs,
2930                                 alc880_gpio1_init_verbs },
2931                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2932                 .dac_nids = alc880_asus_dac_nids,
2933                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2934                 .channel_mode = alc880_asus_modes,
2935                 .need_dac_fix = 1,
2936                 .input_mux = &alc880_capture_source,
2937         },
2938         [ALC880_ASUS_DIG] = {
2939                 .mixers = { alc880_asus_mixer },
2940                 .init_verbs = { alc880_volume_init_verbs,
2941                                 alc880_pin_asus_init_verbs,
2942                                 alc880_gpio1_init_verbs },
2943                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2944                 .dac_nids = alc880_asus_dac_nids,
2945                 .dig_out_nid = ALC880_DIGOUT_NID,
2946                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2947                 .channel_mode = alc880_asus_modes,
2948                 .need_dac_fix = 1,
2949                 .input_mux = &alc880_capture_source,
2950         },
2951         [ALC880_ASUS_DIG2] = {
2952                 .mixers = { alc880_asus_mixer },
2953                 .init_verbs = { alc880_volume_init_verbs,
2954                                 alc880_pin_asus_init_verbs,
2955                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2956                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2957                 .dac_nids = alc880_asus_dac_nids,
2958                 .dig_out_nid = ALC880_DIGOUT_NID,
2959                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2960                 .channel_mode = alc880_asus_modes,
2961                 .need_dac_fix = 1,
2962                 .input_mux = &alc880_capture_source,
2963         },
2964         [ALC880_ASUS_W1V] = {
2965                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2966                 .init_verbs = { alc880_volume_init_verbs,
2967                                 alc880_pin_asus_init_verbs,
2968                                 alc880_gpio1_init_verbs },
2969                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2970                 .dac_nids = alc880_asus_dac_nids,
2971                 .dig_out_nid = ALC880_DIGOUT_NID,
2972                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2973                 .channel_mode = alc880_asus_modes,
2974                 .need_dac_fix = 1,
2975                 .input_mux = &alc880_capture_source,
2976         },
2977         [ALC880_UNIWILL_DIG] = {
2978                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2979                 .init_verbs = { alc880_volume_init_verbs,
2980                                 alc880_pin_asus_init_verbs },
2981                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2982                 .dac_nids = alc880_asus_dac_nids,
2983                 .dig_out_nid = ALC880_DIGOUT_NID,
2984                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2985                 .channel_mode = alc880_asus_modes,
2986                 .need_dac_fix = 1,
2987                 .input_mux = &alc880_capture_source,
2988         },
2989         [ALC880_UNIWILL] = {
2990                 .mixers = { alc880_uniwill_mixer },
2991                 .init_verbs = { alc880_volume_init_verbs,
2992                                 alc880_uniwill_init_verbs },
2993                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2994                 .dac_nids = alc880_asus_dac_nids,
2995                 .dig_out_nid = ALC880_DIGOUT_NID,
2996                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2997                 .channel_mode = alc880_threestack_modes,
2998                 .need_dac_fix = 1,
2999                 .input_mux = &alc880_capture_source,
3000                 .unsol_event = alc880_uniwill_unsol_event,
3001                 .init_hook = alc880_uniwill_automute,
3002         },
3003         [ALC880_UNIWILL_P53] = {
3004                 .mixers = { alc880_uniwill_p53_mixer },
3005                 .init_verbs = { alc880_volume_init_verbs,
3006                                 alc880_uniwill_p53_init_verbs },
3007                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3008                 .dac_nids = alc880_asus_dac_nids,
3009                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3010                 .channel_mode = alc880_threestack_modes,
3011                 .input_mux = &alc880_capture_source,
3012                 .unsol_event = alc880_uniwill_p53_unsol_event,
3013                 .init_hook = alc880_uniwill_p53_hp_automute,
3014         },
3015         [ALC880_FUJITSU] = {
3016                 .mixers = { alc880_fujitsu_mixer,
3017                             alc880_pcbeep_mixer, },
3018                 .init_verbs = { alc880_volume_init_verbs,
3019                                 alc880_uniwill_p53_init_verbs,
3020                                 alc880_beep_init_verbs },
3021                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3022                 .dac_nids = alc880_dac_nids,
3023                 .dig_out_nid = ALC880_DIGOUT_NID,
3024                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3025                 .channel_mode = alc880_2_jack_modes,
3026                 .input_mux = &alc880_capture_source,
3027                 .unsol_event = alc880_uniwill_p53_unsol_event,
3028                 .init_hook = alc880_uniwill_p53_hp_automute,
3029         },
3030         [ALC880_CLEVO] = {
3031                 .mixers = { alc880_three_stack_mixer },
3032                 .init_verbs = { alc880_volume_init_verbs,
3033                                 alc880_pin_clevo_init_verbs },
3034                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3035                 .dac_nids = alc880_dac_nids,
3036                 .hp_nid = 0x03,
3037                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3038                 .channel_mode = alc880_threestack_modes,
3039                 .need_dac_fix = 1,
3040                 .input_mux = &alc880_capture_source,
3041         },
3042         [ALC880_LG] = {
3043                 .mixers = { alc880_lg_mixer },
3044                 .init_verbs = { alc880_volume_init_verbs,
3045                                 alc880_lg_init_verbs },
3046                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3047                 .dac_nids = alc880_lg_dac_nids,
3048                 .dig_out_nid = ALC880_DIGOUT_NID,
3049                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3050                 .channel_mode = alc880_lg_ch_modes,
3051                 .need_dac_fix = 1,
3052                 .input_mux = &alc880_lg_capture_source,
3053                 .unsol_event = alc880_lg_unsol_event,
3054                 .init_hook = alc880_lg_automute,
3055 #ifdef CONFIG_SND_HDA_POWER_SAVE
3056                 .loopbacks = alc880_lg_loopbacks,
3057 #endif
3058         },
3059         [ALC880_LG_LW] = {
3060                 .mixers = { alc880_lg_lw_mixer },
3061                 .init_verbs = { alc880_volume_init_verbs,
3062                                 alc880_lg_lw_init_verbs },
3063                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3064                 .dac_nids = alc880_dac_nids,
3065                 .dig_out_nid = ALC880_DIGOUT_NID,
3066                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3067                 .channel_mode = alc880_lg_lw_modes,
3068                 .input_mux = &alc880_lg_lw_capture_source,
3069                 .unsol_event = alc880_lg_lw_unsol_event,
3070                 .init_hook = alc880_lg_lw_automute,
3071         },
3072 #ifdef CONFIG_SND_DEBUG
3073         [ALC880_TEST] = {
3074                 .mixers = { alc880_test_mixer },
3075                 .init_verbs = { alc880_test_init_verbs },
3076                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3077                 .dac_nids = alc880_test_dac_nids,
3078                 .dig_out_nid = ALC880_DIGOUT_NID,
3079                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3080                 .channel_mode = alc880_test_modes,
3081                 .input_mux = &alc880_test_capture_source,
3082         },
3083 #endif
3084 };
3085
3086 /*
3087  * Automatic parse of I/O pins from the BIOS configuration
3088  */
3089
3090 #define NUM_CONTROL_ALLOC       32
3091 #define NUM_VERB_ALLOC          32
3092
3093 enum {
3094         ALC_CTL_WIDGET_VOL,
3095         ALC_CTL_WIDGET_MUTE,
3096         ALC_CTL_BIND_MUTE,
3097 };
3098 static struct snd_kcontrol_new alc880_control_templates[] = {
3099         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3100         HDA_CODEC_MUTE(NULL, 0, 0, 0),
3101         HDA_BIND_MUTE(NULL, 0, 0, 0),
3102 };
3103
3104 /* add dynamic controls */
3105 static int add_control(struct alc_spec *spec, int type, const char *name,
3106                        unsigned long val)
3107 {
3108         struct snd_kcontrol_new *knew;
3109
3110         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3111                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3112
3113                 /* array + terminator */
3114                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3115                 if (!knew)
3116                         return -ENOMEM;
3117                 if (spec->kctl_alloc) {
3118                         memcpy(knew, spec->kctl_alloc,
3119                                sizeof(*knew) * spec->num_kctl_alloc);
3120                         kfree(spec->kctl_alloc);
3121                 }
3122                 spec->kctl_alloc = knew;
3123                 spec->num_kctl_alloc = num;
3124         }
3125
3126         knew = &spec->kctl_alloc[spec->num_kctl_used];
3127         *knew = alc880_control_templates[type];
3128         knew->name = kstrdup(name, GFP_KERNEL);
3129         if (!knew->name)
3130                 return -ENOMEM;
3131         knew->private_value = val;
3132         spec->num_kctl_used++;
3133         return 0;
3134 }
3135
3136 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
3137 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
3138 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
3139 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
3140 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
3141 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
3142 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
3143 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
3144 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
3145 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
3146 #define ALC880_PIN_CD_NID               0x1c
3147
3148 /* fill in the dac_nids table from the parsed pin configuration */
3149 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3150                                      const struct auto_pin_cfg *cfg)
3151 {
3152         hda_nid_t nid;
3153         int assigned[4];
3154         int i, j;
3155
3156         memset(assigned, 0, sizeof(assigned));
3157         spec->multiout.dac_nids = spec->private_dac_nids;
3158
3159         /* check the pins hardwired to audio widget */
3160         for (i = 0; i < cfg->line_outs; i++) {
3161                 nid = cfg->line_out_pins[i];
3162                 if (alc880_is_fixed_pin(nid)) {
3163                         int idx = alc880_fixed_pin_idx(nid);
3164                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3165                         assigned[idx] = 1;
3166                 }
3167         }
3168         /* left pins can be connect to any audio widget */
3169         for (i = 0; i < cfg->line_outs; i++) {
3170                 nid = cfg->line_out_pins[i];
3171                 if (alc880_is_fixed_pin(nid))
3172                         continue;
3173                 /* search for an empty channel */
3174                 for (j = 0; j < cfg->line_outs; j++) {
3175                         if (!assigned[j]) {
3176                                 spec->multiout.dac_nids[i] =
3177                                         alc880_idx_to_dac(j);
3178                                 assigned[j] = 1;
3179                                 break;
3180                         }
3181                 }
3182         }
3183         spec->multiout.num_dacs = cfg->line_outs;
3184         return 0;
3185 }
3186
3187 /* add playback controls from the parsed DAC table */
3188 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3189                                              const struct auto_pin_cfg *cfg)
3190 {
3191         char name[32];
3192         static const char *chname[4] = {
3193                 "Front", "Surround", NULL /*CLFE*/, "Side"
3194         };
3195         hda_nid_t nid;
3196         int i, err;
3197
3198         for (i = 0; i < cfg->line_outs; i++) {
3199                 if (!spec->multiout.dac_nids[i])
3200                         continue;
3201                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3202                 if (i == 2) {
3203                         /* Center/LFE */
3204                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3205                                           "Center Playback Volume",
3206                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3207                                                               HDA_OUTPUT));
3208                         if (err < 0)
3209                                 return err;
3210                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3211                                           "LFE Playback Volume",
3212                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3213                                                               HDA_OUTPUT));
3214                         if (err < 0)
3215                                 return err;
3216                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3217                                           "Center Playback Switch",
3218                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3219                                                               HDA_INPUT));
3220                         if (err < 0)
3221                                 return err;
3222                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3223                                           "LFE Playback Switch",
3224                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3225                                                               HDA_INPUT));
3226                         if (err < 0)
3227                                 return err;
3228                 } else {
3229                         sprintf(name, "%s Playback Volume", chname[i]);
3230                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3231                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3232                                                               HDA_OUTPUT));
3233                         if (err < 0)
3234                                 return err;
3235                         sprintf(name, "%s Playback Switch", chname[i]);
3236                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3237                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3238                                                               HDA_INPUT));
3239                         if (err < 0)
3240                                 return err;
3241                 }
3242         }
3243         return 0;
3244 }
3245
3246 /* add playback controls for speaker and HP outputs */
3247 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3248                                         const char *pfx)
3249 {
3250         hda_nid_t nid;
3251         int err;
3252         char name[32];
3253
3254         if (!pin)
3255                 return 0;
3256
3257         if (alc880_is_fixed_pin(pin)) {
3258                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3259                 /* specify the DAC as the extra output */
3260                 if (!spec->multiout.hp_nid)
3261                         spec->multiout.hp_nid = nid;
3262                 else
3263                         spec->multiout.extra_out_nid[0] = nid;
3264                 /* control HP volume/switch on the output mixer amp */
3265                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3266                 sprintf(name, "%s Playback Volume", pfx);
3267                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3268                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3269                 if (err < 0)
3270                         return err;
3271                 sprintf(name, "%s Playback Switch", pfx);
3272                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3273                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3274                 if (err < 0)
3275                         return err;
3276         } else if (alc880_is_multi_pin(pin)) {
3277                 /* set manual connection */
3278                 /* we have only a switch on HP-out PIN */
3279                 sprintf(name, "%s Playback Switch", pfx);
3280                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3281                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3282                 if (err < 0)
3283                         return err;
3284         }
3285         return 0;
3286 }
3287
3288 /* create input playback/capture controls for the given pin */
3289 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3290                             const char *ctlname,
3291                             int idx, hda_nid_t mix_nid)
3292 {
3293         char name[32];
3294         int err;
3295
3296         sprintf(name, "%s Playback Volume", ctlname);
3297         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3298                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3299         if (err < 0)
3300                 return err;
3301         sprintf(name, "%s Playback Switch", ctlname);
3302         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3303                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3304         if (err < 0)
3305                 return err;
3306         return 0;
3307 }
3308
3309 /* create playback/capture controls for input pins */
3310 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3311                                                 const struct auto_pin_cfg *cfg)
3312 {
3313         struct hda_input_mux *imux = &spec->private_imux;
3314         int i, err, idx;
3315
3316         for (i = 0; i < AUTO_PIN_LAST; i++) {
3317                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3318                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3319                         err = new_analog_input(spec, cfg->input_pins[i],
3320                                                auto_pin_cfg_labels[i],
3321                                                idx, 0x0b);
3322                         if (err < 0)
3323                                 return err;
3324                         imux->items[imux->num_items].label =
3325                                 auto_pin_cfg_labels[i];
3326                         imux->items[imux->num_items].index =
3327                                 alc880_input_pin_idx(cfg->input_pins[i]);
3328                         imux->num_items++;
3329                 }
3330         }
3331         return 0;
3332 }
3333
3334 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3335                                               hda_nid_t nid, int pin_type,
3336                                               int dac_idx)
3337 {
3338         /* set as output */
3339         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3340                             pin_type);
3341         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3342                             AMP_OUT_UNMUTE);
3343         /* need the manual connection? */
3344         if (alc880_is_multi_pin(nid)) {
3345                 struct alc_spec *spec = codec->spec;
3346                 int idx = alc880_multi_pin_idx(nid);
3347                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3348                                     AC_VERB_SET_CONNECT_SEL,
3349                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3350         }
3351 }
3352
3353 static int get_pin_type(int line_out_type)
3354 {
3355         if (line_out_type == AUTO_PIN_HP_OUT)
3356                 return PIN_HP;
3357         else
3358                 return PIN_OUT;
3359 }
3360
3361 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3362 {
3363         struct alc_spec *spec = codec->spec;
3364         int i;
3365         
3366         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3367         for (i = 0; i < spec->autocfg.line_outs; i++) {
3368                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3369                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3370                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3371         }
3372 }
3373
3374 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3375 {
3376         struct alc_spec *spec = codec->spec;
3377         hda_nid_t pin;
3378
3379         pin = spec->autocfg.speaker_pins[0];
3380         if (pin) /* connect to front */
3381                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3382         pin = spec->autocfg.hp_pins[0];
3383         if (pin) /* connect to front */
3384                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3385 }
3386
3387 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3388 {
3389         struct alc_spec *spec = codec->spec;
3390         int i;
3391
3392         for (i = 0; i < AUTO_PIN_LAST; i++) {
3393                 hda_nid_t nid = spec->autocfg.input_pins[i];
3394                 if (alc880_is_input_pin(nid)) {
3395                         snd_hda_codec_write(codec, nid, 0,
3396                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3397                                             i <= AUTO_PIN_FRONT_MIC ?
3398                                             PIN_VREF80 : PIN_IN);
3399                         if (nid != ALC880_PIN_CD_NID)
3400                                 snd_hda_codec_write(codec, nid, 0,
3401                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3402                                                     AMP_OUT_MUTE);
3403                 }
3404         }
3405 }
3406
3407 /* parse the BIOS configuration and set up the alc_spec */
3408 /* return 1 if successful, 0 if the proper config is not found,
3409  * or a negative error code
3410  */
3411 static int alc880_parse_auto_config(struct hda_codec *codec)
3412 {
3413         struct alc_spec *spec = codec->spec;
3414         int err;
3415         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3416
3417         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3418                                            alc880_ignore);
3419         if (err < 0)
3420                 return err;
3421         if (!spec->autocfg.line_outs)
3422                 return 0; /* can't find valid BIOS pin config */
3423
3424         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3425         if (err < 0)
3426                 return err;
3427         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3428         if (err < 0)
3429                 return err;
3430         err = alc880_auto_create_extra_out(spec,
3431                                            spec->autocfg.speaker_pins[0],
3432                                            "Speaker");
3433         if (err < 0)
3434                 return err;
3435         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3436                                            "Headphone");
3437         if (err < 0)
3438                 return err;
3439         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3440         if (err < 0)
3441                 return err;
3442
3443         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3444
3445         if (spec->autocfg.dig_out_pin)
3446                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3447         if (spec->autocfg.dig_in_pin)
3448                 spec->dig_in_nid = ALC880_DIGIN_NID;
3449
3450         if (spec->kctl_alloc)
3451                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3452
3453         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3454
3455         spec->num_mux_defs = 1;
3456         spec->input_mux = &spec->private_imux;
3457
3458         return 1;
3459 }
3460
3461 /* additional initialization for auto-configuration model */
3462 static void alc880_auto_init(struct hda_codec *codec)
3463 {
3464         alc880_auto_init_multi_out(codec);
3465         alc880_auto_init_extra_out(codec);
3466         alc880_auto_init_analog_input(codec);
3467 }
3468
3469 /*
3470  * OK, here we have finally the patch for ALC880
3471  */
3472
3473 static int patch_alc880(struct hda_codec *codec)
3474 {
3475         struct alc_spec *spec;
3476         int board_config;
3477         int err;
3478
3479         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3480         if (spec == NULL)
3481                 return -ENOMEM;
3482
3483         codec->spec = spec;
3484
3485         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3486                                                   alc880_models,
3487                                                   alc880_cfg_tbl);
3488         if (board_config < 0) {
3489                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3490                        "trying auto-probe from BIOS...\n");
3491                 board_config = ALC880_AUTO;
3492         }
3493
3494         if (board_config == ALC880_AUTO) {
3495                 /* automatic parse from the BIOS config */
3496                 err = alc880_parse_auto_config(codec);
3497                 if (err < 0) {
3498                         alc_free(codec);
3499                         return err;
3500                 } else if (!err) {
3501                         printk(KERN_INFO
3502                                "hda_codec: Cannot set up configuration "
3503                                "from BIOS.  Using 3-stack mode...\n");
3504                         board_config = ALC880_3ST;
3505                 }
3506         }
3507
3508         if (board_config != ALC880_AUTO)
3509                 setup_preset(spec, &alc880_presets[board_config]);
3510
3511         spec->stream_name_analog = "ALC880 Analog";
3512         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3513         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3514
3515         spec->stream_name_digital = "ALC880 Digital";
3516         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3517         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3518
3519         if (!spec->adc_nids && spec->input_mux) {
3520                 /* check whether NID 0x07 is valid */
3521                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3522                 /* get type */
3523                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3524                 if (wcap != AC_WID_AUD_IN) {
3525                         spec->adc_nids = alc880_adc_nids_alt;
3526                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3527                         spec->mixers[spec->num_mixers] =
3528                                 alc880_capture_alt_mixer;
3529                         spec->num_mixers++;
3530                 } else {
3531                         spec->adc_nids = alc880_adc_nids;
3532                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3533                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3534                         spec->num_mixers++;
3535                 }
3536         }
3537
3538         codec->patch_ops = alc_patch_ops;
3539         if (board_config == ALC880_AUTO)
3540                 spec->init_hook = alc880_auto_init;
3541 #ifdef CONFIG_SND_HDA_POWER_SAVE
3542         if (!spec->loopback.amplist)
3543                 spec->loopback.amplist = alc880_loopbacks;
3544 #endif
3545
3546         return 0;
3547 }
3548
3549
3550 /*
3551  * ALC260 support
3552  */
3553
3554 static hda_nid_t alc260_dac_nids[1] = {
3555         /* front */
3556         0x02,
3557 };
3558
3559 static hda_nid_t alc260_adc_nids[1] = {
3560         /* ADC0 */
3561         0x04,
3562 };
3563
3564 static hda_nid_t alc260_adc_nids_alt[1] = {
3565         /* ADC1 */
3566         0x05,
3567 };
3568
3569 static hda_nid_t alc260_hp_adc_nids[2] = {
3570         /* ADC1, 0 */
3571         0x05, 0x04
3572 };
3573
3574 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3575  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3576  */
3577 static hda_nid_t alc260_dual_adc_nids[2] = {
3578         /* ADC0, ADC1 */
3579         0x04, 0x05
3580 };
3581
3582 #define ALC260_DIGOUT_NID       0x03
3583 #define ALC260_DIGIN_NID        0x06
3584
3585 static struct hda_input_mux alc260_capture_source = {
3586         .num_items = 4,
3587         .items = {
3588                 { "Mic", 0x0 },
3589                 { "Front Mic", 0x1 },
3590                 { "Line", 0x2 },
3591                 { "CD", 0x4 },
3592         },
3593 };
3594
3595 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3596  * headphone jack and the internal CD lines since these are the only pins at
3597  * which audio can appear.  For flexibility, also allow the option of
3598  * recording the mixer output on the second ADC (ADC0 doesn't have a
3599  * connection to the mixer output).
3600  */
3601 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3602         {
3603                 .num_items = 3,
3604                 .items = {
3605                         { "Mic/Line", 0x0 },
3606                         { "CD", 0x4 },
3607                         { "Headphone", 0x2 },
3608                 },
3609         },
3610         {
3611                 .num_items = 4,
3612                 .items = {
3613                         { "Mic/Line", 0x0 },
3614                         { "CD", 0x4 },
3615                         { "Headphone", 0x2 },
3616                         { "Mixer", 0x5 },
3617                 },
3618         },
3619
3620 };
3621
3622 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3623  * the Fujitsu S702x, but jacks are marked differently.
3624  */
3625 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3626         {
3627                 .num_items = 4,
3628                 .items = {
3629                         { "Mic", 0x0 },
3630                         { "Line", 0x2 },
3631                         { "CD", 0x4 },
3632                         { "Headphone", 0x5 },
3633                 },
3634         },
3635         {
3636                 .num_items = 5,
3637                 .items = {
3638                         { "Mic", 0x0 },
3639                         { "Line", 0x2 },
3640                         { "CD", 0x4 },
3641                         { "Headphone", 0x6 },
3642                         { "Mixer", 0x5 },
3643                 },
3644         },
3645 };
3646 /*
3647  * This is just place-holder, so there's something for alc_build_pcms to look
3648  * at when it calculates the maximum number of channels. ALC260 has no mixer
3649  * element which allows changing the channel mode, so the verb list is
3650  * never used.
3651  */
3652 static struct hda_channel_mode alc260_modes[1] = {
3653         { 2, NULL },
3654 };
3655
3656
3657 /* Mixer combinations
3658  *
3659  * basic: base_output + input + pc_beep + capture
3660  * HP: base_output + input + capture_alt
3661  * HP_3013: hp_3013 + input + capture
3662  * fujitsu: fujitsu + capture
3663  * acer: acer + capture
3664  */
3665
3666 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3667         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3668         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3669         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3670         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3671         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3672         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3673         { } /* end */
3674 };
3675
3676 static struct snd_kcontrol_new alc260_input_mixer[] = {
3677         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3678         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3679         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3680         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3681         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3682         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3683         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3684         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3685         { } /* end */
3686 };
3687
3688 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3689         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3690         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3691         { } /* end */
3692 };
3693
3694 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3695         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3696         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3697         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3698         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3699         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3700         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3701         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3702         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3703         { } /* end */
3704 };
3705
3706 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3707  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3708  */
3709 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3710         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3711         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3712         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3713         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3714         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3715         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3716         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3717         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3718         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3719         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3720         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3721         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3722         { } /* end */
3723 };
3724
3725 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3726  * versions of the ALC260 don't act on requests to enable mic bias from NID
3727  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3728  * datasheet doesn't mention this restriction.  At this stage it's not clear
3729  * whether this behaviour is intentional or is a hardware bug in chip
3730  * revisions available in early 2006.  Therefore for now allow the
3731  * "Headphone Jack Mode" control to span all choices, but if it turns out
3732  * that the lack of mic bias for this NID is intentional we could change the
3733  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3734  *
3735  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3736  * don't appear to make the mic bias available from the "line" jack, even
3737  * though the NID used for this jack (0x14) can supply it.  The theory is
3738  * that perhaps Acer have included blocking capacitors between the ALC260
3739  * and the output jack.  If this turns out to be the case for all such
3740  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3741  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3742  *
3743  * The C20x Tablet series have a mono internal speaker which is controlled
3744  * via the chip's Mono sum widget and pin complex, so include the necessary
3745  * controls for such models.  On models without a "mono speaker" the control
3746  * won't do anything.
3747  */
3748 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3749         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3750         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3751         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3752         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3753                               HDA_OUTPUT),
3754         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3755                            HDA_INPUT),
3756         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3757         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3758         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3759         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3760         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3761         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3762         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3763         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3764         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3765         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3766         { } /* end */
3767 };
3768
3769 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3770  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3771  */
3772 static struct snd_kcontrol_new alc260_will_mixer[] = {
3773         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3774         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3775         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3776         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3777         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3778         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3779         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3780         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3781         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3782         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3783         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3784         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3785         { } /* end */
3786 };
3787
3788 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3789  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3790  */
3791 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3792         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3793         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3794         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3795         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3796         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3797         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3798         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3799         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3800         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3801         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3802         { } /* end */
3803 };
3804
3805 /* capture mixer elements */
3806 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3807         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3808         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3809         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3810         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3811         {
3812                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3813                 /* The multiple "Capture Source" controls confuse alsamixer
3814                  * So call somewhat different..
3815                  * FIXME: the controls appear in the "playback" view!
3816                  */
3817                 /* .name = "Capture Source", */
3818                 .name = "Input Source",
3819                 .count = 2,
3820                 .info = alc_mux_enum_info,
3821                 .get = alc_mux_enum_get,
3822                 .put = alc_mux_enum_put,
3823         },
3824         { } /* end */
3825 };
3826
3827 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3828         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3829         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3830         {
3831                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3832                 /* The multiple "Capture Source" controls confuse alsamixer
3833                  * So call somewhat different..
3834                  * FIXME: the controls appear in the "playback" view!
3835                  */
3836                 /* .name = "Capture Source", */
3837                 .name = "Input Source",
3838                 .count = 1,
3839                 .info = alc_mux_enum_info,
3840                 .get = alc_mux_enum_get,
3841                 .put = alc_mux_enum_put,
3842         },
3843         { } /* end */
3844 };
3845
3846 /*
3847  * initialization verbs
3848  */
3849 static struct hda_verb alc260_init_verbs[] = {
3850         /* Line In pin widget for input */
3851         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3852         /* CD pin widget for input */
3853         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3854         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3855         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3856         /* Mic2 (front panel) pin widget for input and vref at 80% */
3857         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3858         /* LINE-2 is used for line-out in rear */
3859         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3860         /* select line-out */
3861         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3862         /* LINE-OUT pin */
3863         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3864         /* enable HP */
3865         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3866         /* enable Mono */
3867         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3868         /* mute capture amp left and right */
3869         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3870         /* set connection select to line in (default select for this ADC) */
3871         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3872         /* mute capture amp left and right */
3873         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3874         /* set connection select to line in (default select for this ADC) */
3875         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3876         /* set vol=0 Line-Out mixer amp left and right */
3877         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3878         /* unmute pin widget amp left and right (no gain on this amp) */
3879         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3880         /* set vol=0 HP mixer amp left and right */
3881         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3882         /* unmute pin widget amp left and right (no gain on this amp) */
3883         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3884         /* set vol=0 Mono mixer amp left and right */
3885         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3886         /* unmute pin widget amp left and right (no gain on this amp) */
3887         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3888         /* unmute LINE-2 out pin */
3889         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3890         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3891          * Line In 2 = 0x03
3892          */
3893         /* mute analog inputs */
3894         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3895         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3896         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3897         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3898         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3899         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3900         /* mute Front out path */
3901         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3902         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3903         /* mute Headphone out path */
3904         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3905         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3906         /* mute Mono out path */
3907         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3908         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3909         { }
3910 };
3911
3912 #if 0 /* should be identical with alc260_init_verbs? */
3913 static struct hda_verb alc260_hp_init_verbs[] = {
3914         /* Headphone and output */
3915         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3916         /* mono output */
3917         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3918         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3919         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3920         /* Mic2 (front panel) pin widget for input and vref at 80% */
3921         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3922         /* Line In pin widget for input */
3923         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3924         /* Line-2 pin widget for output */
3925         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3926         /* CD pin widget for input */
3927         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3928         /* unmute amp left and right */
3929         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3930         /* set connection select to line in (default select for this ADC) */
3931         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3932         /* unmute Line-Out mixer amp left and right (volume = 0) */
3933         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3934         /* mute pin widget amp left and right (no gain on this amp) */
3935         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3936         /* unmute HP mixer amp left and right (volume = 0) */
3937         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3938         /* mute pin widget amp left and right (no gain on this amp) */
3939         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3940         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3941          * Line In 2 = 0x03
3942          */
3943         /* mute analog inputs */
3944         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3945         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3946         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3947         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3948         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3949         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3950         /* Unmute Front out path */
3951         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3952         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3953         /* Unmute Headphone out path */
3954         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3955         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3956         /* Unmute Mono out path */
3957         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3958         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3959         { }
3960 };
3961 #endif
3962
3963 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3964         /* Line out and output */
3965         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3966         /* mono output */
3967         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3968         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3969         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3970         /* Mic2 (front panel) pin widget for input and vref at 80% */
3971         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3972         /* Line In pin widget for input */
3973         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3974         /* Headphone pin widget for output */
3975         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3976         /* CD pin widget for input */
3977         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3978         /* unmute amp left and right */
3979         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3980         /* set connection select to line in (default select for this ADC) */
3981         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3982         /* unmute Line-Out mixer amp left and right (volume = 0) */
3983         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3984         /* mute pin widget amp left and right (no gain on this amp) */
3985         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3986         /* unmute HP mixer amp left and right (volume = 0) */
3987         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3988         /* mute pin widget amp left and right (no gain on this amp) */
3989         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3990         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3991          * Line In 2 = 0x03
3992          */
3993         /* mute analog inputs */
3994         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3995         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3996         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3997         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3998         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3999         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4000         /* Unmute Front out path */
4001         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4002         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4003         /* Unmute Headphone out path */
4004         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4005         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4006         /* Unmute Mono out path */
4007         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4008         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4009         { }
4010 };
4011
4012 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4013  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4014  * audio = 0x16, internal speaker = 0x10.
4015  */
4016 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4017         /* Disable all GPIOs */
4018         {0x01, AC_VERB_SET_GPIO_MASK, 0},
4019         /* Internal speaker is connected to headphone pin */
4020         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4021         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4022         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4023         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4024         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4025         /* Ensure all other unused pins are disabled and muted. */
4026         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4027         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4028         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4029         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4030         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4031         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4032         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4033         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4034
4035         /* Disable digital (SPDIF) pins */
4036         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4037         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4038
4039         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
4040          * when acting as an output.
4041          */
4042         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4043
4044         /* Start with output sum widgets muted and their output gains at min */
4045         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4046         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4047         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4048         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4049         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4050         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4051         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4052         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4053         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4054
4055         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4056         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4057         /* Unmute Line1 pin widget output buffer since it starts as an output.
4058          * If the pin mode is changed by the user the pin mode control will
4059          * take care of enabling the pin's input/output buffers as needed.
4060          * Therefore there's no need to enable the input buffer at this
4061          * stage.
4062          */
4063         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4064         /* Unmute input buffer of pin widget used for Line-in (no equiv 
4065          * mixer ctrl)
4066          */
4067         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4068
4069         /* Mute capture amp left and right */
4070         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4071         /* Set ADC connection select to match default mixer setting - line 
4072          * in (on mic1 pin)
4073          */
4074         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4075
4076         /* Do the same for the second ADC: mute capture input amp and
4077          * set ADC connection to line in (on mic1 pin)
4078          */
4079         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4080         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4081
4082         /* Mute all inputs to mixer widget (even unconnected ones) */
4083         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4084         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4085         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4086         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4087         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4088         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4089         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4090         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4091
4092         { }
4093 };
4094
4095 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4096  * similar laptops (adapted from Fujitsu init verbs).
4097  */
4098 static struct hda_verb alc260_acer_init_verbs[] = {
4099         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4100          * the headphone jack.  Turn this on and rely on the standard mute
4101          * methods whenever the user wants to turn these outputs off.
4102          */
4103         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4104         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4105         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4106         /* Internal speaker/Headphone jack is connected to Line-out pin */
4107         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4108         /* Internal microphone/Mic jack is connected to Mic1 pin */
4109         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4110         /* Line In jack is connected to Line1 pin */
4111         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4112         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4113         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4114         /* Ensure all other unused pins are disabled and muted. */
4115         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4116         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4117         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4118         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4119         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4120         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4121         /* Disable digital (SPDIF) pins */
4122         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4123         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4124
4125         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
4126          * bus when acting as outputs.
4127          */
4128         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4129         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4130
4131         /* Start with output sum widgets muted and their output gains at min */
4132         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4133         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4134         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4135         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4136         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4137         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4138         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4139         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4140         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4141
4142         /* Unmute Line-out pin widget amp left and right
4143          * (no equiv mixer ctrl)
4144          */
4145         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4146         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4147         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4148         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4149          * inputs. If the pin mode is changed by the user the pin mode control
4150          * will take care of enabling the pin's input/output buffers as needed.
4151          * Therefore there's no need to enable the input buffer at this
4152          * stage.
4153          */
4154         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4155         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4156
4157         /* Mute capture amp left and right */
4158         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4159         /* Set ADC connection select to match default mixer setting - mic
4160          * (on mic1 pin)
4161          */
4162         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4163
4164         /* Do similar with the second ADC: mute capture input amp and
4165          * set ADC connection to mic to match ALSA's default state.
4166          */
4167         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4168         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4169
4170         /* Mute all inputs to mixer widget (even unconnected ones) */
4171         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4172         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4173         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4174         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4175         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4176         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4177         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4178         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4179
4180         { }
4181 };
4182
4183 static struct hda_verb alc260_will_verbs[] = {
4184         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4185         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4186         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4187         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4188         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4189         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4190         {}
4191 };
4192
4193 static struct hda_verb alc260_replacer_672v_verbs[] = {
4194         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4195         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4196         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4197
4198         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4199         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4200         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4201
4202         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4203         {}
4204 };
4205
4206 /* toggle speaker-output according to the hp-jack state */
4207 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4208 {
4209         unsigned int present;
4210
4211         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4212         present = snd_hda_codec_read(codec, 0x0f, 0,
4213                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4214         if (present) {
4215                 snd_hda_codec_write_cache(codec, 0x01, 0,
4216                                           AC_VERB_SET_GPIO_DATA, 1);
4217                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4218                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4219                                           PIN_HP);
4220         } else {
4221                 snd_hda_codec_write_cache(codec, 0x01, 0,
4222                                           AC_VERB_SET_GPIO_DATA, 0);
4223                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4224                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4225                                           PIN_OUT);
4226         }
4227 }
4228
4229 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4230                                        unsigned int res)
4231 {
4232         if ((res >> 26) == ALC880_HP_EVENT)
4233                 alc260_replacer_672v_automute(codec);
4234 }
4235
4236 /* Test configuration for debugging, modelled after the ALC880 test
4237  * configuration.
4238  */
4239 #ifdef CONFIG_SND_DEBUG
4240 static hda_nid_t alc260_test_dac_nids[1] = {
4241         0x02,
4242 };
4243 static hda_nid_t alc260_test_adc_nids[2] = {
4244         0x04, 0x05,
4245 };
4246 /* For testing the ALC260, each input MUX needs its own definition since
4247  * the signal assignments are different.  This assumes that the first ADC 
4248  * is NID 0x04.
4249  */
4250 static struct hda_input_mux alc260_test_capture_sources[2] = {
4251         {
4252                 .num_items = 7,
4253                 .items = {
4254                         { "MIC1 pin", 0x0 },
4255                         { "MIC2 pin", 0x1 },
4256                         { "LINE1 pin", 0x2 },
4257                         { "LINE2 pin", 0x3 },
4258                         { "CD pin", 0x4 },
4259                         { "LINE-OUT pin", 0x5 },
4260                         { "HP-OUT pin", 0x6 },
4261                 },
4262         },
4263         {
4264                 .num_items = 8,
4265                 .items = {
4266                         { "MIC1 pin", 0x0 },
4267                         { "MIC2 pin", 0x1 },
4268                         { "LINE1 pin", 0x2 },
4269                         { "LINE2 pin", 0x3 },
4270                         { "CD pin", 0x4 },
4271                         { "Mixer", 0x5 },
4272                         { "LINE-OUT pin", 0x6 },
4273                         { "HP-OUT pin", 0x7 },
4274                 },
4275         },
4276 };
4277 static struct snd_kcontrol_new alc260_test_mixer[] = {
4278         /* Output driver widgets */
4279         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4280         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4281         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4282         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4283         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4284         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4285
4286         /* Modes for retasking pin widgets
4287          * Note: the ALC260 doesn't seem to act on requests to enable mic
4288          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4289          * mention this restriction.  At this stage it's not clear whether
4290          * this behaviour is intentional or is a hardware bug in chip
4291          * revisions available at least up until early 2006.  Therefore for
4292          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4293          * choices, but if it turns out that the lack of mic bias for these
4294          * NIDs is intentional we could change their modes from
4295          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4296          */
4297         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4298         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4299         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4300         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4301         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4302         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4303
4304         /* Loopback mixer controls */
4305         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4306         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4307         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4308         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4309         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4310         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4311         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4312         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4313         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4314         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4315         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4316         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4317         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4318         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4319         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4320         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4321
4322         /* Controls for GPIO pins, assuming they are configured as outputs */
4323         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4324         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4325         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4326         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4327
4328         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4329          * is ambigious as to which NID is which; testing on laptops which
4330          * make this output available should provide clarification. 
4331          */
4332         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4333         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4334
4335         { } /* end */
4336 };
4337 static struct hda_verb alc260_test_init_verbs[] = {
4338         /* Enable all GPIOs as outputs with an initial value of 0 */
4339         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4340         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4341         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4342
4343         /* Enable retasking pins as output, initially without power amp */
4344         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4345         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4346         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4347         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4348         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4349         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4350
4351         /* Disable digital (SPDIF) pins initially, but users can enable
4352          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4353          * payload also sets the generation to 0, output to be in "consumer"
4354          * PCM format, copyright asserted, no pre-emphasis and no validity
4355          * control.
4356          */
4357         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4358         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4359
4360         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4361          * OUT1 sum bus when acting as an output.
4362          */
4363         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4364         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4365         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4366         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4367
4368         /* Start with output sum widgets muted and their output gains at min */
4369         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4370         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4371         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4372         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4373         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4374         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4375         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4376         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4377         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4378
4379         /* Unmute retasking pin widget output buffers since the default
4380          * state appears to be output.  As the pin mode is changed by the
4381          * user the pin mode control will take care of enabling the pin's
4382          * input/output buffers as needed.
4383          */
4384         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4385         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4386         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4387         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4388         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4389         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4390         /* Also unmute the mono-out pin widget */
4391         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4392
4393         /* Mute capture amp left and right */
4394         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4395         /* Set ADC connection select to match default mixer setting (mic1
4396          * pin)
4397          */
4398         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4399
4400         /* Do the same for the second ADC: mute capture input amp and
4401          * set ADC connection to mic1 pin
4402          */
4403         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4404         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4405
4406         /* Mute all inputs to mixer widget (even unconnected ones) */
4407         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4408         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4409         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4410         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4411         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4412         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4413         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4414         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4415
4416         { }
4417 };
4418 #endif
4419
4420 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4421         .substreams = 1,
4422         .channels_min = 2,
4423         .channels_max = 2,
4424 };
4425
4426 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4427         .substreams = 1,
4428         .channels_min = 2,
4429         .channels_max = 2,
4430 };
4431
4432 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4433 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4434
4435 /*
4436  * for BIOS auto-configuration
4437  */
4438
4439 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4440                                         const char *pfx)
4441 {
4442         hda_nid_t nid_vol;
4443         unsigned long vol_val, sw_val;
4444         char name[32];
4445         int err;
4446
4447         if (nid >= 0x0f && nid < 0x11) {
4448                 nid_vol = nid - 0x7;
4449                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4450                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4451         } else if (nid == 0x11) {
4452                 nid_vol = nid - 0x7;
4453                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4454                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4455         } else if (nid >= 0x12 && nid <= 0x15) {
4456                 nid_vol = 0x08;
4457                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4458                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4459         } else
4460                 return 0; /* N/A */
4461         
4462         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4463         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4464         if (err < 0)
4465                 return err;
4466         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4467         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4468         if (err < 0)
4469                 return err;
4470         return 1;
4471 }
4472
4473 /* add playback controls from the parsed DAC table */
4474 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4475                                              const struct auto_pin_cfg *cfg)
4476 {
4477         hda_nid_t nid;
4478         int err;
4479
4480         spec->multiout.num_dacs = 1;
4481         spec->multiout.dac_nids = spec->private_dac_nids;
4482         spec->multiout.dac_nids[0] = 0x02;
4483
4484         nid = cfg->line_out_pins[0];
4485         if (nid) {
4486                 err = alc260_add_playback_controls(spec, nid, "Front");
4487                 if (err < 0)
4488                         return err;
4489         }
4490
4491         nid = cfg->speaker_pins[0];
4492         if (nid) {
4493                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4494                 if (err < 0)
4495                         return err;
4496         }
4497
4498         nid = cfg->hp_pins[0];
4499         if (nid) {
4500                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4501                 if (err < 0)
4502                         return err;
4503         }
4504         return 0;
4505 }
4506
4507 /* create playback/capture controls for input pins */
4508 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4509                                                 const struct auto_pin_cfg *cfg)
4510 {
4511         struct hda_input_mux *imux = &spec->private_imux;
4512         int i, err, idx;
4513
4514         for (i = 0; i < AUTO_PIN_LAST; i++) {
4515                 if (cfg->input_pins[i] >= 0x12) {
4516                         idx = cfg->input_pins[i] - 0x12;
4517                         err = new_analog_input(spec, cfg->input_pins[i],
4518                                                auto_pin_cfg_labels[i], idx,
4519                                                0x07);
4520                         if (err < 0)
4521                                 return err;
4522                         imux->items[imux->num_items].label =
4523                                 auto_pin_cfg_labels[i];
4524                         imux->items[imux->num_items].index = idx;
4525                         imux->num_items++;
4526                 }
4527                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4528                         idx = cfg->input_pins[i] - 0x09;
4529                         err = new_analog_input(spec, cfg->input_pins[i],
4530                                                auto_pin_cfg_labels[i], idx,
4531                                                0x07);
4532                         if (err < 0)
4533                                 return err;
4534                         imux->items[imux->num_items].label =
4535                                 auto_pin_cfg_labels[i];
4536                         imux->items[imux->num_items].index = idx;
4537                         imux->num_items++;
4538                 }
4539         }
4540         return 0;
4541 }
4542
4543 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4544                                               hda_nid_t nid, int pin_type,
4545                                               int sel_idx)
4546 {
4547         /* set as output */
4548         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4549                             pin_type);
4550         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4551                             AMP_OUT_UNMUTE);
4552         /* need the manual connection? */
4553         if (nid >= 0x12) {
4554                 int idx = nid - 0x12;
4555                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4556                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4557         }
4558 }
4559
4560 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4561 {
4562         struct alc_spec *spec = codec->spec;
4563         hda_nid_t nid;
4564
4565         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4566         nid = spec->autocfg.line_out_pins[0];
4567         if (nid) {
4568                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4569                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4570         }
4571         
4572         nid = spec->autocfg.speaker_pins[0];
4573         if (nid)
4574                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4575
4576         nid = spec->autocfg.hp_pins[0];
4577         if (nid)
4578                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4579 }
4580
4581 #define ALC260_PIN_CD_NID               0x16
4582 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4583 {
4584         struct alc_spec *spec = codec->spec;
4585         int i;
4586
4587         for (i = 0; i < AUTO_PIN_LAST; i++) {
4588                 hda_nid_t nid = spec->autocfg.input_pins[i];
4589                 if (nid >= 0x12) {
4590                         snd_hda_codec_write(codec, nid, 0,
4591                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4592                                             i <= AUTO_PIN_FRONT_MIC ?
4593                                             PIN_VREF80 : PIN_IN);
4594                         if (nid != ALC260_PIN_CD_NID)
4595                                 snd_hda_codec_write(codec, nid, 0,
4596                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4597                                                     AMP_OUT_MUTE);
4598                 }
4599         }
4600 }
4601
4602 /*
4603  * generic initialization of ADC, input mixers and output mixers
4604  */
4605 static struct hda_verb alc260_volume_init_verbs[] = {
4606         /*
4607          * Unmute ADC0-1 and set the default input to mic-in
4608          */
4609         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4610         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4611         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4612         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4613         
4614         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4615          * mixer widget
4616          * Note: PASD motherboards uses the Line In 2 as the input for
4617          * front panel mic (mic 2)
4618          */
4619         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4620         /* mute analog inputs */
4621         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4622         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4623         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4624         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4625         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4626
4627         /*
4628          * Set up output mixers (0x08 - 0x0a)
4629          */
4630         /* set vol=0 to output mixers */
4631         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4632         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4633         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4634         /* set up input amps for analog loopback */
4635         /* Amp Indices: DAC = 0, mixer = 1 */
4636         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4637         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4638         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4639         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4640         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4641         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4642         
4643         { }
4644 };
4645
4646 static int alc260_parse_auto_config(struct hda_codec *codec)
4647 {
4648         struct alc_spec *spec = codec->spec;
4649         unsigned int wcap;
4650         int err;
4651         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4652
4653         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4654                                            alc260_ignore);
4655         if (err < 0)
4656                 return err;
4657         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4658         if (err < 0)
4659                 return err;
4660         if (!spec->kctl_alloc)
4661                 return 0; /* can't find valid BIOS pin config */
4662         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4663         if (err < 0)
4664                 return err;
4665
4666         spec->multiout.max_channels = 2;
4667
4668         if (spec->autocfg.dig_out_pin)
4669                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4670         if (spec->kctl_alloc)
4671                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4672
4673         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4674
4675         spec->num_mux_defs = 1;
4676         spec->input_mux = &spec->private_imux;
4677
4678         /* check whether NID 0x04 is valid */
4679         wcap = get_wcaps(codec, 0x04);
4680         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4681         if (wcap != AC_WID_AUD_IN) {
4682                 spec->adc_nids = alc260_adc_nids_alt;
4683                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4684                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4685         } else {
4686                 spec->adc_nids = alc260_adc_nids;
4687                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4688                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4689         }
4690         spec->num_mixers++;
4691
4692         return 1;
4693 }
4694
4695 /* additional initialization for auto-configuration model */
4696 static void alc260_auto_init(struct hda_codec *codec)
4697 {
4698         alc260_auto_init_multi_out(codec);
4699         alc260_auto_init_analog_input(codec);
4700 }
4701
4702 #ifdef CONFIG_SND_HDA_POWER_SAVE
4703 static struct hda_amp_list alc260_loopbacks[] = {
4704         { 0x07, HDA_INPUT, 0 },
4705         { 0x07, HDA_INPUT, 1 },
4706         { 0x07, HDA_INPUT, 2 },
4707         { 0x07, HDA_INPUT, 3 },
4708         { 0x07, HDA_INPUT, 4 },
4709         { } /* end */
4710 };
4711 #endif
4712
4713 /*
4714  * ALC260 configurations
4715  */
4716 static const char *alc260_models[ALC260_MODEL_LAST] = {
4717         [ALC260_BASIC]          = "basic",
4718         [ALC260_HP]             = "hp",
4719         [ALC260_HP_3013]        = "hp-3013",
4720         [ALC260_FUJITSU_S702X]  = "fujitsu",
4721         [ALC260_ACER]           = "acer",
4722         [ALC260_WILL]           = "will",
4723         [ALC260_REPLACER_672V]  = "replacer",
4724 #ifdef CONFIG_SND_DEBUG
4725         [ALC260_TEST]           = "test",
4726 #endif
4727         [ALC260_AUTO]           = "auto",
4728 };
4729
4730 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4731         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4732         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4733         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4734         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4735         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4736         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4737         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4738         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4739         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4740         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4741         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4742         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4743         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4744         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4745         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4746         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4747         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4748         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4749         {}
4750 };
4751
4752 static struct alc_config_preset alc260_presets[] = {
4753         [ALC260_BASIC] = {
4754                 .mixers = { alc260_base_output_mixer,
4755                             alc260_input_mixer,
4756                             alc260_pc_beep_mixer,
4757                             alc260_capture_mixer },
4758                 .init_verbs = { alc260_init_verbs },
4759                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4760                 .dac_nids = alc260_dac_nids,
4761                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4762                 .adc_nids = alc260_adc_nids,
4763                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4764                 .channel_mode = alc260_modes,
4765                 .input_mux = &alc260_capture_source,
4766         },
4767         [ALC260_HP] = {
4768                 .mixers = { alc260_base_output_mixer,
4769                             alc260_input_mixer,
4770                             alc260_capture_alt_mixer },
4771                 .init_verbs = { alc260_init_verbs },
4772                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4773                 .dac_nids = alc260_dac_nids,
4774                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4775                 .adc_nids = alc260_hp_adc_nids,
4776                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4777                 .channel_mode = alc260_modes,
4778                 .input_mux = &alc260_capture_source,
4779         },
4780         [ALC260_HP_3013] = {
4781                 .mixers = { alc260_hp_3013_mixer,
4782                             alc260_input_mixer,
4783                             alc260_capture_alt_mixer },
4784                 .init_verbs = { alc260_hp_3013_init_verbs },
4785                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4786                 .dac_nids = alc260_dac_nids,
4787                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4788                 .adc_nids = alc260_hp_adc_nids,
4789                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4790                 .channel_mode = alc260_modes,
4791                 .input_mux = &alc260_capture_source,
4792         },
4793         [ALC260_FUJITSU_S702X] = {
4794                 .mixers = { alc260_fujitsu_mixer,
4795                             alc260_capture_mixer },
4796                 .init_verbs = { alc260_fujitsu_init_verbs },
4797                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4798                 .dac_nids = alc260_dac_nids,
4799                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4800                 .adc_nids = alc260_dual_adc_nids,
4801                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4802                 .channel_mode = alc260_modes,
4803                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4804                 .input_mux = alc260_fujitsu_capture_sources,
4805         },
4806         [ALC260_ACER] = {
4807                 .mixers = { alc260_acer_mixer,
4808                             alc260_capture_mixer },
4809                 .init_verbs = { alc260_acer_init_verbs },
4810                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4811                 .dac_nids = alc260_dac_nids,
4812                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4813                 .adc_nids = alc260_dual_adc_nids,
4814                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4815                 .channel_mode = alc260_modes,
4816                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4817                 .input_mux = alc260_acer_capture_sources,
4818         },
4819         [ALC260_WILL] = {
4820                 .mixers = { alc260_will_mixer,
4821                             alc260_capture_mixer },
4822                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4823                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4824                 .dac_nids = alc260_dac_nids,
4825                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4826                 .adc_nids = alc260_adc_nids,
4827                 .dig_out_nid = ALC260_DIGOUT_NID,
4828                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4829                 .channel_mode = alc260_modes,
4830                 .input_mux = &alc260_capture_source,
4831         },
4832         [ALC260_REPLACER_672V] = {
4833                 .mixers = { alc260_replacer_672v_mixer,
4834                             alc260_capture_mixer },
4835                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4836                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4837                 .dac_nids = alc260_dac_nids,
4838                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4839                 .adc_nids = alc260_adc_nids,
4840                 .dig_out_nid = ALC260_DIGOUT_NID,
4841                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4842                 .channel_mode = alc260_modes,
4843                 .input_mux = &alc260_capture_source,
4844                 .unsol_event = alc260_replacer_672v_unsol_event,
4845                 .init_hook = alc260_replacer_672v_automute,
4846         },
4847 #ifdef CONFIG_SND_DEBUG
4848         [ALC260_TEST] = {
4849                 .mixers = { alc260_test_mixer,
4850                             alc260_capture_mixer },
4851                 .init_verbs = { alc260_test_init_verbs },
4852                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4853                 .dac_nids = alc260_test_dac_nids,
4854                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4855                 .adc_nids = alc260_test_adc_nids,
4856                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4857                 .channel_mode = alc260_modes,
4858                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4859                 .input_mux = alc260_test_capture_sources,
4860         },
4861 #endif
4862 };
4863
4864 static int patch_alc260(struct hda_codec *codec)
4865 {
4866         struct alc_spec *spec;
4867         int err, board_config;
4868
4869         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4870         if (spec == NULL)
4871                 return -ENOMEM;
4872
4873         codec->spec = spec;
4874
4875         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4876                                                   alc260_models,
4877                                                   alc260_cfg_tbl);
4878         if (board_config < 0) {
4879                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4880                            "trying auto-probe from BIOS...\n");
4881                 board_config = ALC260_AUTO;
4882         }
4883
4884         if (board_config == ALC260_AUTO) {
4885                 /* automatic parse from the BIOS config */
4886                 err = alc260_parse_auto_config(codec);
4887                 if (err < 0) {
4888                         alc_free(codec);
4889                         return err;
4890                 } else if (!err) {
4891                         printk(KERN_INFO
4892                                "hda_codec: Cannot set up configuration "
4893                                "from BIOS.  Using base mode...\n");
4894                         board_config = ALC260_BASIC;
4895                 }
4896         }
4897
4898         if (board_config != ALC260_AUTO)
4899                 setup_preset(spec, &alc260_presets[board_config]);
4900
4901         spec->stream_name_analog = "ALC260 Analog";
4902         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4903         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4904
4905         spec->stream_name_digital = "ALC260 Digital";
4906         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4907         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4908
4909         codec->patch_ops = alc_patch_ops;
4910         if (board_config == ALC260_AUTO)
4911                 spec->init_hook = alc260_auto_init;
4912 #ifdef CONFIG_SND_HDA_POWER_SAVE
4913         if (!spec->loopback.amplist)
4914                 spec->loopback.amplist = alc260_loopbacks;
4915 #endif
4916
4917         return 0;
4918 }
4919
4920
4921 /*
4922  * ALC882 support
4923  *
4924  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4925  * configuration.  Each pin widget can choose any input DACs and a mixer.
4926  * Each ADC is connected from a mixer of all inputs.  This makes possible
4927  * 6-channel independent captures.
4928  *
4929  * In addition, an independent DAC for the multi-playback (not used in this
4930  * driver yet).
4931  */
4932 #define ALC882_DIGOUT_NID       0x06
4933 #define ALC882_DIGIN_NID        0x0a
4934
4935 static struct hda_channel_mode alc882_ch_modes[1] = {
4936         { 8, NULL }
4937 };
4938
4939 static hda_nid_t alc882_dac_nids[4] = {
4940         /* front, rear, clfe, rear_surr */
4941         0x02, 0x03, 0x04, 0x05
4942 };
4943
4944 /* identical with ALC880 */
4945 #define alc882_adc_nids         alc880_adc_nids
4946 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4947
4948 /* input MUX */
4949 /* FIXME: should be a matrix-type input source selection */
4950
4951 static struct hda_input_mux alc882_capture_source = {
4952         .num_items = 4,
4953         .items = {
4954                 { "Mic", 0x0 },
4955                 { "Front Mic", 0x1 },
4956                 { "Line", 0x2 },
4957                 { "CD", 0x4 },
4958         },
4959 };
4960 #define alc882_mux_enum_info alc_mux_enum_info
4961 #define alc882_mux_enum_get alc_mux_enum_get
4962
4963 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4964                                struct snd_ctl_elem_value *ucontrol)
4965 {
4966         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4967         struct alc_spec *spec = codec->spec;
4968         const struct hda_input_mux *imux = spec->input_mux;
4969         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4970         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4971         hda_nid_t nid = capture_mixers[adc_idx];
4972         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4973         unsigned int i, idx;
4974
4975         idx = ucontrol->value.enumerated.item[0];
4976         if (idx >= imux->num_items)
4977                 idx = imux->num_items - 1;
4978         if (*cur_val == idx)
4979                 return 0;
4980         for (i = 0; i < imux->num_items; i++) {
4981                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4982                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4983                                          imux->items[i].index,
4984                                          HDA_AMP_MUTE, v);
4985         }
4986         *cur_val = idx;
4987         return 1;
4988 }
4989
4990 /*
4991  * 2ch mode
4992  */
4993 static struct hda_verb alc882_3ST_ch2_init[] = {
4994         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4995         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4996         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4997         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4998         { } /* end */
4999 };
5000
5001 /*
5002  * 6ch mode
5003  */
5004 static struct hda_verb alc882_3ST_ch6_init[] = {
5005         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5006         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5007         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5008         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5009         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5010         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5011         { } /* end */
5012 };
5013
5014 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5015         { 2, alc882_3ST_ch2_init },
5016         { 6, alc882_3ST_ch6_init },
5017 };
5018
5019 /*
5020  * 6ch mode
5021  */
5022 static struct hda_verb alc882_sixstack_ch6_init[] = {
5023         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5024         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5025         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5026         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5027         { } /* end */
5028 };
5029
5030 /*
5031  * 8ch mode
5032  */
5033 static struct hda_verb alc882_sixstack_ch8_init[] = {
5034         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5035         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5036         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5037         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5038         { } /* end */
5039 };
5040
5041 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5042         { 6, alc882_sixstack_ch6_init },
5043         { 8, alc882_sixstack_ch8_init },
5044 };
5045
5046 /*
5047  * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5048  */
5049
5050 /*
5051  * 2ch mode
5052  */
5053 static struct hda_verb alc885_mbp_ch2_init[] = {
5054         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5055         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5056         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5057         { } /* end */
5058 };
5059
5060 /*
5061  * 6ch mode
5062  */
5063 static struct hda_verb alc885_mbp_ch6_init[] = {
5064         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5065         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5066         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5067         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5068         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5069         { } /* end */
5070 };
5071
5072 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5073         { 2, alc885_mbp_ch2_init },
5074         { 6, alc885_mbp_ch6_init },
5075 };
5076
5077
5078 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5079  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5080  */
5081 static struct snd_kcontrol_new alc882_base_mixer[] = {
5082         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5083         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5084         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5085         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5086         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5087         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5088         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5089         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5090         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5091         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5092         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5093         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5094         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5095         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5096         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5097         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5098         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5099         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5100         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5101         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5102         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5103         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5104         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5105         { } /* end */
5106 };
5107
5108 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5109         HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5110         HDA_BIND_MUTE   ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5111         HDA_CODEC_MUTE  ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5112         HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5113         HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5114         HDA_CODEC_MUTE  ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5115         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5116         HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5117         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5118         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5119         { } /* end */
5120 };
5121 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5122         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5123         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5124         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5125         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5126         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5127         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5128         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5129         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5130         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5131         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5132         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5133         { } /* end */
5134 };
5135
5136 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5137         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5138         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5139         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5140         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5141         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5142         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5143         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5144         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5145         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5146         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5147         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5148         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5149         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5150         { } /* end */
5151 };
5152
5153 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5154  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5155  */
5156 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5157         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5158         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5159         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5160         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5161         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5162         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5163         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5164         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5165         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5166         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5167         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5168         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5169         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5170         { } /* end */
5171 };
5172
5173 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5174         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5175         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5176         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5177         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5178         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5179         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5180         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5181         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5182         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5183         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5184         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5185         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5186         { } /* end */
5187 };
5188
5189 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5190         {
5191                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5192                 .name = "Channel Mode",
5193                 .info = alc_ch_mode_info,
5194                 .get = alc_ch_mode_get,
5195                 .put = alc_ch_mode_put,
5196         },
5197         { } /* end */
5198 };
5199
5200 static struct hda_verb alc882_init_verbs[] = {
5201         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5202         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5203         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5204         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5205         /* Rear mixer */
5206         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5207         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5208         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5209         /* CLFE mixer */
5210         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5211         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5212         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5213         /* Side mixer */
5214         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5215         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5216         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5217
5218         /* Front Pin: output 0 (0x0c) */
5219         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5220         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5221         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5222         /* Rear Pin: output 1 (0x0d) */
5223         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5224         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5225         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5226         /* CLFE Pin: output 2 (0x0e) */
5227         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5228         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5229         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5230         /* Side Pin: output 3 (0x0f) */
5231         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5232         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5233         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5234         /* Mic (rear) pin: input vref at 80% */
5235         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5236         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5237         /* Front Mic pin: input vref at 80% */
5238         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5239         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5240         /* Line In pin: input */
5241         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5242         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5243         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5244         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5245         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5246         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5247         /* CD pin widget for input */
5248         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5249
5250         /* FIXME: use matrix-type input source selection */
5251         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5252         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5253         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5254         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5255         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5256         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5257         /* Input mixer2 */
5258         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5259         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5260         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5261         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5262         /* Input mixer3 */
5263         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5264         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5265         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5266         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5267         /* ADC1: mute amp left and right */
5268         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5269         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5270         /* ADC2: mute amp left and right */
5271         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5272         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5273         /* ADC3: mute amp left and right */
5274         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5275         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5276
5277         { }
5278 };
5279
5280 static struct hda_verb alc882_eapd_verbs[] = {
5281         /* change to EAPD mode */
5282         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5283         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5284         { }
5285 };
5286
5287 /* Mac Pro test */
5288 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5289         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5290         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5291         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5292         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5293         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5294         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5295         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5296         { } /* end */
5297 };
5298
5299 static struct hda_verb alc882_macpro_init_verbs[] = {
5300         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5301         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5302         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5303         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5304         /* Front Pin: output 0 (0x0c) */
5305         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5306         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5307         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5308         /* Front Mic pin: input vref at 80% */
5309         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5310         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5311         /* Speaker:  output */
5312         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5313         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5314         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5315         /* Headphone output (output 0 - 0x0c) */
5316         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5317         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5318         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5319
5320         /* FIXME: use matrix-type input source selection */
5321         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5322         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5323         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5324         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5325         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5326         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5327         /* Input mixer2 */
5328         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5329         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5330         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5331         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5332         /* Input mixer3 */
5333         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5334         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5335         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5336         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5337         /* ADC1: mute amp left and right */
5338         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5339         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5340         /* ADC2: mute amp left and right */
5341         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5342         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5343         /* ADC3: mute amp left and right */
5344         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5345         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5346
5347         { }
5348 };
5349
5350 /* Macbook Pro rev3 */
5351 static struct hda_verb alc885_mbp3_init_verbs[] = {
5352         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5353         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5354         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5355         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5356         /* Rear mixer */
5357         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5358         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5359         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5360         /* Front Pin: output 0 (0x0c) */
5361         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5362         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5363         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5364         /* HP Pin: output 0 (0x0d) */
5365         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5366         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5367         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5368         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5369         /* Mic (rear) pin: input vref at 80% */
5370         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5371         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5372         /* Front Mic pin: input vref at 80% */
5373         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5374         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5375         /* Line In pin: use output 1 when in LineOut mode */
5376         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5377         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5378         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5379
5380         /* FIXME: use matrix-type input source selection */
5381         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5382         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5383         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5384         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5385         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5386         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5387         /* Input mixer2 */
5388         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5389         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5390         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5391         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5392         /* Input mixer3 */
5393         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5394         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5395         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5396         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5397         /* ADC1: mute amp left and right */
5398         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5399         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5400         /* ADC2: mute amp left and right */
5401         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5402         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5403         /* ADC3: mute amp left and right */
5404         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5405         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5406
5407         { }
5408 };
5409
5410 /* iMac 24 mixer. */
5411 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5412         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5413         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5414         { } /* end */
5415 };
5416
5417 /* iMac 24 init verbs. */
5418 static struct hda_verb alc885_imac24_init_verbs[] = {
5419         /* Internal speakers: output 0 (0x0c) */
5420         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5421         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5422         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5423         /* Internal speakers: output 0 (0x0c) */
5424         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5425         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5426         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5427         /* Headphone: output 0 (0x0c) */
5428         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5429         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5430         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5431         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5432         /* Front Mic: input vref at 80% */
5433         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5434         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5435         { }
5436 };
5437
5438 /* Toggle speaker-output according to the hp-jack state */
5439 static void alc885_imac24_automute(struct hda_codec *codec)
5440 {
5441         unsigned int present;
5442
5443         present = snd_hda_codec_read(codec, 0x14, 0,
5444                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5445         snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5446                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5447         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5448                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5449 }
5450
5451 /* Processes unsolicited events. */
5452 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5453                                       unsigned int res)
5454 {
5455         /* Headphone insertion or removal. */
5456         if ((res >> 26) == ALC880_HP_EVENT)
5457                 alc885_imac24_automute(codec);
5458 }
5459
5460 static void alc885_mbp3_automute(struct hda_codec *codec)
5461 {
5462         unsigned int present;
5463
5464         present = snd_hda_codec_read(codec, 0x15, 0,
5465                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5466         snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5467                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5468         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5469                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5470
5471 }
5472 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5473                                     unsigned int res)
5474 {
5475         /* Headphone insertion or removal. */
5476         if ((res >> 26) == ALC880_HP_EVENT)
5477                 alc885_mbp3_automute(codec);
5478 }
5479
5480
5481 static struct hda_verb alc882_targa_verbs[] = {
5482         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5483         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5484
5485         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5486         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5487         
5488         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5489         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5490         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5491
5492         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5493         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5494         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5495         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5496         { } /* end */
5497 };
5498
5499 /* toggle speaker-output according to the hp-jack state */
5500 static void alc882_targa_automute(struct hda_codec *codec)
5501 {
5502         unsigned int present;
5503  
5504         present = snd_hda_codec_read(codec, 0x14, 0,
5505                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5506         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5507                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5508         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5509                                   present ? 1 : 3);
5510 }
5511
5512 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5513 {
5514         /* Looks like the unsol event is incompatible with the standard
5515          * definition.  4bit tag is placed at 26 bit!
5516          */
5517         if (((res >> 26) == ALC880_HP_EVENT)) {
5518                 alc882_targa_automute(codec);
5519         }
5520 }
5521
5522 static struct hda_verb alc882_asus_a7j_verbs[] = {
5523         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5524         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5525
5526         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5527         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5528         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5529         
5530         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5531         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5532         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5533
5534         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5535         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5536         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5537         { } /* end */
5538 };
5539
5540 static struct hda_verb alc882_asus_a7m_verbs[] = {
5541         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5542         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5543
5544         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5545         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5546         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5547         
5548         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5549         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5550         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5551
5552         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5553         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5554         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5555         { } /* end */
5556 };
5557
5558 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5559 {
5560         unsigned int gpiostate, gpiomask, gpiodir;
5561
5562         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5563                                        AC_VERB_GET_GPIO_DATA, 0);
5564
5565         if (!muted)
5566                 gpiostate |= (1 << pin);
5567         else
5568                 gpiostate &= ~(1 << pin);
5569
5570         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5571                                       AC_VERB_GET_GPIO_MASK, 0);
5572         gpiomask |= (1 << pin);
5573
5574         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5575                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5576         gpiodir |= (1 << pin);
5577
5578
5579         snd_hda_codec_write(codec, codec->afg, 0,
5580                             AC_VERB_SET_GPIO_MASK, gpiomask);
5581         snd_hda_codec_write(codec, codec->afg, 0,
5582                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5583
5584         msleep(1);
5585
5586         snd_hda_codec_write(codec, codec->afg, 0,
5587                             AC_VERB_SET_GPIO_DATA, gpiostate);
5588 }
5589
5590 /* set up GPIO at initialization */
5591 static void alc885_macpro_init_hook(struct hda_codec *codec)
5592 {
5593         alc882_gpio_mute(codec, 0, 0);
5594         alc882_gpio_mute(codec, 1, 0);
5595 }
5596
5597 /* set up GPIO and update auto-muting at initialization */
5598 static void alc885_imac24_init_hook(struct hda_codec *codec)
5599 {
5600         alc885_macpro_init_hook(codec);
5601         alc885_imac24_automute(codec);
5602 }
5603
5604 /*
5605  * generic initialization of ADC, input mixers and output mixers
5606  */
5607 static struct hda_verb alc882_auto_init_verbs[] = {
5608         /*
5609          * Unmute ADC0-2 and set the default input to mic-in
5610          */
5611         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5612         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5613         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5614         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5615         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5616         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5617
5618         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5619          * mixer widget
5620          * Note: PASD motherboards uses the Line In 2 as the input for
5621          * front panel mic (mic 2)
5622          */
5623         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5624         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5625         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5626         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5627         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5628         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5629
5630         /*
5631          * Set up output mixers (0x0c - 0x0f)
5632          */
5633         /* set vol=0 to output mixers */
5634         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5635         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5636         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5637         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5638         /* set up input amps for analog loopback */
5639         /* Amp Indices: DAC = 0, mixer = 1 */
5640         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5641         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5642         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5643         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5644         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5645         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5646         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5647         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5648         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5649         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5650
5651         /* FIXME: use matrix-type input source selection */
5652         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5653         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5654         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5655         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5656         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5657         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5658         /* Input mixer2 */
5659         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5660         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5661         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5662         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5663         /* Input mixer3 */
5664         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5665         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5666         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5667         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5668
5669         { }
5670 };
5671
5672 /* capture mixer elements */
5673 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5674         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5675         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5676         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5677         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5678         {
5679                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5680                 /* The multiple "Capture Source" controls confuse alsamixer
5681                  * So call somewhat different..
5682                  * FIXME: the controls appear in the "playback" view!
5683                  */
5684                 /* .name = "Capture Source", */
5685                 .name = "Input Source",
5686                 .count = 2,
5687                 .info = alc882_mux_enum_info,
5688                 .get = alc882_mux_enum_get,
5689                 .put = alc882_mux_enum_put,
5690         },
5691         { } /* end */
5692 };
5693
5694 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5695         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5696         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5697         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5698         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5699         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5700         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5701         {
5702                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5703                 /* The multiple "Capture Source" controls confuse alsamixer
5704                  * So call somewhat different..
5705                  * FIXME: the controls appear in the "playback" view!
5706                  */
5707                 /* .name = "Capture Source", */
5708                 .name = "Input Source",
5709                 .count = 3,
5710                 .info = alc882_mux_enum_info,
5711                 .get = alc882_mux_enum_get,
5712                 .put = alc882_mux_enum_put,
5713         },
5714         { } /* end */
5715 };
5716
5717 #ifdef CONFIG_SND_HDA_POWER_SAVE
5718 #define alc882_loopbacks        alc880_loopbacks
5719 #endif
5720
5721 /* pcm configuration: identiacal with ALC880 */
5722 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5723 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5724 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5725 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5726
5727 /*
5728  * configuration and preset
5729  */
5730 static const char *alc882_models[ALC882_MODEL_LAST] = {
5731         [ALC882_3ST_DIG]        = "3stack-dig",
5732         [ALC882_6ST_DIG]        = "6stack-dig",
5733         [ALC882_ARIMA]          = "arima",
5734         [ALC882_W2JC]           = "w2jc",
5735         [ALC882_TARGA]          = "targa",
5736         [ALC882_ASUS_A7J]       = "asus-a7j",
5737         [ALC882_ASUS_A7M]       = "asus-a7m",
5738         [ALC885_MACPRO]         = "macpro",
5739         [ALC885_MBP3]           = "mbp3",
5740         [ALC885_IMAC24]         = "imac24",
5741         [ALC882_AUTO]           = "auto",
5742 };
5743
5744 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5745         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5746         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5747         SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
5748         SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
5749         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5750         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5751         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5752         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5753         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5754         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5755         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5756         {}
5757 };
5758
5759 static struct alc_config_preset alc882_presets[] = {
5760         [ALC882_3ST_DIG] = {
5761                 .mixers = { alc882_base_mixer },
5762                 .init_verbs = { alc882_init_verbs },
5763                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5764                 .dac_nids = alc882_dac_nids,
5765                 .dig_out_nid = ALC882_DIGOUT_NID,
5766                 .dig_in_nid = ALC882_DIGIN_NID,
5767                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5768                 .channel_mode = alc882_ch_modes,
5769                 .need_dac_fix = 1,
5770                 .input_mux = &alc882_capture_source,
5771         },
5772         [ALC882_6ST_DIG] = {
5773                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5774                 .init_verbs = { alc882_init_verbs },
5775                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5776                 .dac_nids = alc882_dac_nids,
5777                 .dig_out_nid = ALC882_DIGOUT_NID,
5778                 .dig_in_nid = ALC882_DIGIN_NID,
5779                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5780                 .channel_mode = alc882_sixstack_modes,
5781                 .input_mux = &alc882_capture_source,
5782         },
5783         [ALC882_ARIMA] = {
5784                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5785                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5786                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5787                 .dac_nids = alc882_dac_nids,
5788                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5789                 .channel_mode = alc882_sixstack_modes,
5790                 .input_mux = &alc882_capture_source,
5791         },
5792         [ALC882_W2JC] = {
5793                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5794                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5795                                 alc880_gpio1_init_verbs },
5796                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5797                 .dac_nids = alc882_dac_nids,
5798                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5799                 .channel_mode = alc880_threestack_modes,
5800                 .need_dac_fix = 1,
5801                 .input_mux = &alc882_capture_source,
5802                 .dig_out_nid = ALC882_DIGOUT_NID,
5803         },
5804         [ALC885_MBP3] = {
5805                 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5806                 .init_verbs = { alc885_mbp3_init_verbs,
5807                                 alc880_gpio1_init_verbs },
5808                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5809                 .dac_nids = alc882_dac_nids,
5810                 .channel_mode = alc885_mbp_6ch_modes,
5811                 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5812                 .input_mux = &alc882_capture_source,
5813                 .dig_out_nid = ALC882_DIGOUT_NID,
5814                 .dig_in_nid = ALC882_DIGIN_NID,
5815                 .unsol_event = alc885_mbp3_unsol_event,
5816                 .init_hook = alc885_mbp3_automute,
5817         },
5818         [ALC885_MACPRO] = {
5819                 .mixers = { alc882_macpro_mixer },
5820                 .init_verbs = { alc882_macpro_init_verbs },
5821                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5822                 .dac_nids = alc882_dac_nids,
5823                 .dig_out_nid = ALC882_DIGOUT_NID,
5824                 .dig_in_nid = ALC882_DIGIN_NID,
5825                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5826                 .channel_mode = alc882_ch_modes,
5827                 .input_mux = &alc882_capture_source,
5828                 .init_hook = alc885_macpro_init_hook,
5829         },
5830         [ALC885_IMAC24] = {
5831                 .mixers = { alc885_imac24_mixer },
5832                 .init_verbs = { alc885_imac24_init_verbs },
5833                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5834                 .dac_nids = alc882_dac_nids,
5835                 .dig_out_nid = ALC882_DIGOUT_NID,
5836                 .dig_in_nid = ALC882_DIGIN_NID,
5837                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5838                 .channel_mode = alc882_ch_modes,
5839                 .input_mux = &alc882_capture_source,
5840                 .unsol_event = alc885_imac24_unsol_event,
5841                 .init_hook = alc885_imac24_init_hook,
5842         },
5843         [ALC882_TARGA] = {
5844                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5845                             alc882_capture_mixer },
5846                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5847                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5848                 .dac_nids = alc882_dac_nids,
5849                 .dig_out_nid = ALC882_DIGOUT_NID,
5850                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5851                 .adc_nids = alc882_adc_nids,
5852                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5853                 .channel_mode = alc882_3ST_6ch_modes,
5854                 .need_dac_fix = 1,
5855                 .input_mux = &alc882_capture_source,
5856                 .unsol_event = alc882_targa_unsol_event,
5857                 .init_hook = alc882_targa_automute,
5858         },
5859         [ALC882_ASUS_A7J] = {
5860                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5861                             alc882_capture_mixer },
5862                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5863                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5864                 .dac_nids = alc882_dac_nids,
5865                 .dig_out_nid = ALC882_DIGOUT_NID,
5866                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5867                 .adc_nids = alc882_adc_nids,
5868                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5869                 .channel_mode = alc882_3ST_6ch_modes,
5870                 .need_dac_fix = 1,
5871                 .input_mux = &alc882_capture_source,
5872         },      
5873         [ALC882_ASUS_A7M] = {
5874                 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5875                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5876                                 alc880_gpio1_init_verbs,
5877                                 alc882_asus_a7m_verbs },
5878                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5879                 .dac_nids = alc882_dac_nids,
5880                 .dig_out_nid = ALC882_DIGOUT_NID,
5881                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5882                 .channel_mode = alc880_threestack_modes,
5883                 .need_dac_fix = 1,
5884                 .input_mux = &alc882_capture_source,
5885         },      
5886 };
5887
5888
5889 /*
5890  * Pin config fixes
5891  */
5892 enum { 
5893         PINFIX_ABIT_AW9D_MAX
5894 };
5895
5896 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5897         { 0x15, 0x01080104 }, /* side */
5898         { 0x16, 0x01011012 }, /* rear */
5899         { 0x17, 0x01016011 }, /* clfe */
5900         { }
5901 };
5902
5903 static const struct alc_pincfg *alc882_pin_fixes[] = {
5904         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5905 };
5906
5907 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5908         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5909         {}
5910 };
5911
5912 /*
5913  * BIOS auto configuration
5914  */
5915 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5916                                               hda_nid_t nid, int pin_type,
5917                                               int dac_idx)
5918 {
5919         /* set as output */
5920         struct alc_spec *spec = codec->spec;
5921         int idx;
5922
5923         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5924                 idx = 4;
5925         else
5926                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5927
5928         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5929                             pin_type);
5930         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5931                             AMP_OUT_UNMUTE);
5932         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5933
5934 }
5935
5936 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5937 {
5938         struct alc_spec *spec = codec->spec;
5939         int i;
5940
5941         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5942         for (i = 0; i <= HDA_SIDE; i++) {
5943                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5944                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5945                 if (nid)
5946                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5947                                                           i);
5948         }
5949 }
5950
5951 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5952 {
5953         struct alc_spec *spec = codec->spec;
5954         hda_nid_t pin;
5955
5956         pin = spec->autocfg.hp_pins[0];
5957         if (pin) /* connect to front */
5958                 /* use dac 0 */
5959                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5960 }
5961
5962 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5963 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5964
5965 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5966 {
5967         struct alc_spec *spec = codec->spec;
5968         int i;
5969
5970         for (i = 0; i < AUTO_PIN_LAST; i++) {
5971                 hda_nid_t nid = spec->autocfg.input_pins[i];
5972                 if (alc882_is_input_pin(nid)) {
5973                         snd_hda_codec_write(codec, nid, 0,
5974                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5975                                             i <= AUTO_PIN_FRONT_MIC ?
5976                                             PIN_VREF80 : PIN_IN);
5977                         if (nid != ALC882_PIN_CD_NID)
5978                                 snd_hda_codec_write(codec, nid, 0,
5979                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5980                                                     AMP_OUT_MUTE);
5981                 }
5982         }
5983 }
5984
5985 /* add mic boosts if needed */
5986 static int alc_auto_add_mic_boost(struct hda_codec *codec)
5987 {
5988         struct alc_spec *spec = codec->spec;
5989         int err;
5990         hda_nid_t nid;
5991
5992         nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
5993         if (nid) {
5994                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
5995                                   "Mic Boost",
5996                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
5997                 if (err < 0)
5998                         return err;
5999         }
6000         nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6001         if (nid) {
6002                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6003                                   "Front Mic Boost",
6004                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6005                 if (err < 0)
6006                         return err;
6007         }
6008         return 0;
6009 }
6010
6011 /* almost identical with ALC880 parser... */
6012 static int alc882_parse_auto_config(struct hda_codec *codec)
6013 {
6014         struct alc_spec *spec = codec->spec;
6015         int err = alc880_parse_auto_config(codec);
6016
6017         if (err < 0)
6018                 return err;
6019         else if (!err)
6020                 return 0; /* no config found */
6021
6022         err = alc_auto_add_mic_boost(codec);
6023         if (err < 0)
6024                 return err;
6025
6026         /* hack - override the init verbs */
6027         spec->init_verbs[0] = alc882_auto_init_verbs;
6028
6029         return 1; /* config found */
6030 }
6031
6032 /* additional initialization for auto-configuration model */
6033 static void alc882_auto_init(struct hda_codec *codec)
6034 {
6035         alc882_auto_init_multi_out(codec);
6036         alc882_auto_init_hp_out(codec);
6037         alc882_auto_init_analog_input(codec);
6038 }
6039
6040 static int patch_alc882(struct hda_codec *codec)
6041 {
6042         struct alc_spec *spec;
6043         int err, board_config;
6044
6045         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6046         if (spec == NULL)
6047                 return -ENOMEM;
6048
6049         codec->spec = spec;
6050
6051         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6052                                                   alc882_models,
6053                                                   alc882_cfg_tbl);
6054
6055         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6056                 /* Pick up systems that don't supply PCI SSID */
6057                 switch (codec->subsystem_id) {
6058                 case 0x106b0c00: /* Mac Pro */
6059                         board_config = ALC885_MACPRO;
6060                         break;
6061                 case 0x106b1000: /* iMac 24 */
6062                         board_config = ALC885_IMAC24;
6063                         break;
6064                 case 0x106b2c00: /* Macbook Pro rev3 */
6065                         board_config = ALC885_MBP3;
6066                         break;
6067                 default:
6068                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6069                                          "trying auto-probe from BIOS...\n");
6070                         board_config = ALC882_AUTO;
6071                 }
6072         }
6073
6074         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6075
6076         if (board_config == ALC882_AUTO) {
6077                 /* automatic parse from the BIOS config */
6078                 err = alc882_parse_auto_config(codec);
6079                 if (err < 0) {
6080                         alc_free(codec);
6081                         return err;
6082                 } else if (!err) {
6083                         printk(KERN_INFO
6084                                "hda_codec: Cannot set up configuration "
6085                                "from BIOS.  Using base mode...\n");
6086                         board_config = ALC882_3ST_DIG;
6087                 }
6088         }
6089
6090         if (board_config != ALC882_AUTO)
6091                 setup_preset(spec, &alc882_presets[board_config]);
6092
6093         spec->stream_name_analog = "ALC882 Analog";
6094         spec->stream_analog_playback = &alc882_pcm_analog_playback;
6095         spec->stream_analog_capture = &alc882_pcm_analog_capture;
6096
6097         spec->stream_name_digital = "ALC882 Digital";
6098         spec->stream_digital_playback = &alc882_pcm_digital_playback;
6099         spec->stream_digital_capture = &alc882_pcm_digital_capture;
6100
6101         if (!spec->adc_nids && spec->input_mux) {
6102                 /* check whether NID 0x07 is valid */
6103                 unsigned int wcap = get_wcaps(codec, 0x07);
6104                 /* get type */
6105                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6106                 if (wcap != AC_WID_AUD_IN) {
6107                         spec->adc_nids = alc882_adc_nids_alt;
6108                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6109                         spec->mixers[spec->num_mixers] =
6110                                 alc882_capture_alt_mixer;
6111                         spec->num_mixers++;
6112                 } else {
6113                         spec->adc_nids = alc882_adc_nids;
6114                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6115                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6116                         spec->num_mixers++;
6117                 }
6118         }
6119
6120         codec->patch_ops = alc_patch_ops;
6121         if (board_config == ALC882_AUTO)
6122                 spec->init_hook = alc882_auto_init;
6123 #ifdef CONFIG_SND_HDA_POWER_SAVE
6124         if (!spec->loopback.amplist)
6125                 spec->loopback.amplist = alc882_loopbacks;
6126 #endif
6127
6128         return 0;
6129 }
6130
6131 /*
6132  * ALC883 support
6133  *
6134  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6135  * configuration.  Each pin widget can choose any input DACs and a mixer.
6136  * Each ADC is connected from a mixer of all inputs.  This makes possible
6137  * 6-channel independent captures.
6138  *
6139  * In addition, an independent DAC for the multi-playback (not used in this
6140  * driver yet).
6141  */
6142 #define ALC883_DIGOUT_NID       0x06
6143 #define ALC883_DIGIN_NID        0x0a
6144
6145 static hda_nid_t alc883_dac_nids[4] = {
6146         /* front, rear, clfe, rear_surr */
6147         0x02, 0x04, 0x03, 0x05
6148 };
6149
6150 static hda_nid_t alc883_adc_nids[2] = {
6151         /* ADC1-2 */
6152         0x08, 0x09,
6153 };
6154
6155 /* input MUX */
6156 /* FIXME: should be a matrix-type input source selection */
6157
6158 static struct hda_input_mux alc883_capture_source = {
6159         .num_items = 4,
6160         .items = {
6161                 { "Mic", 0x0 },
6162                 { "Front Mic", 0x1 },
6163                 { "Line", 0x2 },
6164                 { "CD", 0x4 },
6165         },
6166 };
6167
6168 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6169         .num_items = 2,
6170         .items = {
6171                 { "Mic", 0x1 },
6172                 { "Line", 0x2 },
6173         },
6174 };
6175
6176 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6177         .num_items = 4,
6178         .items = {
6179                 { "Mic", 0x0 },
6180                 { "iMic", 0x1 },
6181                 { "Line", 0x2 },
6182                 { "CD", 0x4 },
6183         },
6184 };
6185
6186 #define alc883_mux_enum_info alc_mux_enum_info
6187 #define alc883_mux_enum_get alc_mux_enum_get
6188
6189 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6190                                struct snd_ctl_elem_value *ucontrol)
6191 {
6192         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6193         struct alc_spec *spec = codec->spec;
6194         const struct hda_input_mux *imux = spec->input_mux;
6195         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6196         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6197         hda_nid_t nid = capture_mixers[adc_idx];
6198         unsigned int *cur_val = &spec->cur_mux[adc_idx];
6199         unsigned int i, idx;
6200
6201         idx = ucontrol->value.enumerated.item[0];
6202         if (idx >= imux->num_items)
6203                 idx = imux->num_items - 1;
6204         if (*cur_val == idx)
6205                 return 0;
6206         for (i = 0; i < imux->num_items; i++) {
6207                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6208                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6209                                          imux->items[i].index,
6210                                          HDA_AMP_MUTE, v);
6211         }
6212         *cur_val = idx;
6213         return 1;
6214 }
6215
6216 /*
6217  * 2ch mode
6218  */
6219 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6220         { 2, NULL }
6221 };
6222
6223 /*
6224  * 2ch mode
6225  */
6226 static struct hda_verb alc883_3ST_ch2_init[] = {
6227         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6228         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6229         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6230         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6231         { } /* end */
6232 };
6233
6234 /*
6235  * 4ch mode
6236  */
6237 static struct hda_verb alc883_3ST_ch4_init[] = {
6238         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6239         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6240         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6241         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6242         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6243         { } /* end */
6244 };
6245
6246 /*
6247  * 6ch mode
6248  */
6249 static struct hda_verb alc883_3ST_ch6_init[] = {
6250         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6251         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6252         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6253         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6254         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6255         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6256         { } /* end */
6257 };
6258
6259 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6260         { 2, alc883_3ST_ch2_init },
6261         { 4, alc883_3ST_ch4_init },
6262         { 6, alc883_3ST_ch6_init },
6263 };
6264
6265 /*
6266  * 6ch mode
6267  */
6268 static struct hda_verb alc883_sixstack_ch6_init[] = {
6269         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6270         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6271         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6272         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6273         { } /* end */
6274 };
6275
6276 /*
6277  * 8ch mode
6278  */
6279 static struct hda_verb alc883_sixstack_ch8_init[] = {
6280         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6281         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6282         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6283         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6284         { } /* end */
6285 };
6286
6287 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6288         { 6, alc883_sixstack_ch6_init },
6289         { 8, alc883_sixstack_ch8_init },
6290 };
6291
6292 static struct hda_verb alc883_medion_eapd_verbs[] = {
6293         /* eanable EAPD on medion laptop */
6294         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6295         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6296         { }
6297 };
6298
6299 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6300  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6301  */
6302
6303 static struct snd_kcontrol_new alc883_base_mixer[] = {
6304         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6305         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6306         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6307         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6308         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6309         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6310         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6311         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6312         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6313         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6314         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6315         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6316         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6317         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6318         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6319         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6320         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6321         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6322         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6323         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6324         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6325         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6326         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6327         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6328         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6329         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6330         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6331         {
6332                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6333                 /* .name = "Capture Source", */
6334                 .name = "Input Source",
6335                 .count = 2,
6336                 .info = alc883_mux_enum_info,
6337                 .get = alc883_mux_enum_get,
6338                 .put = alc883_mux_enum_put,
6339         },
6340         { } /* end */
6341 };
6342
6343 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6344         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6345         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6346         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6347         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6348         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6349         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6350         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6351         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6352         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6353         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6354         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6355         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6356         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6357         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6358         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6359         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6360         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6361         {
6362                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6363                 /* .name = "Capture Source", */
6364                 .name = "Input Source",
6365                 .count = 2,
6366                 .info = alc883_mux_enum_info,
6367                 .get = alc883_mux_enum_get,
6368                 .put = alc883_mux_enum_put,
6369         },
6370         { } /* end */
6371 };
6372
6373 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6374         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6375         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6376         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6377         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6378         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6379         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6380         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6381         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6382         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6383         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6384         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6385         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6386         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6387         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6388         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6389         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6390         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6391         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6392         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6393         {
6394                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6395                 /* .name = "Capture Source", */
6396                 .name = "Input Source",
6397                 .count = 2,
6398                 .info = alc883_mux_enum_info,
6399                 .get = alc883_mux_enum_get,
6400                 .put = alc883_mux_enum_put,
6401         },
6402         { } /* end */
6403 };
6404
6405 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6406         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6407         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6408         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6409         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6410         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6411         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6412         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6413         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6414         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6415         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6416         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6417         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6418         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6419         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6420         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6421         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6422         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6423         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6424         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6425         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6426         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6427         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6428         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6429         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6430         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6431         {
6432                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6433                 /* .name = "Capture Source", */
6434                 .name = "Input Source",
6435                 .count = 2,
6436                 .info = alc883_mux_enum_info,
6437                 .get = alc883_mux_enum_get,
6438                 .put = alc883_mux_enum_put,
6439         },
6440         { } /* end */
6441 };
6442
6443 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6444         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6445         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6446         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6447         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6448         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6449         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6450         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6451         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6452         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6453         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6454         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6455         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6456         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6457         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6458         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6459         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6460         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6461         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6462         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6463         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6464         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6465         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6466         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6467
6468         {
6469                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6470                 /* .name = "Capture Source", */
6471                 .name = "Input Source",
6472                 .count = 1,
6473                 .info = alc883_mux_enum_info,
6474                 .get = alc883_mux_enum_get,
6475                 .put = alc883_mux_enum_put,
6476         },
6477         { } /* end */
6478 };
6479
6480 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6481         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6482         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6483         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6484         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6485         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6486         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6487         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6488         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6489         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6490         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6491         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6492         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6493         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6494         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6495         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6496         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6497         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6498         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6499         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6500         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6501         {
6502                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6503                 /* .name = "Capture Source", */
6504                 .name = "Input Source",
6505                 .count = 2,
6506                 .info = alc883_mux_enum_info,
6507                 .get = alc883_mux_enum_get,
6508                 .put = alc883_mux_enum_put,
6509         },
6510         { } /* end */
6511 };
6512
6513 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6514         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6515         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6516         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6517         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6518         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6519         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6520         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6521         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6522         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6523         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6524         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6525         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6526         {
6527                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6528                 /* .name = "Capture Source", */
6529                 .name = "Input Source",
6530                 .count = 2,
6531                 .info = alc883_mux_enum_info,
6532                 .get = alc883_mux_enum_get,
6533                 .put = alc883_mux_enum_put,
6534         },
6535         { } /* end */
6536 };
6537
6538 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6539         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6540         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6541         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6542         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6543         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6544         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6545         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6546         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6547         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6548         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6549         {
6550                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6551                 /* .name = "Capture Source", */
6552                 .name = "Input Source",
6553                 .count = 1,
6554                 .info = alc883_mux_enum_info,
6555                 .get = alc883_mux_enum_get,
6556                 .put = alc883_mux_enum_put,
6557         },
6558         { } /* end */
6559 };
6560
6561 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6562         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6563         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6564         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6565         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6566         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6567         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6568         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6569         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6570         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
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                 /* .name = "Capture Source", */
6578                 .name = "Input Source",
6579                 .count = 2,
6580                 .info = alc883_mux_enum_info,
6581                 .get = alc883_mux_enum_get,
6582                 .put = alc883_mux_enum_put,
6583         },
6584         { } /* end */
6585 };
6586
6587 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6588         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6589         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6590         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6591         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6592         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6593         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6594         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6595         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6596         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6597         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6598         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6599         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6600         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6601         {
6602                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6603                 /* .name = "Capture Source", */
6604                 .name = "Input Source",
6605                 .count = 2,
6606                 .info = alc883_mux_enum_info,
6607                 .get = alc883_mux_enum_get,
6608                 .put = alc883_mux_enum_put,
6609         },
6610         { } /* end */
6611 };      
6612
6613 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6614         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6615         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6616         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6617         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6618         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6619         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6620         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6621         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6622         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6623         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6624         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6625         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6626         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6627         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6628         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6629         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6630         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6631         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6632         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6633         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6634         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6635         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6636         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6637         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6638         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6639         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6640         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6641         {
6642                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6643                 /* .name = "Capture Source", */
6644                 .name = "Input Source",
6645                 .count = 2,
6646                 .info = alc883_mux_enum_info,
6647                 .get = alc883_mux_enum_get,
6648                 .put = alc883_mux_enum_put,
6649         },
6650         { } /* end */
6651 };
6652
6653 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6654         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6655         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6656         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6657         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6658         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6659         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6660         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6661         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6662         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6663         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6664         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6665         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6666         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6667         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6668         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6669         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6670         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6671         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6672         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6673         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6674         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6675         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6676         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6677         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6678         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6679         {
6680                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6681                 /* .name = "Capture Source", */
6682                 .name = "Input Source",
6683                 .count = 2,
6684                 .info = alc883_mux_enum_info,
6685                 .get = alc883_mux_enum_get,
6686                 .put = alc883_mux_enum_put,
6687         },
6688         { } /* end */
6689 };
6690
6691 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6692         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6693         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6694         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6695         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6696         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6697         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6698         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6699         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6700         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6701         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6702         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6703         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6704         {
6705                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6706                 /* .name = "Capture Source", */
6707                 .name = "Input Source",
6708                 .count = 2,
6709                 .info = alc883_mux_enum_info,
6710                 .get = alc883_mux_enum_get,
6711                 .put = alc883_mux_enum_put,
6712         },
6713         { } /* end */
6714 };
6715
6716 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6717         {
6718                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6719                 .name = "Channel Mode",
6720                 .info = alc_ch_mode_info,
6721                 .get = alc_ch_mode_get,
6722                 .put = alc_ch_mode_put,
6723         },
6724         { } /* end */
6725 };
6726
6727 static struct hda_verb alc883_init_verbs[] = {
6728         /* ADC1: mute amp left and right */
6729         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6730         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6731         /* ADC2: mute amp left and right */
6732         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6733         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6734         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6735         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6736         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6737         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6738         /* Rear mixer */
6739         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6740         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6741         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6742         /* CLFE mixer */
6743         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6744         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6745         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6746         /* Side mixer */
6747         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6748         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6749         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6750
6751         /* mute analog input loopbacks */
6752         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6753         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6754         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6755         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6756         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6757
6758         /* Front Pin: output 0 (0x0c) */
6759         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6760         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6761         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6762         /* Rear Pin: output 1 (0x0d) */
6763         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6764         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6765         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6766         /* CLFE Pin: output 2 (0x0e) */
6767         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6768         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6769         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6770         /* Side Pin: output 3 (0x0f) */
6771         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6772         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6773         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6774         /* Mic (rear) pin: input vref at 80% */
6775         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6776         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6777         /* Front Mic pin: input vref at 80% */
6778         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6779         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6780         /* Line In pin: input */
6781         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6782         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6783         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6784         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6785         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6786         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6787         /* CD pin widget for input */
6788         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6789
6790         /* FIXME: use matrix-type input source selection */
6791         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6792         /* Input mixer2 */
6793         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6794         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6795         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6796         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6797         /* Input mixer3 */
6798         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6799         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6800         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6801         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6802         { }
6803 };
6804
6805 /* toggle speaker-output according to the hp-jack state */
6806 static void alc883_mitac_hp_automute(struct hda_codec *codec)
6807 {
6808         unsigned int present;
6809
6810         present = snd_hda_codec_read(codec, 0x15, 0,
6811                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6812         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6813                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6814         snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
6815                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6816 }
6817
6818 /* auto-toggle front mic */
6819 /*
6820 static void alc883_mitac_mic_automute(struct hda_codec *codec)
6821 {
6822         unsigned int present;
6823         unsigned char bits;
6824
6825         present = snd_hda_codec_read(codec, 0x18, 0,
6826                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6827         bits = present ? HDA_AMP_MUTE : 0;
6828         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
6829 }
6830 */
6831
6832 static void alc883_mitac_automute(struct hda_codec *codec)
6833 {
6834         alc883_mitac_hp_automute(codec);
6835         /* alc883_mitac_mic_automute(codec); */
6836 }
6837
6838 static void alc883_mitac_unsol_event(struct hda_codec *codec,
6839                                            unsigned int res)
6840 {
6841         switch (res >> 26) {
6842         case ALC880_HP_EVENT:
6843                 alc883_mitac_hp_automute(codec);
6844                 break;
6845         case ALC880_MIC_EVENT:
6846                 /* alc883_mitac_mic_automute(codec); */
6847                 break;
6848         }
6849 }
6850
6851 static struct hda_verb alc883_mitac_verbs[] = {
6852         /* HP */
6853         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6854         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6855         /* Subwoofer */
6856         {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
6857         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6858
6859         /* enable unsolicited event */
6860         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6861         /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
6862
6863         { } /* end */
6864 };
6865
6866 static struct hda_verb alc883_tagra_verbs[] = {
6867         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6868         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6869
6870         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6871         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6872         
6873         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6874         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6875         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6876
6877         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6878         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6879         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6880         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6881
6882         { } /* end */
6883 };
6884
6885 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6886         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6887         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6888         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6889         { } /* end */
6890 };
6891
6892 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6893         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6894         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6895         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6896         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6897         { } /* end */
6898 };
6899
6900 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6901         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6902         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6903         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6904         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6905         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6906         { } /* end */
6907 };
6908
6909 static struct hda_verb alc883_haier_w66_verbs[] = {
6910         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6911         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6912
6913         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6914
6915         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6916         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6917         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6918         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6919         { } /* end */
6920 };
6921
6922 static struct hda_verb alc888_6st_hp_verbs[] = {
6923         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6924         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6925         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6926         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6927         { }
6928 };
6929
6930 static struct hda_verb alc888_3st_hp_verbs[] = {
6931         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6932         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6933         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6934         { }
6935 };
6936
6937 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6938         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6939         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6940         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6941         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6942         { }
6943 };
6944
6945 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6946         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6947         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6948         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6949         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6950         { }
6951 };
6952
6953 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6954         { 2, alc888_3st_hp_2ch_init },
6955         { 6, alc888_3st_hp_6ch_init },
6956 };
6957
6958 /* toggle front-jack and RCA according to the hp-jack state */
6959 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6960 {
6961         unsigned int present;
6962  
6963         present = snd_hda_codec_read(codec, 0x1b, 0,
6964                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6965         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6966                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6967         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6968                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6969 }
6970
6971 /* toggle RCA according to the front-jack state */
6972 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6973 {
6974         unsigned int present;
6975  
6976         present = snd_hda_codec_read(codec, 0x14, 0,
6977                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6978         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6979                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6980 }
6981
6982 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6983                                              unsigned int res)
6984 {
6985         if ((res >> 26) == ALC880_HP_EVENT)
6986                 alc888_lenovo_ms7195_front_automute(codec);
6987         if ((res >> 26) == ALC880_FRONT_EVENT)
6988                 alc888_lenovo_ms7195_rca_automute(codec);
6989 }
6990
6991 static struct hda_verb alc883_medion_md2_verbs[] = {
6992         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6993         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6994
6995         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6996
6997         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6998         { } /* end */
6999 };
7000
7001 /* toggle speaker-output according to the hp-jack state */
7002 static void alc883_medion_md2_automute(struct hda_codec *codec)
7003 {
7004         unsigned int present;
7005  
7006         present = snd_hda_codec_read(codec, 0x14, 0,
7007                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7008         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7009                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7010 }
7011
7012 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7013                                           unsigned int res)
7014 {
7015         if ((res >> 26) == ALC880_HP_EVENT)
7016                 alc883_medion_md2_automute(codec);
7017 }
7018
7019 /* toggle speaker-output according to the hp-jack state */
7020 static void alc883_tagra_automute(struct hda_codec *codec)
7021 {
7022         unsigned int present;
7023         unsigned char bits;
7024
7025         present = snd_hda_codec_read(codec, 0x14, 0,
7026                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7027         bits = present ? HDA_AMP_MUTE : 0;
7028         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7029                                  HDA_AMP_MUTE, bits);
7030         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7031                                   present ? 1 : 3);
7032 }
7033
7034 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7035 {
7036         if ((res >> 26) == ALC880_HP_EVENT)
7037                 alc883_tagra_automute(codec);
7038 }
7039
7040 static void alc883_haier_w66_automute(struct hda_codec *codec)
7041 {
7042         unsigned int present;
7043         unsigned char bits;
7044
7045         present = snd_hda_codec_read(codec, 0x1b, 0,
7046                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7047         bits = present ? 0x80 : 0;
7048         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7049                                  0x80, bits);
7050 }
7051
7052 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7053                                          unsigned int res)
7054 {
7055         if ((res >> 26) == ALC880_HP_EVENT)
7056                 alc883_haier_w66_automute(codec);
7057 }
7058
7059 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7060 {
7061         unsigned int present;
7062         unsigned char bits;
7063
7064         present = snd_hda_codec_read(codec, 0x14, 0,
7065                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7066         bits = present ? HDA_AMP_MUTE : 0;
7067         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7068                                  HDA_AMP_MUTE, bits);
7069 }
7070
7071 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7072 {
7073         unsigned int present;
7074         unsigned char bits;
7075
7076         present = snd_hda_codec_read(codec, 0x1b, 0,
7077                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7078         bits = present ? HDA_AMP_MUTE : 0;
7079         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7080                                  HDA_AMP_MUTE, bits);
7081         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7082                                  HDA_AMP_MUTE, bits);
7083 }
7084
7085 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7086                                            unsigned int res)
7087 {
7088         if ((res >> 26) == ALC880_HP_EVENT)
7089                 alc883_lenovo_101e_all_automute(codec);
7090         if ((res >> 26) == ALC880_FRONT_EVENT)
7091                 alc883_lenovo_101e_ispeaker_automute(codec);
7092 }
7093
7094 /* toggle speaker-output according to the hp-jack state */
7095 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7096 {
7097         unsigned int present;
7098  
7099         present = snd_hda_codec_read(codec, 0x14, 0,
7100                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7101         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7102                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7103         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7104                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7105 }
7106
7107 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7108                                            unsigned int res)
7109 {
7110         if ((res >> 26) == ALC880_HP_EVENT)
7111                 alc883_acer_aspire_automute(codec);
7112 }
7113
7114 static struct hda_verb alc883_acer_eapd_verbs[] = {
7115         /* HP Pin: output 0 (0x0c) */
7116         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7117         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7118         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7119         /* Front Pin: output 0 (0x0c) */
7120         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7121         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7122         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7123         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7124         /* eanable EAPD on medion laptop */
7125         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7126         {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7127         /* enable unsolicited event */
7128         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7129         { }
7130 };
7131
7132 /*
7133  * generic initialization of ADC, input mixers and output mixers
7134  */
7135 static struct hda_verb alc883_auto_init_verbs[] = {
7136         /*
7137          * Unmute ADC0-2 and set the default input to mic-in
7138          */
7139         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7140         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7141         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7142         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7143
7144         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7145          * mixer widget
7146          * Note: PASD motherboards uses the Line In 2 as the input for
7147          * front panel mic (mic 2)
7148          */
7149         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7150         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7151         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7152         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7153         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7154         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7155
7156         /*
7157          * Set up output mixers (0x0c - 0x0f)
7158          */
7159         /* set vol=0 to output mixers */
7160         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7161         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7162         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7163         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7164         /* set up input amps for analog loopback */
7165         /* Amp Indices: DAC = 0, mixer = 1 */
7166         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7167         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7168         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7169         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7170         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7171         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7172         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7173         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7174         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7175         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7176
7177         /* FIXME: use matrix-type input source selection */
7178         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7179         /* Input mixer1 */
7180         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7181         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7182         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7183         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7184         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7185         /* Input mixer2 */
7186         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7187         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7188         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7189         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7190         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7191
7192         { }
7193 };
7194
7195 /* capture mixer elements */
7196 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7197         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7198         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7199         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7200         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7201         {
7202                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7203                 /* The multiple "Capture Source" controls confuse alsamixer
7204                  * So call somewhat different..
7205                  * FIXME: the controls appear in the "playback" view!
7206                  */
7207                 /* .name = "Capture Source", */
7208                 .name = "Input Source",
7209                 .count = 2,
7210                 .info = alc882_mux_enum_info,
7211                 .get = alc882_mux_enum_get,
7212                 .put = alc882_mux_enum_put,
7213         },
7214         { } /* end */
7215 };
7216
7217 #ifdef CONFIG_SND_HDA_POWER_SAVE
7218 #define alc883_loopbacks        alc880_loopbacks
7219 #endif
7220
7221 /* pcm configuration: identiacal with ALC880 */
7222 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
7223 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
7224 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
7225 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
7226
7227 /*
7228  * configuration and preset
7229  */
7230 static const char *alc883_models[ALC883_MODEL_LAST] = {
7231         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
7232         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
7233         [ALC883_3ST_6ch]        = "3stack-6ch",
7234         [ALC883_6ST_DIG]        = "6stack-dig",
7235         [ALC883_TARGA_DIG]      = "targa-dig",
7236         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
7237         [ALC883_ACER]           = "acer",
7238         [ALC883_ACER_ASPIRE]    = "acer-aspire",
7239         [ALC883_MEDION]         = "medion",
7240         [ALC883_MEDION_MD2]     = "medion-md2",
7241         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
7242         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7243         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
7244         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7245         [ALC883_HAIER_W66]      = "haier-w66",
7246         [ALC888_6ST_HP]         = "6stack-hp",
7247         [ALC888_3ST_HP]         = "3stack-hp",
7248         [ALC883_MITAC]          = "mitac",
7249         [ALC883_AUTO]           = "auto",
7250 };
7251
7252 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7253         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7254         SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7255         SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7256         SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7257         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7258         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7259         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7260         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7261         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7262         SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7263         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7264         SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7265         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7266         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7267         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7268         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7269         SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7270         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7271         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7272         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7273         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7274         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7275         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7276         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7277         SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7278         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7279         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7280         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7281         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7282         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7283         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7284         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7285         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7286         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7287         SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7288         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7289         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7290         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7291         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7292         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7293         SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7294         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7295         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7296         SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7297         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7298         {}
7299 };
7300
7301 static struct alc_config_preset alc883_presets[] = {
7302         [ALC883_3ST_2ch_DIG] = {
7303                 .mixers = { alc883_3ST_2ch_mixer },
7304                 .init_verbs = { alc883_init_verbs },
7305                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7306                 .dac_nids = alc883_dac_nids,
7307                 .dig_out_nid = ALC883_DIGOUT_NID,
7308                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7309                 .adc_nids = alc883_adc_nids,
7310                 .dig_in_nid = ALC883_DIGIN_NID,
7311                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7312                 .channel_mode = alc883_3ST_2ch_modes,
7313                 .input_mux = &alc883_capture_source,
7314         },
7315         [ALC883_3ST_6ch_DIG] = {
7316                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7317                 .init_verbs = { alc883_init_verbs },
7318                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7319                 .dac_nids = alc883_dac_nids,
7320                 .dig_out_nid = ALC883_DIGOUT_NID,
7321                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7322                 .adc_nids = alc883_adc_nids,
7323                 .dig_in_nid = ALC883_DIGIN_NID,
7324                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7325                 .channel_mode = alc883_3ST_6ch_modes,
7326                 .need_dac_fix = 1,
7327                 .input_mux = &alc883_capture_source,
7328         },
7329         [ALC883_3ST_6ch] = {
7330                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7331                 .init_verbs = { alc883_init_verbs },
7332                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7333                 .dac_nids = alc883_dac_nids,
7334                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7335                 .adc_nids = alc883_adc_nids,
7336                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7337                 .channel_mode = alc883_3ST_6ch_modes,
7338                 .need_dac_fix = 1,
7339                 .input_mux = &alc883_capture_source,
7340         },
7341         [ALC883_6ST_DIG] = {
7342                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7343                 .init_verbs = { alc883_init_verbs },
7344                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7345                 .dac_nids = alc883_dac_nids,
7346                 .dig_out_nid = ALC883_DIGOUT_NID,
7347                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7348                 .adc_nids = alc883_adc_nids,
7349                 .dig_in_nid = ALC883_DIGIN_NID,
7350                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7351                 .channel_mode = alc883_sixstack_modes,
7352                 .input_mux = &alc883_capture_source,
7353         },
7354         [ALC883_TARGA_DIG] = {
7355                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7356                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7357                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7358                 .dac_nids = alc883_dac_nids,
7359                 .dig_out_nid = ALC883_DIGOUT_NID,
7360                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7361                 .adc_nids = alc883_adc_nids,
7362                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7363                 .channel_mode = alc883_3ST_6ch_modes,
7364                 .need_dac_fix = 1,
7365                 .input_mux = &alc883_capture_source,
7366                 .unsol_event = alc883_tagra_unsol_event,
7367                 .init_hook = alc883_tagra_automute,
7368         },
7369         [ALC883_TARGA_2ch_DIG] = {
7370                 .mixers = { alc883_tagra_2ch_mixer},
7371                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7372                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7373                 .dac_nids = alc883_dac_nids,
7374                 .dig_out_nid = ALC883_DIGOUT_NID,
7375                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7376                 .adc_nids = alc883_adc_nids,
7377                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7378                 .channel_mode = alc883_3ST_2ch_modes,
7379                 .input_mux = &alc883_capture_source,
7380                 .unsol_event = alc883_tagra_unsol_event,
7381                 .init_hook = alc883_tagra_automute,
7382         },
7383         [ALC883_ACER] = {
7384                 .mixers = { alc883_base_mixer },
7385                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7386                  * and the headphone jack.  Turn this on and rely on the
7387                  * standard mute methods whenever the user wants to turn
7388                  * these outputs off.
7389                  */
7390                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7391                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7392                 .dac_nids = alc883_dac_nids,
7393                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7394                 .adc_nids = alc883_adc_nids,
7395                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7396                 .channel_mode = alc883_3ST_2ch_modes,
7397                 .input_mux = &alc883_capture_source,
7398         },
7399         [ALC883_ACER_ASPIRE] = {
7400                 .mixers = { alc883_acer_aspire_mixer },
7401                 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7402                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7403                 .dac_nids = alc883_dac_nids,
7404                 .dig_out_nid = ALC883_DIGOUT_NID,
7405                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7406                 .adc_nids = alc883_adc_nids,
7407                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7408                 .channel_mode = alc883_3ST_2ch_modes,
7409                 .input_mux = &alc883_capture_source,
7410                 .unsol_event = alc883_acer_aspire_unsol_event,
7411                 .init_hook = alc883_acer_aspire_automute,
7412         },
7413         [ALC883_MEDION] = {
7414                 .mixers = { alc883_fivestack_mixer,
7415                             alc883_chmode_mixer },
7416                 .init_verbs = { alc883_init_verbs,
7417                                 alc883_medion_eapd_verbs },
7418                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7419                 .dac_nids = alc883_dac_nids,
7420                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7421                 .adc_nids = alc883_adc_nids,
7422                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7423                 .channel_mode = alc883_sixstack_modes,
7424                 .input_mux = &alc883_capture_source,
7425         },
7426         [ALC883_MEDION_MD2] = {
7427                 .mixers = { alc883_medion_md2_mixer},
7428                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7429                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7430                 .dac_nids = alc883_dac_nids,
7431                 .dig_out_nid = ALC883_DIGOUT_NID,
7432                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7433                 .adc_nids = alc883_adc_nids,
7434                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7435                 .channel_mode = alc883_3ST_2ch_modes,
7436                 .input_mux = &alc883_capture_source,
7437                 .unsol_event = alc883_medion_md2_unsol_event,
7438                 .init_hook = alc883_medion_md2_automute,
7439         },      
7440         [ALC883_LAPTOP_EAPD] = {
7441                 .mixers = { alc883_base_mixer },
7442                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7443                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7444                 .dac_nids = alc883_dac_nids,
7445                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7446                 .adc_nids = alc883_adc_nids,
7447                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7448                 .channel_mode = alc883_3ST_2ch_modes,
7449                 .input_mux = &alc883_capture_source,
7450         },
7451         [ALC883_LENOVO_101E_2ch] = {
7452                 .mixers = { alc883_lenovo_101e_2ch_mixer},
7453                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7454                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7455                 .dac_nids = alc883_dac_nids,
7456                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7457                 .adc_nids = alc883_adc_nids,
7458                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7459                 .channel_mode = alc883_3ST_2ch_modes,
7460                 .input_mux = &alc883_lenovo_101e_capture_source,
7461                 .unsol_event = alc883_lenovo_101e_unsol_event,
7462                 .init_hook = alc883_lenovo_101e_all_automute,
7463         },
7464         [ALC883_LENOVO_NB0763] = {
7465                 .mixers = { alc883_lenovo_nb0763_mixer },
7466                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7467                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7468                 .dac_nids = alc883_dac_nids,
7469                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7470                 .adc_nids = alc883_adc_nids,
7471                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7472                 .channel_mode = alc883_3ST_2ch_modes,
7473                 .need_dac_fix = 1,
7474                 .input_mux = &alc883_lenovo_nb0763_capture_source,
7475                 .unsol_event = alc883_medion_md2_unsol_event,
7476                 .init_hook = alc883_medion_md2_automute,
7477         },
7478         [ALC888_LENOVO_MS7195_DIG] = {
7479                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7480                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7481                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7482                 .dac_nids = alc883_dac_nids,
7483                 .dig_out_nid = ALC883_DIGOUT_NID,
7484                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7485                 .adc_nids = alc883_adc_nids,
7486                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7487                 .channel_mode = alc883_3ST_6ch_modes,
7488                 .need_dac_fix = 1,
7489                 .input_mux = &alc883_capture_source,
7490                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7491                 .init_hook = alc888_lenovo_ms7195_front_automute,
7492         },
7493         [ALC883_HAIER_W66] = {
7494                 .mixers = { alc883_tagra_2ch_mixer},
7495                 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7496                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7497                 .dac_nids = alc883_dac_nids,
7498                 .dig_out_nid = ALC883_DIGOUT_NID,
7499                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7500                 .adc_nids = alc883_adc_nids,
7501                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7502                 .channel_mode = alc883_3ST_2ch_modes,
7503                 .input_mux = &alc883_capture_source,
7504                 .unsol_event = alc883_haier_w66_unsol_event,
7505                 .init_hook = alc883_haier_w66_automute,
7506         },      
7507         [ALC888_6ST_HP] = {
7508                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7509                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7510                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7511                 .dac_nids = alc883_dac_nids,
7512                 .dig_out_nid = ALC883_DIGOUT_NID,
7513                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7514                 .adc_nids = alc883_adc_nids,
7515                 .dig_in_nid = ALC883_DIGIN_NID,
7516                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7517                 .channel_mode = alc883_sixstack_modes,
7518                 .input_mux = &alc883_capture_source,
7519         },
7520         [ALC888_3ST_HP] = {
7521                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7522                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7523                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7524                 .dac_nids = alc883_dac_nids,
7525                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7526                 .adc_nids = alc883_adc_nids,
7527                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7528                 .channel_mode = alc888_3st_hp_modes,
7529                 .need_dac_fix = 1,
7530                 .input_mux = &alc883_capture_source,
7531         },
7532         [ALC883_MITAC] = {
7533                 .mixers = { alc883_mitac_mixer },
7534                 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7535                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7536                 .dac_nids = alc883_dac_nids,
7537                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7538                 .adc_nids = alc883_adc_nids,
7539                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7540                 .channel_mode = alc883_3ST_2ch_modes,
7541                 .input_mux = &alc883_capture_source,
7542                 .unsol_event = alc883_mitac_unsol_event,
7543                 .init_hook = alc883_mitac_automute,
7544         },
7545 };
7546
7547
7548 /*
7549  * BIOS auto configuration
7550  */
7551 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7552                                               hda_nid_t nid, int pin_type,
7553                                               int dac_idx)
7554 {
7555         /* set as output */
7556         struct alc_spec *spec = codec->spec;
7557         int idx;
7558
7559         if (spec->multiout.dac_nids[dac_idx] == 0x25)
7560                 idx = 4;
7561         else
7562                 idx = spec->multiout.dac_nids[dac_idx] - 2;
7563
7564         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7565                             pin_type);
7566         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7567                             AMP_OUT_UNMUTE);
7568         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7569
7570 }
7571
7572 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7573 {
7574         struct alc_spec *spec = codec->spec;
7575         int i;
7576
7577         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7578         for (i = 0; i <= HDA_SIDE; i++) {
7579                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7580                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7581                 if (nid)
7582                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7583                                                           i);
7584         }
7585 }
7586
7587 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7588 {
7589         struct alc_spec *spec = codec->spec;
7590         hda_nid_t pin;
7591
7592         pin = spec->autocfg.hp_pins[0];
7593         if (pin) /* connect to front */
7594                 /* use dac 0 */
7595                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7596 }
7597
7598 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
7599 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
7600
7601 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7602 {
7603         struct alc_spec *spec = codec->spec;
7604         int i;
7605
7606         for (i = 0; i < AUTO_PIN_LAST; i++) {
7607                 hda_nid_t nid = spec->autocfg.input_pins[i];
7608                 if (alc883_is_input_pin(nid)) {
7609                         snd_hda_codec_write(codec, nid, 0,
7610                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
7611                                             (i <= AUTO_PIN_FRONT_MIC ?
7612                                              PIN_VREF80 : PIN_IN));
7613                         if (nid != ALC883_PIN_CD_NID)
7614                                 snd_hda_codec_write(codec, nid, 0,
7615                                                     AC_VERB_SET_AMP_GAIN_MUTE,
7616                                                     AMP_OUT_MUTE);
7617                 }
7618         }
7619 }
7620
7621 /* almost identical with ALC880 parser... */
7622 static int alc883_parse_auto_config(struct hda_codec *codec)
7623 {
7624         struct alc_spec *spec = codec->spec;
7625         int err = alc880_parse_auto_config(codec);
7626
7627         if (err < 0)
7628                 return err;
7629         else if (!err)
7630                 return 0; /* no config found */
7631
7632         err = alc_auto_add_mic_boost(codec);
7633         if (err < 0)
7634                 return err;
7635
7636         /* hack - override the init verbs */
7637         spec->init_verbs[0] = alc883_auto_init_verbs;
7638         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7639         spec->num_mixers++;
7640
7641         return 1; /* config found */
7642 }
7643
7644 /* additional initialization for auto-configuration model */
7645 static void alc883_auto_init(struct hda_codec *codec)
7646 {
7647         alc883_auto_init_multi_out(codec);
7648         alc883_auto_init_hp_out(codec);
7649         alc883_auto_init_analog_input(codec);
7650 }
7651
7652 static int patch_alc883(struct hda_codec *codec)
7653 {
7654         struct alc_spec *spec;
7655         int err, board_config;
7656
7657         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7658         if (spec == NULL)
7659                 return -ENOMEM;
7660
7661         codec->spec = spec;
7662
7663         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7664                                                   alc883_models,
7665                                                   alc883_cfg_tbl);
7666         if (board_config < 0) {
7667                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7668                        "trying auto-probe from BIOS...\n");
7669                 board_config = ALC883_AUTO;
7670         }
7671
7672         if (board_config == ALC883_AUTO) {
7673                 /* automatic parse from the BIOS config */
7674                 err = alc883_parse_auto_config(codec);
7675                 if (err < 0) {
7676                         alc_free(codec);
7677                         return err;
7678                 } else if (!err) {
7679                         printk(KERN_INFO
7680                                "hda_codec: Cannot set up configuration "
7681                                "from BIOS.  Using base mode...\n");
7682                         board_config = ALC883_3ST_2ch_DIG;
7683                 }
7684         }
7685
7686         if (board_config != ALC883_AUTO)
7687                 setup_preset(spec, &alc883_presets[board_config]);
7688
7689         spec->stream_name_analog = "ALC883 Analog";
7690         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7691         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7692
7693         spec->stream_name_digital = "ALC883 Digital";
7694         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7695         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7696
7697         if (!spec->adc_nids && spec->input_mux) {
7698                 spec->adc_nids = alc883_adc_nids;
7699                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7700         }
7701
7702         codec->patch_ops = alc_patch_ops;
7703         if (board_config == ALC883_AUTO)
7704                 spec->init_hook = alc883_auto_init;
7705 #ifdef CONFIG_SND_HDA_POWER_SAVE
7706         if (!spec->loopback.amplist)
7707                 spec->loopback.amplist = alc883_loopbacks;
7708 #endif
7709
7710         return 0;
7711 }
7712
7713 /*
7714  * ALC262 support
7715  */
7716
7717 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7718 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7719
7720 #define alc262_dac_nids         alc260_dac_nids
7721 #define alc262_adc_nids         alc882_adc_nids
7722 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7723
7724 #define alc262_modes            alc260_modes
7725 #define alc262_capture_source   alc882_capture_source
7726
7727 static struct snd_kcontrol_new alc262_base_mixer[] = {
7728         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7729         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7730         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7731         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7732         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7733         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7734         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7735         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7736         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7737         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7738         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7739         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7740         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7741            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7742         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7743         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7744         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7745         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7746         { } /* end */
7747 };
7748
7749 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7750         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7751         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7752         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7753         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7754         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7755         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7756         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7757         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7758         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7759         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7760         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7761         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7762         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7763            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7764         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7765         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7766         { } /* end */
7767 };
7768
7769 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7770         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7771         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7772         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7773         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7774         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7775
7776         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7777         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7778         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7779         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7780         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7781         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7782         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7783         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7784         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7785         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7786         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7787         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7788         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7789         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7790         { } /* end */
7791 };
7792
7793 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7794         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7795         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7796         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7797         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7798         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7799         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7800         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7801         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7802         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7803         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7804         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7805         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7806         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7807         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7808         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7809         { } /* end */
7810 };
7811
7812 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7813         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7814         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7815         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7816         { } /* end */
7817 };
7818
7819 static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
7820         .ops = &snd_hda_bind_vol,
7821         .values = {
7822                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7823                 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7824                 0
7825         },
7826 };
7827
7828 static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
7829         .ops = &snd_hda_bind_sw,
7830         .values = {
7831                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7832                 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7833                 0
7834         },
7835 };
7836
7837 /* mute/unmute internal speaker according to the hp jack and mute state */
7838 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
7839 {
7840         struct alc_spec *spec = codec->spec;
7841         unsigned int mute;
7842
7843         if (force || !spec->sense_updated) {
7844                 unsigned int present;
7845                 present = snd_hda_codec_read(codec, 0x15, 0,
7846                                              AC_VERB_GET_PIN_SENSE, 0);
7847                 spec->jack_present = (present & 0x80000000) != 0;
7848                 spec->sense_updated = 1;
7849         }
7850         if (spec->jack_present)
7851                 mute = (0x7080 | ((0)<<8));  /* mute internal speaker */
7852         else    /* unmute internal speaker if necessary */
7853                 mute = (0x7000 | ((0)<<8));
7854         snd_hda_codec_write(codec, 0x0c, 0,
7855                             AC_VERB_SET_AMP_GAIN_MUTE, mute );
7856 }
7857
7858 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
7859                                         unsigned int res)
7860 {
7861         if ((res >> 26) != ALC880_HP_EVENT)
7862                 return;
7863         alc262_hp_t5735_automute(codec, 1);
7864 }
7865
7866 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
7867 {
7868         alc262_hp_t5735_automute(codec, 1);
7869 }
7870
7871 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
7872         HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
7873         HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
7874         HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7875         HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7876         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7877         HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7878         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7879         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7880         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7881         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7882         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7883         { } /* end */
7884 };
7885
7886 static struct hda_verb alc262_hp_t5735_verbs[] = {
7887         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7888         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7889
7890         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7891         { }
7892 };
7893
7894 /* bind hp and internal speaker mute (with plug check) */
7895 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7896                                      struct snd_ctl_elem_value *ucontrol)
7897 {
7898         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7899         long *valp = ucontrol->value.integer.value;
7900         int change;
7901
7902         /* change hp mute */
7903         change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7904                                           HDA_AMP_MUTE,
7905                                           valp[0] ? 0 : HDA_AMP_MUTE);
7906         change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7907                                            HDA_AMP_MUTE,
7908                                            valp[1] ? 0 : HDA_AMP_MUTE);
7909         if (change) {
7910                 /* change speaker according to HP jack state */
7911                 struct alc_spec *spec = codec->spec;
7912                 unsigned int mute;
7913                 if (spec->jack_present)
7914                         mute = HDA_AMP_MUTE;
7915                 else
7916                         mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7917                                                       HDA_OUTPUT, 0);
7918                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7919                                          HDA_AMP_MUTE, mute);
7920         }
7921         return change;
7922 }
7923
7924 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7925         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7926         {
7927                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7928                 .name = "Master Playback Switch",
7929                 .info = snd_hda_mixer_amp_switch_info,
7930                 .get = snd_hda_mixer_amp_switch_get,
7931                 .put = alc262_sony_master_sw_put,
7932                 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7933         },
7934         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7935         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7936         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7937         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7938         { } /* end */
7939 };
7940
7941 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7942         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7943         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7944         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7945         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7946         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7947         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7948         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7949         { } /* end */
7950 };
7951
7952 #define alc262_capture_mixer            alc882_capture_mixer
7953 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7954
7955 /*
7956  * generic initialization of ADC, input mixers and output mixers
7957  */
7958 static struct hda_verb alc262_init_verbs[] = {
7959         /*
7960          * Unmute ADC0-2 and set the default input to mic-in
7961          */
7962         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7963         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7964         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7965         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7966         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7967         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7968
7969         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7970          * mixer widget
7971          * Note: PASD motherboards uses the Line In 2 as the input for
7972          * front panel mic (mic 2)
7973          */
7974         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7975         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7976         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7977         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7978         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7979         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7980
7981         /*
7982          * Set up output mixers (0x0c - 0x0e)
7983          */
7984         /* set vol=0 to output mixers */
7985         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7986         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7987         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7988         /* set up input amps for analog loopback */
7989         /* Amp Indices: DAC = 0, mixer = 1 */
7990         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7991         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7992         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7993         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7994         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7995         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7996
7997         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7998         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7999         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8000         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8001         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8002         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8003
8004         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8005         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8006         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8007         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8008         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8009         
8010         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8011         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8012         
8013         /* FIXME: use matrix-type input source selection */
8014         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8015         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8016         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8017         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8018         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8019         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8020         /* Input mixer2 */
8021         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8022         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8023         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8024         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8025         /* Input mixer3 */
8026         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8027         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8028         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8029         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8030
8031         { }
8032 };
8033
8034 static struct hda_verb alc262_hippo_unsol_verbs[] = {
8035         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8036         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8037         {}
8038 };
8039
8040 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8041         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8042         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8043         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8044
8045         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8046         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8047         {}
8048 };
8049
8050 static struct hda_verb alc262_sony_unsol_verbs[] = {
8051         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8052         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8053         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
8054
8055         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8056         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8057 };
8058
8059 /* mute/unmute internal speaker according to the hp jack and mute state */
8060 static void alc262_hippo_automute(struct hda_codec *codec)
8061 {
8062         struct alc_spec *spec = codec->spec;
8063         unsigned int mute;
8064         unsigned int present;
8065
8066         /* need to execute and sync at first */
8067         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8068         present = snd_hda_codec_read(codec, 0x15, 0,
8069                                      AC_VERB_GET_PIN_SENSE, 0);
8070         spec->jack_present = (present & 0x80000000) != 0;
8071         if (spec->jack_present) {
8072                 /* mute internal speaker */
8073                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8074                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8075         } else {
8076                 /* unmute internal speaker if necessary */
8077                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8078                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8079                                          HDA_AMP_MUTE, mute);
8080         }
8081 }
8082
8083 /* unsolicited event for HP jack sensing */
8084 static void alc262_hippo_unsol_event(struct hda_codec *codec,
8085                                        unsigned int res)
8086 {
8087         if ((res >> 26) != ALC880_HP_EVENT)
8088                 return;
8089         alc262_hippo_automute(codec);
8090 }
8091
8092 static void alc262_hippo1_automute(struct hda_codec *codec)
8093 {
8094         unsigned int mute;
8095         unsigned int present;
8096
8097         snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8098         present = snd_hda_codec_read(codec, 0x1b, 0,
8099                                      AC_VERB_GET_PIN_SENSE, 0);
8100         present = (present & 0x80000000) != 0;
8101         if (present) {
8102                 /* mute internal speaker */
8103                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8104                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8105         } else {
8106                 /* unmute internal speaker if necessary */
8107                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8108                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8109                                          HDA_AMP_MUTE, mute);
8110         }
8111 }
8112
8113 /* unsolicited event for HP jack sensing */
8114 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8115                                        unsigned int res)
8116 {
8117         if ((res >> 26) != ALC880_HP_EVENT)
8118                 return;
8119         alc262_hippo1_automute(codec);
8120 }
8121
8122 /*
8123  * fujitsu model
8124  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
8125  */
8126
8127 #define ALC_HP_EVENT    0x37
8128
8129 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8130         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8131         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8132         {}
8133 };
8134
8135 static struct hda_input_mux alc262_fujitsu_capture_source = {
8136         .num_items = 3,
8137         .items = {
8138                 { "Mic", 0x0 },
8139                 { "Int Mic", 0x1 },
8140                 { "CD", 0x4 },
8141         },
8142 };
8143
8144 static struct hda_input_mux alc262_HP_capture_source = {
8145         .num_items = 5,
8146         .items = {
8147                 { "Mic", 0x0 },
8148                 { "Front Mic", 0x1 },
8149                 { "Line", 0x2 },
8150                 { "CD", 0x4 },
8151                 { "AUX IN", 0x6 },
8152         },
8153 };
8154
8155 static struct hda_input_mux alc262_HP_D7000_capture_source = {
8156         .num_items = 4,
8157         .items = {
8158                 { "Mic", 0x0 },
8159                 { "Front Mic", 0x2 },
8160                 { "Line", 0x1 },
8161                 { "CD", 0x4 },
8162         },
8163 };
8164
8165 /* mute/unmute internal speaker according to the hp jack and mute state */
8166 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8167 {
8168         struct alc_spec *spec = codec->spec;
8169         unsigned int mute;
8170
8171         if (force || !spec->sense_updated) {
8172                 unsigned int present;
8173                 /* need to execute and sync at first */
8174                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8175                 present = snd_hda_codec_read(codec, 0x14, 0,
8176                                          AC_VERB_GET_PIN_SENSE, 0);
8177                 spec->jack_present = (present & 0x80000000) != 0;
8178                 spec->sense_updated = 1;
8179         }
8180         if (spec->jack_present) {
8181                 /* mute internal speaker */
8182                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8183                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8184         } else {
8185                 /* unmute internal speaker if necessary */
8186                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8187                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8188                                          HDA_AMP_MUTE, mute);
8189         }
8190 }
8191
8192 /* unsolicited event for HP jack sensing */
8193 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8194                                        unsigned int res)
8195 {
8196         if ((res >> 26) != ALC_HP_EVENT)
8197                 return;
8198         alc262_fujitsu_automute(codec, 1);
8199 }
8200
8201 /* bind volumes of both NID 0x0c and 0x0d */
8202 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8203         .ops = &snd_hda_bind_vol,
8204         .values = {
8205                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8206                 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8207                 0
8208         },
8209 };
8210
8211 /* bind hp and internal speaker mute (with plug check) */
8212 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8213                                          struct snd_ctl_elem_value *ucontrol)
8214 {
8215         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8216         long *valp = ucontrol->value.integer.value;
8217         int change;
8218
8219         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8220                                           HDA_AMP_MUTE,
8221                                           valp[0] ? 0 : HDA_AMP_MUTE);
8222         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8223                                            HDA_AMP_MUTE,
8224                                            valp[1] ? 0 : HDA_AMP_MUTE);
8225         if (change)
8226                 alc262_fujitsu_automute(codec, 0);
8227         return change;
8228 }
8229
8230 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8231         HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8232         {
8233                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8234                 .name = "Master Playback Switch",
8235                 .info = snd_hda_mixer_amp_switch_info,
8236                 .get = snd_hda_mixer_amp_switch_get,
8237                 .put = alc262_fujitsu_master_sw_put,
8238                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8239         },
8240         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8241         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8242         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8243         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8244         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8245         HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8246         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8247         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8248         { } /* end */
8249 };
8250
8251 /* additional init verbs for Benq laptops */
8252 static struct hda_verb alc262_EAPD_verbs[] = {
8253         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8254         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
8255         {}
8256 };
8257
8258 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8259         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8260         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8261
8262         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8263         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
8264         {}
8265 };
8266
8267 /* Samsung Q1 Ultra Vista model setup */
8268 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8269         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8270         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8271         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8272         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8273         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8274         HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8275         { } /* end */
8276 };
8277
8278 static struct hda_verb alc262_ultra_verbs[] = {
8279         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8280         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8281         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8282         /* Mic is on Node 0x19 */
8283         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8284         {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8285         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8286         {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8287         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8288         {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8289         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8290         {}
8291 };
8292
8293 static struct hda_input_mux alc262_ultra_capture_source = {
8294         .num_items = 1,
8295         .items = {
8296                 { "Mic", 0x1 },
8297         },
8298 };
8299
8300 /* mute/unmute internal speaker according to the hp jack and mute state */
8301 static void alc262_ultra_automute(struct hda_codec *codec)
8302 {
8303         struct alc_spec *spec = codec->spec;
8304         unsigned int mute;
8305         unsigned int present;
8306
8307         /* need to execute and sync at first */
8308         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8309         present = snd_hda_codec_read(codec, 0x15, 0,
8310                                      AC_VERB_GET_PIN_SENSE, 0);
8311         spec->jack_present = (present & 0x80000000) != 0;
8312         if (spec->jack_present) {
8313                 /* mute internal speaker */
8314                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8315                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8316         } else {
8317                 /* unmute internal speaker if necessary */
8318                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8319                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8320                                          HDA_AMP_MUTE, mute);
8321         }
8322 }
8323
8324 /* unsolicited event for HP jack sensing */
8325 static void alc262_ultra_unsol_event(struct hda_codec *codec,
8326                                        unsigned int res)
8327 {
8328         if ((res >> 26) != ALC880_HP_EVENT)
8329                 return;
8330         alc262_ultra_automute(codec);
8331 }
8332
8333 /* add playback controls from the parsed DAC table */
8334 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8335                                              const struct auto_pin_cfg *cfg)
8336 {
8337         hda_nid_t nid;
8338         int err;
8339
8340         spec->multiout.num_dacs = 1;    /* only use one dac */
8341         spec->multiout.dac_nids = spec->private_dac_nids;
8342         spec->multiout.dac_nids[0] = 2;
8343
8344         nid = cfg->line_out_pins[0];
8345         if (nid) {
8346                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8347                                   "Front Playback Volume",
8348                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8349                 if (err < 0)
8350                         return err;
8351                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8352                                   "Front Playback Switch",
8353                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8354                 if (err < 0)
8355                         return err;
8356         }
8357
8358         nid = cfg->speaker_pins[0];
8359         if (nid) {
8360                 if (nid == 0x16) {
8361                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
8362                                           "Speaker Playback Volume",
8363                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8364                                                               HDA_OUTPUT));
8365                         if (err < 0)
8366                                 return err;
8367                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8368                                           "Speaker Playback Switch",
8369                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8370                                                               HDA_OUTPUT));
8371                         if (err < 0)
8372                                 return err;
8373                 } else {
8374                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8375                                           "Speaker Playback Switch",
8376                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8377                                                               HDA_OUTPUT));
8378                         if (err < 0)
8379                                 return err;
8380                 }
8381         }
8382         nid = cfg->hp_pins[0];
8383         if (nid) {
8384                 /* spec->multiout.hp_nid = 2; */
8385                 if (nid == 0x16) {
8386                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
8387                                           "Headphone Playback Volume",
8388                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8389                                                               HDA_OUTPUT));
8390                         if (err < 0)
8391                                 return err;
8392                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8393                                           "Headphone Playback Switch",
8394                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8395                                                               HDA_OUTPUT));
8396                         if (err < 0)
8397                                 return err;
8398                 } else {
8399                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8400                                           "Headphone Playback Switch",
8401                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8402                                                               HDA_OUTPUT));
8403                         if (err < 0)
8404                                 return err;
8405                 }
8406         }
8407         return 0;
8408 }
8409
8410 /* identical with ALC880 */
8411 #define alc262_auto_create_analog_input_ctls \
8412         alc880_auto_create_analog_input_ctls
8413
8414 /*
8415  * generic initialization of ADC, input mixers and output mixers
8416  */
8417 static struct hda_verb alc262_volume_init_verbs[] = {
8418         /*
8419          * Unmute ADC0-2 and set the default input to mic-in
8420          */
8421         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8422         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8423         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8424         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8425         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8426         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8427
8428         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8429          * mixer widget
8430          * Note: PASD motherboards uses the Line In 2 as the input for
8431          * front panel mic (mic 2)
8432          */
8433         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8434         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8435         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8436         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8437         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8438         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8439
8440         /*
8441          * Set up output mixers (0x0c - 0x0f)
8442          */
8443         /* set vol=0 to output mixers */
8444         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8445         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8446         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8447         
8448         /* set up input amps for analog loopback */
8449         /* Amp Indices: DAC = 0, mixer = 1 */
8450         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8451         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8452         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8453         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8454         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8455         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8456
8457         /* FIXME: use matrix-type input source selection */
8458         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8459         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8460         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8461         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8462         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8463         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8464         /* Input mixer2 */
8465         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8466         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8467         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8468         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8469         /* Input mixer3 */
8470         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8471         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8472         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8473         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8474
8475         { }
8476 };
8477
8478 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8479         /*
8480          * Unmute ADC0-2 and set the default input to mic-in
8481          */
8482         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8483         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8484         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8485         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8486         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8487         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8488
8489         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8490          * mixer widget
8491          * Note: PASD motherboards uses the Line In 2 as the input for
8492          * front panel mic (mic 2)
8493          */
8494         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8495         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8496         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8497         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8498         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8499         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8500         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8501         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8502         
8503         /*
8504          * Set up output mixers (0x0c - 0x0e)
8505          */
8506         /* set vol=0 to output mixers */
8507         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8510
8511         /* set up input amps for analog loopback */
8512         /* Amp Indices: DAC = 0, mixer = 1 */
8513         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8514         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8515         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8516         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8517         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8518         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8519
8520         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8521         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8522         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8523
8524         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8525         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8526
8527         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8528         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8529
8530         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8531         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8532         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8533         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8534         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8535
8536         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8537         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8538         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8539         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8540         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8541         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8542
8543
8544         /* FIXME: use matrix-type input source selection */
8545         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8546         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8547         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8548         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8549         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8550         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8551         /* Input mixer2 */
8552         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8553         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8554         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8555         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8556         /* Input mixer3 */
8557         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8558         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8559         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8560         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8561
8562         { }
8563 };
8564
8565 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8566         /*
8567          * Unmute ADC0-2 and set the default input to mic-in
8568          */
8569         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8570         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8571         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8572         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8573         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8574         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8575
8576         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8577          * mixer widget
8578          * Note: PASD motherboards uses the Line In 2 as the input for front
8579          * panel mic (mic 2)
8580          */
8581         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8582         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8583         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8584         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8585         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8586         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8587         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8588         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8589         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8590         /*
8591          * Set up output mixers (0x0c - 0x0e)
8592          */
8593         /* set vol=0 to output mixers */
8594         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8595         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8596         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8597
8598         /* set up input amps for analog loopback */
8599         /* Amp Indices: DAC = 0, mixer = 1 */
8600         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8601         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8602         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8603         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8604         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8605         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8606
8607
8608         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
8609         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
8610         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
8611         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
8612         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
8613         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
8614         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
8615
8616         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8617         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8618
8619         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8620         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8621
8622         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8623         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8624         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8625         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8626         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8627         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8628
8629         /* FIXME: use matrix-type input source selection */
8630         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8631         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8632         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8633         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8634         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8635         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8636         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8637         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
8638         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8639         /* Input mixer2 */
8640         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8641         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8642         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8643         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8644         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8645         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8646         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8647         /* Input mixer3 */
8648         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8649         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8650         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8651         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8652         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8653         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8654         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8655
8656         { }
8657 };
8658
8659 #ifdef CONFIG_SND_HDA_POWER_SAVE
8660 #define alc262_loopbacks        alc880_loopbacks
8661 #endif
8662
8663 /* pcm configuration: identiacal with ALC880 */
8664 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
8665 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
8666 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
8667 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
8668
8669 /*
8670  * BIOS auto configuration
8671  */
8672 static int alc262_parse_auto_config(struct hda_codec *codec)
8673 {
8674         struct alc_spec *spec = codec->spec;
8675         int err;
8676         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8677
8678         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8679                                            alc262_ignore);
8680         if (err < 0)
8681                 return err;
8682         if (!spec->autocfg.line_outs)
8683                 return 0; /* can't find valid BIOS pin config */
8684         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8685         if (err < 0)
8686                 return err;
8687         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8688         if (err < 0)
8689                 return err;
8690
8691         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8692
8693         if (spec->autocfg.dig_out_pin)
8694                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8695         if (spec->autocfg.dig_in_pin)
8696                 spec->dig_in_nid = ALC262_DIGIN_NID;
8697
8698         if (spec->kctl_alloc)
8699                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8700
8701         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8702         spec->num_mux_defs = 1;
8703         spec->input_mux = &spec->private_imux;
8704
8705         err = alc_auto_add_mic_boost(codec);
8706         if (err < 0)
8707                 return err;
8708
8709         return 1;
8710 }
8711
8712 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
8713 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
8714 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
8715
8716
8717 /* init callback for auto-configuration model -- overriding the default init */
8718 static void alc262_auto_init(struct hda_codec *codec)
8719 {
8720         alc262_auto_init_multi_out(codec);
8721         alc262_auto_init_hp_out(codec);
8722         alc262_auto_init_analog_input(codec);
8723 }
8724
8725 /*
8726  * configuration and preset
8727  */
8728 static const char *alc262_models[ALC262_MODEL_LAST] = {
8729         [ALC262_BASIC]          = "basic",
8730         [ALC262_HIPPO]          = "hippo",
8731         [ALC262_HIPPO_1]        = "hippo_1",
8732         [ALC262_FUJITSU]        = "fujitsu",
8733         [ALC262_HP_BPC]         = "hp-bpc",
8734         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8735         [ALC262_HP_TC_T5735]    = "hp-tc-t5735",
8736         [ALC262_BENQ_ED8]       = "benq",
8737         [ALC262_BENQ_T31]       = "benq-t31",
8738         [ALC262_SONY_ASSAMD]    = "sony-assamd",
8739         [ALC262_ULTRA]          = "ultra",
8740         [ALC262_AUTO]           = "auto",
8741 };
8742
8743 static struct snd_pci_quirk alc262_cfg_tbl[] = {
8744         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8745         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8746         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8747         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8748         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8749         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8750         SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
8751         SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
8752         SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
8753         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8754         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8755         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8756         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8757         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8758         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8759         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8760         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8761         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8762         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8763         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8764         SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8765                       ALC262_HP_TC_T5735),
8766         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8767         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8768         SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8769         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8770         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8771         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8772         SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
8773         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8774         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8775         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8776         {}
8777 };
8778
8779 static struct alc_config_preset alc262_presets[] = {
8780         [ALC262_BASIC] = {
8781                 .mixers = { alc262_base_mixer },
8782                 .init_verbs = { alc262_init_verbs },
8783                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8784                 .dac_nids = alc262_dac_nids,
8785                 .hp_nid = 0x03,
8786                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8787                 .channel_mode = alc262_modes,
8788                 .input_mux = &alc262_capture_source,
8789         },
8790         [ALC262_HIPPO] = {
8791                 .mixers = { alc262_base_mixer },
8792                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8793                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8794                 .dac_nids = alc262_dac_nids,
8795                 .hp_nid = 0x03,
8796                 .dig_out_nid = ALC262_DIGOUT_NID,
8797                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8798                 .channel_mode = alc262_modes,
8799                 .input_mux = &alc262_capture_source,
8800                 .unsol_event = alc262_hippo_unsol_event,
8801                 .init_hook = alc262_hippo_automute,
8802         },
8803         [ALC262_HIPPO_1] = {
8804                 .mixers = { alc262_hippo1_mixer },
8805                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8806                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8807                 .dac_nids = alc262_dac_nids,
8808                 .hp_nid = 0x02,
8809                 .dig_out_nid = ALC262_DIGOUT_NID,
8810                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8811                 .channel_mode = alc262_modes,
8812                 .input_mux = &alc262_capture_source,
8813                 .unsol_event = alc262_hippo1_unsol_event,
8814                 .init_hook = alc262_hippo1_automute,
8815         },
8816         [ALC262_FUJITSU] = {
8817                 .mixers = { alc262_fujitsu_mixer },
8818                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8819                                 alc262_fujitsu_unsol_verbs },
8820                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8821                 .dac_nids = alc262_dac_nids,
8822                 .hp_nid = 0x03,
8823                 .dig_out_nid = ALC262_DIGOUT_NID,
8824                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8825                 .channel_mode = alc262_modes,
8826                 .input_mux = &alc262_fujitsu_capture_source,
8827                 .unsol_event = alc262_fujitsu_unsol_event,
8828         },
8829         [ALC262_HP_BPC] = {
8830                 .mixers = { alc262_HP_BPC_mixer },
8831                 .init_verbs = { alc262_HP_BPC_init_verbs },
8832                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8833                 .dac_nids = alc262_dac_nids,
8834                 .hp_nid = 0x03,
8835                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8836                 .channel_mode = alc262_modes,
8837                 .input_mux = &alc262_HP_capture_source,
8838         },
8839         [ALC262_HP_BPC_D7000_WF] = {
8840                 .mixers = { alc262_HP_BPC_WildWest_mixer },
8841                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8842                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8843                 .dac_nids = alc262_dac_nids,
8844                 .hp_nid = 0x03,
8845                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8846                 .channel_mode = alc262_modes,
8847                 .input_mux = &alc262_HP_D7000_capture_source,
8848         },
8849         [ALC262_HP_BPC_D7000_WL] = {
8850                 .mixers = { alc262_HP_BPC_WildWest_mixer,
8851                             alc262_HP_BPC_WildWest_option_mixer },
8852                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8853                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8854                 .dac_nids = alc262_dac_nids,
8855                 .hp_nid = 0x03,
8856                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8857                 .channel_mode = alc262_modes,
8858                 .input_mux = &alc262_HP_D7000_capture_source,
8859         },
8860         [ALC262_HP_TC_T5735] = {
8861                 .mixers = { alc262_hp_t5735_mixer },
8862                 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
8863                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8864                 .dac_nids = alc262_dac_nids,
8865                 .hp_nid = 0x03,
8866                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8867                 .channel_mode = alc262_modes,
8868                 .input_mux = &alc262_capture_source,
8869                 .unsol_event = alc262_hp_t5735_unsol_event,
8870                 .init_hook = alc262_hp_t5735_init_hook,
8871         },
8872         [ALC262_BENQ_ED8] = {
8873                 .mixers = { alc262_base_mixer },
8874                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8875                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8876                 .dac_nids = alc262_dac_nids,
8877                 .hp_nid = 0x03,
8878                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8879                 .channel_mode = alc262_modes,
8880                 .input_mux = &alc262_capture_source,
8881         },
8882         [ALC262_SONY_ASSAMD] = {
8883                 .mixers = { alc262_sony_mixer },
8884                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8885                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8886                 .dac_nids = alc262_dac_nids,
8887                 .hp_nid = 0x02,
8888                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8889                 .channel_mode = alc262_modes,
8890                 .input_mux = &alc262_capture_source,
8891                 .unsol_event = alc262_hippo_unsol_event,
8892                 .init_hook = alc262_hippo_automute,
8893         },
8894         [ALC262_BENQ_T31] = {
8895                 .mixers = { alc262_benq_t31_mixer },
8896                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8897                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8898                 .dac_nids = alc262_dac_nids,
8899                 .hp_nid = 0x03,
8900                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8901                 .channel_mode = alc262_modes,
8902                 .input_mux = &alc262_capture_source,
8903                 .unsol_event = alc262_hippo_unsol_event,
8904                 .init_hook = alc262_hippo_automute,
8905         },      
8906         [ALC262_ULTRA] = {
8907                 .mixers = { alc262_ultra_mixer },
8908                 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
8909                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8910                 .dac_nids = alc262_dac_nids,
8911                 .hp_nid = 0x03,
8912                 .dig_out_nid = ALC262_DIGOUT_NID,
8913                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8914                 .channel_mode = alc262_modes,
8915                 .input_mux = &alc262_ultra_capture_source,
8916                 .unsol_event = alc262_ultra_unsol_event,
8917                 .init_hook = alc262_ultra_automute,
8918         },
8919 };
8920
8921 static int patch_alc262(struct hda_codec *codec)
8922 {
8923         struct alc_spec *spec;
8924         int board_config;
8925         int err;
8926
8927         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8928         if (spec == NULL)
8929                 return -ENOMEM;
8930
8931         codec->spec = spec;
8932 #if 0
8933         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8934          * under-run
8935          */
8936         {
8937         int tmp;
8938         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8939         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8940         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8941         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8942         }
8943 #endif
8944
8945         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8946                                                   alc262_models,
8947                                                   alc262_cfg_tbl);
8948
8949         if (board_config < 0) {
8950                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8951                        "trying auto-probe from BIOS...\n");
8952                 board_config = ALC262_AUTO;
8953         }
8954
8955         if (board_config == ALC262_AUTO) {
8956                 /* automatic parse from the BIOS config */
8957                 err = alc262_parse_auto_config(codec);
8958                 if (err < 0) {
8959                         alc_free(codec);
8960                         return err;
8961                 } else if (!err) {
8962                         printk(KERN_INFO
8963                                "hda_codec: Cannot set up configuration "
8964                                "from BIOS.  Using base mode...\n");
8965                         board_config = ALC262_BASIC;
8966                 }
8967         }
8968
8969         if (board_config != ALC262_AUTO)
8970                 setup_preset(spec, &alc262_presets[board_config]);
8971
8972         spec->stream_name_analog = "ALC262 Analog";
8973         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8974         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8975                 
8976         spec->stream_name_digital = "ALC262 Digital";
8977         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8978         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8979
8980         if (!spec->adc_nids && spec->input_mux) {
8981                 /* check whether NID 0x07 is valid */
8982                 unsigned int wcap = get_wcaps(codec, 0x07);
8983
8984                 /* get type */
8985                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8986                 if (wcap != AC_WID_AUD_IN) {
8987                         spec->adc_nids = alc262_adc_nids_alt;
8988                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8989                         spec->mixers[spec->num_mixers] =
8990                                 alc262_capture_alt_mixer;
8991                         spec->num_mixers++;
8992                 } else {
8993                         spec->adc_nids = alc262_adc_nids;
8994                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8995                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8996                         spec->num_mixers++;
8997                 }
8998         }
8999
9000         codec->patch_ops = alc_patch_ops;
9001         if (board_config == ALC262_AUTO)
9002                 spec->init_hook = alc262_auto_init;
9003 #ifdef CONFIG_SND_HDA_POWER_SAVE
9004         if (!spec->loopback.amplist)
9005                 spec->loopback.amplist = alc262_loopbacks;
9006 #endif
9007                 
9008         return 0;
9009 }
9010
9011 /*
9012  *  ALC268 channel source setting (2 channel)
9013  */
9014 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
9015 #define alc268_modes            alc260_modes
9016         
9017 static hda_nid_t alc268_dac_nids[2] = {
9018         /* front, hp */
9019         0x02, 0x03
9020 };
9021
9022 static hda_nid_t alc268_adc_nids[2] = {
9023         /* ADC0-1 */
9024         0x08, 0x07
9025 };
9026
9027 static hda_nid_t alc268_adc_nids_alt[1] = {
9028         /* ADC0 */
9029         0x08
9030 };
9031
9032 static struct snd_kcontrol_new alc268_base_mixer[] = {
9033         /* output mixer control */
9034         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9035         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9036         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9037         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9038         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9039         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9040         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9041         { }
9042 };
9043
9044 static struct hda_verb alc268_eapd_verbs[] = {
9045         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9046         {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9047         { }
9048 };
9049
9050 /* Toshiba specific */
9051 #define alc268_toshiba_automute alc262_hippo_automute
9052
9053 static struct hda_verb alc268_toshiba_verbs[] = {
9054         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9055         { } /* end */
9056 };
9057
9058 /* Acer specific */
9059 /* bind volumes of both NID 0x02 and 0x03 */
9060 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9061         .ops = &snd_hda_bind_vol,
9062         .values = {
9063                 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9064                 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9065                 0
9066         },
9067 };
9068
9069 /* mute/unmute internal speaker according to the hp jack and mute state */
9070 static void alc268_acer_automute(struct hda_codec *codec, int force)
9071 {
9072         struct alc_spec *spec = codec->spec;
9073         unsigned int mute;
9074
9075         if (force || !spec->sense_updated) {
9076                 unsigned int present;
9077                 present = snd_hda_codec_read(codec, 0x14, 0,
9078                                          AC_VERB_GET_PIN_SENSE, 0);
9079                 spec->jack_present = (present & 0x80000000) != 0;
9080                 spec->sense_updated = 1;
9081         }
9082         if (spec->jack_present)
9083                 mute = HDA_AMP_MUTE; /* mute internal speaker */
9084         else /* unmute internal speaker if necessary */
9085                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9086         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9087                                  HDA_AMP_MUTE, mute);
9088 }
9089
9090
9091 /* bind hp and internal speaker mute (with plug check) */
9092 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9093                                      struct snd_ctl_elem_value *ucontrol)
9094 {
9095         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9096         long *valp = ucontrol->value.integer.value;
9097         int change;
9098
9099         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9100                                           HDA_AMP_MUTE,
9101                                           valp[0] ? 0 : HDA_AMP_MUTE);
9102         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9103                                            HDA_AMP_MUTE,
9104                                            valp[1] ? 0 : HDA_AMP_MUTE);
9105         if (change)
9106                 alc268_acer_automute(codec, 0);
9107         return change;
9108 }
9109
9110 static struct snd_kcontrol_new alc268_acer_mixer[] = {
9111         /* output mixer control */
9112         HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9113         {
9114                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9115                 .name = "Master Playback Switch",
9116                 .info = snd_hda_mixer_amp_switch_info,
9117                 .get = snd_hda_mixer_amp_switch_get,
9118                 .put = alc268_acer_master_sw_put,
9119                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9120         },
9121         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9122         HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9123         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9124         { }
9125 };
9126
9127 static struct hda_verb alc268_acer_verbs[] = {
9128         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9129         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9130
9131         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9132         { }
9133 };
9134
9135 /* unsolicited event for HP jack sensing */
9136 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9137                                        unsigned int res)
9138 {
9139         if ((res >> 26) != ALC880_HP_EVENT)
9140                 return;
9141         alc268_toshiba_automute(codec);
9142 }
9143
9144 static void alc268_acer_unsol_event(struct hda_codec *codec,
9145                                        unsigned int res)
9146 {
9147         if ((res >> 26) != ALC880_HP_EVENT)
9148                 return;
9149         alc268_acer_automute(codec, 1);
9150 }
9151
9152 static void alc268_acer_init_hook(struct hda_codec *codec)
9153 {
9154         alc268_acer_automute(codec, 1);
9155 }
9156
9157 /*
9158  * generic initialization of ADC, input mixers and output mixers
9159  */
9160 static struct hda_verb alc268_base_init_verbs[] = {
9161         /* Unmute DAC0-1 and set vol = 0 */
9162         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9163         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9164         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9165         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9166         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9167         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9168
9169         /*
9170          * Set up output mixers (0x0c - 0x0e)
9171          */
9172         /* set vol=0 to output mixers */
9173         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9174         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9175         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9176         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9177
9178         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9179         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9180
9181         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9182         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9183         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9184         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9185         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9186         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9187         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9188         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9189
9190         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9191         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9192         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9193         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9194         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9195         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9196         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9197         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9198
9199         /* FIXME: use matrix-type input source selection */
9200         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
9201         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9202         /* Input mixer2 */
9203         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9204         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9205         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9206         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9207
9208         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9209         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9210         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9211         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9212         { }
9213 };
9214
9215 /*
9216  * generic initialization of ADC, input mixers and output mixers
9217  */
9218 static struct hda_verb alc268_volume_init_verbs[] = {
9219         /* set output DAC */
9220         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9221         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9222         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9223         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9224
9225         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9226         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9227         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9228         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9229         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9230
9231         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9232         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9233         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9234         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9235         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9236
9237         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9238         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9239         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9240         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9241
9242         /* set PCBEEP vol = 0 */
9243         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9244
9245         { }
9246 };
9247
9248 #define alc268_mux_enum_info alc_mux_enum_info
9249 #define alc268_mux_enum_get alc_mux_enum_get
9250
9251 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9252                                struct snd_ctl_elem_value *ucontrol)
9253 {
9254         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9255         struct alc_spec *spec = codec->spec;
9256         const struct hda_input_mux *imux = spec->input_mux;
9257         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9258         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9259         hda_nid_t nid = capture_mixers[adc_idx];
9260         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9261         unsigned int i, idx;
9262
9263         idx = ucontrol->value.enumerated.item[0];
9264         if (idx >= imux->num_items)
9265                 idx = imux->num_items - 1;
9266         if (*cur_val == idx)
9267                 return 0;
9268         for (i = 0; i < imux->num_items; i++) {
9269                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
9270                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
9271                                          imux->items[i].index,
9272                                          HDA_AMP_MUTE, v);
9273                 snd_hda_codec_write_cache(codec, nid, 0,
9274                                           AC_VERB_SET_CONNECT_SEL,
9275                                           idx );
9276         }
9277         *cur_val = idx;
9278         return 1;
9279 }
9280
9281 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9282         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9283         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9284         {
9285                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9286                 /* The multiple "Capture Source" controls confuse alsamixer
9287                  * So call somewhat different..
9288                  * FIXME: the controls appear in the "playback" view!
9289                  */
9290                 /* .name = "Capture Source", */
9291                 .name = "Input Source",
9292                 .count = 1,
9293                 .info = alc268_mux_enum_info,
9294                 .get = alc268_mux_enum_get,
9295                 .put = alc268_mux_enum_put,
9296         },
9297         { } /* end */
9298 };
9299
9300 static struct snd_kcontrol_new alc268_capture_mixer[] = {
9301         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9302         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9303         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9304         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9305         {
9306                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9307                 /* The multiple "Capture Source" controls confuse alsamixer
9308                  * So call somewhat different..
9309                  * FIXME: the controls appear in the "playback" view!
9310                  */
9311                 /* .name = "Capture Source", */
9312                 .name = "Input Source",
9313                 .count = 2,
9314                 .info = alc268_mux_enum_info,
9315                 .get = alc268_mux_enum_get,
9316                 .put = alc268_mux_enum_put,
9317         },
9318         { } /* end */
9319 };
9320
9321 static struct hda_input_mux alc268_capture_source = {
9322         .num_items = 4,
9323         .items = {
9324                 { "Mic", 0x0 },
9325                 { "Front Mic", 0x1 },
9326                 { "Line", 0x2 },
9327                 { "CD", 0x3 },
9328         },
9329 };
9330
9331 /* create input playback/capture controls for the given pin */
9332 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9333                                     const char *ctlname, int idx)
9334 {
9335         char name[32];
9336         int err;
9337
9338         sprintf(name, "%s Playback Volume", ctlname);
9339         if (nid == 0x14) {
9340                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9341                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9342                                                       HDA_OUTPUT));
9343                 if (err < 0)
9344                         return err;
9345         } else if (nid == 0x15) {
9346                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9347                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9348                                                       HDA_OUTPUT));
9349                 if (err < 0)
9350                         return err;
9351         } else
9352                 return -1;
9353         sprintf(name, "%s Playback Switch", ctlname);
9354         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9355                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9356         if (err < 0)
9357                 return err;
9358         return 0;
9359 }
9360
9361 /* add playback controls from the parsed DAC table */
9362 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9363                                              const struct auto_pin_cfg *cfg)
9364 {
9365         hda_nid_t nid;
9366         int err;
9367
9368         spec->multiout.num_dacs = 2;    /* only use one dac */
9369         spec->multiout.dac_nids = spec->private_dac_nids;
9370         spec->multiout.dac_nids[0] = 2;
9371         spec->multiout.dac_nids[1] = 3;
9372
9373         nid = cfg->line_out_pins[0];
9374         if (nid)
9375                 alc268_new_analog_output(spec, nid, "Front", 0);        
9376
9377         nid = cfg->speaker_pins[0];
9378         if (nid == 0x1d) {
9379                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9380                                   "Speaker Playback Volume",
9381                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9382                 if (err < 0)
9383                         return err;
9384         }
9385         nid = cfg->hp_pins[0];
9386         if (nid)
9387                 alc268_new_analog_output(spec, nid, "Headphone", 0);
9388
9389         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9390         if (nid == 0x16) {
9391                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9392                                   "Mono Playback Switch",
9393                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9394                 if (err < 0)
9395                         return err;
9396         }
9397         return 0;       
9398 }
9399
9400 /* create playback/capture controls for input pins */
9401 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9402                                                 const struct auto_pin_cfg *cfg)
9403 {
9404         struct hda_input_mux *imux = &spec->private_imux;
9405         int i, idx1;
9406
9407         for (i = 0; i < AUTO_PIN_LAST; i++) {
9408                 switch(cfg->input_pins[i]) {
9409                 case 0x18:
9410                         idx1 = 0;       /* Mic 1 */
9411                         break;
9412                 case 0x19:
9413                         idx1 = 1;       /* Mic 2 */
9414                         break;
9415                 case 0x1a:
9416                         idx1 = 2;       /* Line In */
9417                         break;
9418                 case 0x1c:      
9419                         idx1 = 3;       /* CD */
9420                         break;
9421                 default:
9422                         continue;
9423                 }
9424                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9425                 imux->items[imux->num_items].index = idx1;
9426                 imux->num_items++;      
9427         }
9428         return 0;
9429 }
9430
9431 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9432 {
9433         struct alc_spec *spec = codec->spec;
9434         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9435         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9436         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9437         unsigned int    dac_vol1, dac_vol2;
9438
9439         if (speaker_nid) {
9440                 snd_hda_codec_write(codec, speaker_nid, 0,
9441                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9442                 snd_hda_codec_write(codec, 0x0f, 0,
9443                                     AC_VERB_SET_AMP_GAIN_MUTE,
9444                                     AMP_IN_UNMUTE(1));
9445                 snd_hda_codec_write(codec, 0x10, 0,
9446                                     AC_VERB_SET_AMP_GAIN_MUTE,
9447                                     AMP_IN_UNMUTE(1));
9448         } else {
9449                 snd_hda_codec_write(codec, 0x0f, 0,
9450                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9451                 snd_hda_codec_write(codec, 0x10, 0,
9452                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9453         }
9454
9455         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
9456         if (line_nid == 0x14)   
9457                 dac_vol2 = AMP_OUT_ZERO;
9458         else if (line_nid == 0x15)
9459                 dac_vol1 = AMP_OUT_ZERO;
9460         if (hp_nid == 0x14)     
9461                 dac_vol2 = AMP_OUT_ZERO;
9462         else if (hp_nid == 0x15)
9463                 dac_vol1 = AMP_OUT_ZERO;
9464         if (line_nid != 0x16 || hp_nid != 0x16 ||
9465             spec->autocfg.line_out_pins[1] != 0x16 ||
9466             spec->autocfg.line_out_pins[2] != 0x16)
9467                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9468
9469         snd_hda_codec_write(codec, 0x02, 0,
9470                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9471         snd_hda_codec_write(codec, 0x03, 0,
9472                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9473 }
9474
9475 /* pcm configuration: identiacal with ALC880 */
9476 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
9477 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
9478 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
9479
9480 /*
9481  * BIOS auto configuration
9482  */
9483 static int alc268_parse_auto_config(struct hda_codec *codec)
9484 {
9485         struct alc_spec *spec = codec->spec;
9486         int err;
9487         static hda_nid_t alc268_ignore[] = { 0 };
9488
9489         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9490                                            alc268_ignore);
9491         if (err < 0)
9492                 return err;
9493         if (!spec->autocfg.line_outs)
9494                 return 0; /* can't find valid BIOS pin config */
9495
9496         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9497         if (err < 0)
9498                 return err;
9499         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9500         if (err < 0)
9501                 return err;
9502
9503         spec->multiout.max_channels = 2;
9504
9505         /* digital only support output */
9506         if (spec->autocfg.dig_out_pin)
9507                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9508
9509         if (spec->kctl_alloc)
9510                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9511
9512         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9513         spec->num_mux_defs = 1;
9514         spec->input_mux = &spec->private_imux;
9515
9516         err = alc_auto_add_mic_boost(codec);
9517         if (err < 0)
9518                 return err;
9519
9520         return 1;
9521 }
9522
9523 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
9524 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
9525 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
9526
9527 /* init callback for auto-configuration model -- overriding the default init */
9528 static void alc268_auto_init(struct hda_codec *codec)
9529 {
9530         alc268_auto_init_multi_out(codec);
9531         alc268_auto_init_hp_out(codec);
9532         alc268_auto_init_mono_speaker_out(codec);
9533         alc268_auto_init_analog_input(codec);
9534 }
9535
9536 /*
9537  * configuration and preset
9538  */
9539 static const char *alc268_models[ALC268_MODEL_LAST] = {
9540         [ALC268_3ST]            = "3stack",
9541         [ALC268_TOSHIBA]        = "toshiba",
9542         [ALC268_ACER]           = "acer",
9543         [ALC268_AUTO]           = "auto",
9544 };
9545
9546 static struct snd_pci_quirk alc268_cfg_tbl[] = {
9547         SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9548         SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9549         SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
9550         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
9551         SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
9552         SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
9553         SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
9554         {}
9555 };
9556
9557 static struct alc_config_preset alc268_presets[] = {
9558         [ALC268_3ST] = {
9559                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9560                 .init_verbs = { alc268_base_init_verbs },
9561                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9562                 .dac_nids = alc268_dac_nids,
9563                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9564                 .adc_nids = alc268_adc_nids_alt,
9565                 .hp_nid = 0x03,
9566                 .dig_out_nid = ALC268_DIGOUT_NID,
9567                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9568                 .channel_mode = alc268_modes,
9569                 .input_mux = &alc268_capture_source,
9570         },
9571         [ALC268_TOSHIBA] = {
9572                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9573                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9574                                 alc268_toshiba_verbs },
9575                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9576                 .dac_nids = alc268_dac_nids,
9577                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9578                 .adc_nids = alc268_adc_nids_alt,
9579                 .hp_nid = 0x03,
9580                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9581                 .channel_mode = alc268_modes,
9582                 .input_mux = &alc268_capture_source,
9583                 .unsol_event = alc268_toshiba_unsol_event,
9584                 .init_hook = alc268_toshiba_automute,
9585         },
9586         [ALC268_ACER] = {
9587                 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9588                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9589                                 alc268_acer_verbs },
9590                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9591                 .dac_nids = alc268_dac_nids,
9592                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9593                 .adc_nids = alc268_adc_nids_alt,
9594                 .hp_nid = 0x02,
9595                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9596                 .channel_mode = alc268_modes,
9597                 .input_mux = &alc268_capture_source,
9598                 .unsol_event = alc268_acer_unsol_event,
9599                 .init_hook = alc268_acer_init_hook,
9600         },
9601 };
9602
9603 static int patch_alc268(struct hda_codec *codec)
9604 {
9605         struct alc_spec *spec;
9606         int board_config;
9607         int err;
9608
9609         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9610         if (spec == NULL)
9611                 return -ENOMEM;
9612
9613         codec->spec = spec;
9614
9615         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9616                                                   alc268_models,
9617                                                   alc268_cfg_tbl);
9618
9619         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9620                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9621                        "trying auto-probe from BIOS...\n");
9622                 board_config = ALC268_AUTO;
9623         }
9624
9625         if (board_config == ALC268_AUTO) {
9626                 /* automatic parse from the BIOS config */
9627                 err = alc268_parse_auto_config(codec);
9628                 if (err < 0) {
9629                         alc_free(codec);
9630                         return err;
9631                 } else if (!err) {
9632                         printk(KERN_INFO
9633                                "hda_codec: Cannot set up configuration "
9634                                "from BIOS.  Using base mode...\n");
9635                         board_config = ALC268_3ST;
9636                 }
9637         }
9638
9639         if (board_config != ALC268_AUTO)
9640                 setup_preset(spec, &alc268_presets[board_config]);
9641
9642         spec->stream_name_analog = "ALC268 Analog";
9643         spec->stream_analog_playback = &alc268_pcm_analog_playback;
9644         spec->stream_analog_capture = &alc268_pcm_analog_capture;
9645
9646         spec->stream_name_digital = "ALC268 Digital";
9647         spec->stream_digital_playback = &alc268_pcm_digital_playback;
9648
9649         if (board_config == ALC268_AUTO) {
9650                 if (!spec->adc_nids && spec->input_mux) {
9651                         /* check whether NID 0x07 is valid */
9652                         unsigned int wcap = get_wcaps(codec, 0x07);
9653
9654                         /* get type */
9655                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9656                         if (wcap != AC_WID_AUD_IN) {
9657                                 spec->adc_nids = alc268_adc_nids_alt;
9658                                 spec->num_adc_nids =
9659                                         ARRAY_SIZE(alc268_adc_nids_alt);
9660                                 spec->mixers[spec->num_mixers] =
9661                                         alc268_capture_alt_mixer;
9662                                 spec->num_mixers++;
9663                         } else {
9664                                 spec->adc_nids = alc268_adc_nids;
9665                                 spec->num_adc_nids =
9666                                         ARRAY_SIZE(alc268_adc_nids);
9667                                 spec->mixers[spec->num_mixers] =
9668                                         alc268_capture_mixer;
9669                                 spec->num_mixers++;
9670                         }
9671                 }
9672         }
9673         codec->patch_ops = alc_patch_ops;
9674         if (board_config == ALC268_AUTO)
9675                 spec->init_hook = alc268_auto_init;
9676                 
9677         return 0;
9678 }
9679
9680 /*
9681  *  ALC269 channel source setting (2 channel)
9682  */
9683 #define ALC269_DIGOUT_NID       ALC880_DIGOUT_NID
9684
9685 #define alc269_dac_nids         alc260_dac_nids
9686
9687 static hda_nid_t alc269_adc_nids[1] = {
9688         /* ADC1 */
9689         0x07,
9690 };
9691
9692 #define alc269_modes            alc260_modes
9693 #define alc269_capture_source   alc880_lg_lw_capture_source
9694
9695 static struct snd_kcontrol_new alc269_base_mixer[] = {
9696         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9697         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9698         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9699         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9700         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9701         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9702         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9703         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9704         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9705         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9706         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9707         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9708         { } /* end */
9709 };
9710
9711 /* capture mixer elements */
9712 static struct snd_kcontrol_new alc269_capture_mixer[] = {
9713         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9714         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9715         {
9716                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9717                 /* The multiple "Capture Source" controls confuse alsamixer
9718                  * So call somewhat different..
9719                  * FIXME: the controls appear in the "playback" view!
9720                  */
9721                 /* .name = "Capture Source", */
9722                 .name = "Input Source",
9723                 .count = 1,
9724                 .info = alc_mux_enum_info,
9725                 .get = alc_mux_enum_get,
9726                 .put = alc_mux_enum_put,
9727         },
9728         { } /* end */
9729 };
9730
9731 /*
9732  * generic initialization of ADC, input mixers and output mixers
9733  */
9734 static struct hda_verb alc269_init_verbs[] = {
9735         /*
9736          * Unmute ADC0 and set the default input to mic-in
9737          */
9738         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9739
9740         /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
9741          * analog-loopback mixer widget
9742          * Note: PASD motherboards uses the Line In 2 as the input for
9743          * front panel mic (mic 2)
9744          */
9745         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9746         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9747         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9748         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9749         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9750         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9751
9752         /*
9753          * Set up output mixers (0x0c - 0x0e)
9754          */
9755         /* set vol=0 to output mixers */
9756         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9757         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9758
9759         /* set up input amps for analog loopback */
9760         /* Amp Indices: DAC = 0, mixer = 1 */
9761         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9762         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9763         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9764         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9765         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9766         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9767
9768         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9769         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9770         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9771         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9772         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9773         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9774         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9775
9776         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9777         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9778         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9779         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9780         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9781         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9782         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9783
9784         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9785         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9786
9787         /* FIXME: use matrix-type input source selection */
9788         /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
9789         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9790         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9791         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9792         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9793         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9794
9795         /* set EAPD */
9796         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9797         {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9798         { }
9799 };
9800
9801 /* add playback controls from the parsed DAC table */
9802 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
9803                                              const struct auto_pin_cfg *cfg)
9804 {
9805         hda_nid_t nid;
9806         int err;
9807
9808         spec->multiout.num_dacs = 1;    /* only use one dac */
9809         spec->multiout.dac_nids = spec->private_dac_nids;
9810         spec->multiout.dac_nids[0] = 2;
9811
9812         nid = cfg->line_out_pins[0];
9813         if (nid) {
9814                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9815                                   "Front Playback Volume",
9816                                   HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
9817                 if (err < 0)
9818                         return err;
9819                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9820                                   "Front Playback Switch",
9821                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9822                 if (err < 0)
9823                         return err;
9824         }
9825
9826         nid = cfg->speaker_pins[0];
9827         if (nid) {
9828                 if (!cfg->line_out_pins[0]) {
9829                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
9830                                           "Speaker Playback Volume",
9831                                           HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9832                                                               HDA_OUTPUT));
9833                         if (err < 0)
9834                                 return err;
9835                 }
9836                 if (nid == 0x16) {
9837                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9838                                           "Speaker Playback Switch",
9839                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9840                                                               HDA_OUTPUT));
9841                         if (err < 0)
9842                                 return err;
9843                 } else {
9844                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9845                                           "Speaker Playback Switch",
9846                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9847                                                               HDA_OUTPUT));
9848                         if (err < 0)
9849                                 return err;
9850                 }
9851         }
9852         nid = cfg->hp_pins[0];
9853         if (nid) {
9854                 /* spec->multiout.hp_nid = 2; */
9855                 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
9856                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
9857                                           "Headphone Playback Volume",
9858                                           HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9859                                                               HDA_OUTPUT));
9860                         if (err < 0)
9861                                 return err;
9862                 }
9863                 if (nid == 0x16) {
9864                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9865                                           "Headphone Playback Switch",
9866                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9867                                                               HDA_OUTPUT));
9868                         if (err < 0)
9869                                 return err;
9870                 } else {
9871                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9872                                           "Headphone Playback Switch",
9873                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9874                                                               HDA_OUTPUT));
9875                         if (err < 0)
9876                                 return err;
9877                 }
9878         }
9879         return 0;
9880 }
9881
9882 #define alc269_auto_create_analog_input_ctls \
9883         alc880_auto_create_analog_input_ctls
9884
9885 #ifdef CONFIG_SND_HDA_POWER_SAVE
9886 #define alc269_loopbacks        alc880_loopbacks
9887 #endif
9888
9889 /* pcm configuration: identiacal with ALC880 */
9890 #define alc269_pcm_analog_playback      alc880_pcm_analog_playback
9891 #define alc269_pcm_analog_capture       alc880_pcm_analog_capture
9892 #define alc269_pcm_digital_playback     alc880_pcm_digital_playback
9893 #define alc269_pcm_digital_capture      alc880_pcm_digital_capture
9894
9895 /*
9896  * BIOS auto configuration
9897  */
9898 static int alc269_parse_auto_config(struct hda_codec *codec)
9899 {
9900         struct alc_spec *spec = codec->spec;
9901         int err;
9902         static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
9903
9904         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9905                                            alc269_ignore);
9906         if (err < 0)
9907                 return err;
9908
9909         err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
9910         if (err < 0)
9911                 return err;
9912         err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
9913         if (err < 0)
9914                 return err;
9915
9916         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9917
9918         if (spec->autocfg.dig_out_pin)
9919                 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
9920
9921         if (spec->kctl_alloc)
9922                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9923
9924         spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
9925         spec->num_mux_defs = 1;
9926         spec->input_mux = &spec->private_imux;
9927
9928         err = alc_auto_add_mic_boost(codec);
9929         if (err < 0)
9930                 return err;
9931
9932         return 1;
9933 }
9934
9935 #define alc269_auto_init_multi_out      alc882_auto_init_multi_out
9936 #define alc269_auto_init_hp_out         alc882_auto_init_hp_out
9937 #define alc269_auto_init_analog_input   alc882_auto_init_analog_input
9938
9939
9940 /* init callback for auto-configuration model -- overriding the default init */
9941 static void alc269_auto_init(struct hda_codec *codec)
9942 {
9943         alc269_auto_init_multi_out(codec);
9944         alc269_auto_init_hp_out(codec);
9945         alc269_auto_init_analog_input(codec);
9946 }
9947
9948 /*
9949  * configuration and preset
9950  */
9951 static const char *alc269_models[ALC269_MODEL_LAST] = {
9952         [ALC269_BASIC]          = "basic",
9953 };
9954
9955 static struct snd_pci_quirk alc269_cfg_tbl[] = {
9956         {}
9957 };
9958
9959 static struct alc_config_preset alc269_presets[] = {
9960         [ALC269_BASIC] = {
9961                 .mixers = { alc269_base_mixer },
9962                 .init_verbs = { alc269_init_verbs },
9963                 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
9964                 .dac_nids = alc269_dac_nids,
9965                 .hp_nid = 0x03,
9966                 .num_channel_mode = ARRAY_SIZE(alc269_modes),
9967                 .channel_mode = alc269_modes,
9968                 .input_mux = &alc269_capture_source,
9969         },
9970 };
9971
9972 static int patch_alc269(struct hda_codec *codec)
9973 {
9974         struct alc_spec *spec;
9975         int board_config;
9976         int err;
9977
9978         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9979         if (spec == NULL)
9980                 return -ENOMEM;
9981
9982         codec->spec = spec;
9983
9984         board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
9985                                                   alc269_models,
9986                                                   alc269_cfg_tbl);
9987
9988         if (board_config < 0) {
9989                 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
9990                        "trying auto-probe from BIOS...\n");
9991                 board_config = ALC269_AUTO;
9992         }
9993
9994         if (board_config == ALC269_AUTO) {
9995                 /* automatic parse from the BIOS config */
9996                 err = alc269_parse_auto_config(codec);
9997                 if (err < 0) {
9998                         alc_free(codec);
9999                         return err;
10000                 } else if (!err) {
10001                         printk(KERN_INFO
10002                                "hda_codec: Cannot set up configuration "
10003                                "from BIOS.  Using base mode...\n");
10004                         board_config = ALC269_BASIC;
10005                 }
10006         }
10007
10008         if (board_config != ALC269_AUTO)
10009                 setup_preset(spec, &alc269_presets[board_config]);
10010
10011         spec->stream_name_analog = "ALC269 Analog";
10012         spec->stream_analog_playback = &alc269_pcm_analog_playback;
10013         spec->stream_analog_capture = &alc269_pcm_analog_capture;
10014
10015         spec->stream_name_digital = "ALC269 Digital";
10016         spec->stream_digital_playback = &alc269_pcm_digital_playback;
10017         spec->stream_digital_capture = &alc269_pcm_digital_capture;
10018
10019         spec->adc_nids = alc269_adc_nids;
10020         spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10021         spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10022         spec->num_mixers++;
10023
10024         codec->patch_ops = alc_patch_ops;
10025         if (board_config == ALC269_AUTO)
10026                 spec->init_hook = alc269_auto_init;
10027 #ifdef CONFIG_SND_HDA_POWER_SAVE
10028         if (!spec->loopback.amplist)
10029                 spec->loopback.amplist = alc269_loopbacks;
10030 #endif
10031
10032         return 0;
10033 }
10034
10035 /*
10036  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
10037  */
10038
10039 /*
10040  * set the path ways for 2 channel output
10041  * need to set the codec line out and mic 1 pin widgets to inputs
10042  */
10043 static struct hda_verb alc861_threestack_ch2_init[] = {
10044         /* set pin widget 1Ah (line in) for input */
10045         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10046         /* set pin widget 18h (mic1/2) for input, for mic also enable
10047          * the vref
10048          */
10049         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10050
10051         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10052 #if 0
10053         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10054         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10055 #endif
10056         { } /* end */
10057 };
10058 /*
10059  * 6ch mode
10060  * need to set the codec line out and mic 1 pin widgets to outputs
10061  */
10062 static struct hda_verb alc861_threestack_ch6_init[] = {
10063         /* set pin widget 1Ah (line in) for output (Back Surround)*/
10064         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10065         /* set pin widget 18h (mic1) for output (CLFE)*/
10066         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10067
10068         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10069         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10070
10071         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10072 #if 0
10073         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10074         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10075 #endif
10076         { } /* end */
10077 };
10078
10079 static struct hda_channel_mode alc861_threestack_modes[2] = {
10080         { 2, alc861_threestack_ch2_init },
10081         { 6, alc861_threestack_ch6_init },
10082 };
10083 /* Set mic1 as input and unmute the mixer */
10084 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10085         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10086         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10087         { } /* end */
10088 };
10089 /* Set mic1 as output and mute mixer */
10090 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10091         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10092         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10093         { } /* end */
10094 };
10095
10096 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10097         { 2, alc861_uniwill_m31_ch2_init },
10098         { 4, alc861_uniwill_m31_ch4_init },
10099 };
10100
10101 /* Set mic1 and line-in as input and unmute the mixer */
10102 static struct hda_verb alc861_asus_ch2_init[] = {
10103         /* set pin widget 1Ah (line in) for input */
10104         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10105         /* set pin widget 18h (mic1/2) for input, for mic also enable
10106          * the vref
10107          */
10108         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10109
10110         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10111 #if 0
10112         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10113         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10114 #endif
10115         { } /* end */
10116 };
10117 /* Set mic1 nad line-in as output and mute mixer */
10118 static struct hda_verb alc861_asus_ch6_init[] = {
10119         /* set pin widget 1Ah (line in) for output (Back Surround)*/
10120         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10121         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10122         /* set pin widget 18h (mic1) for output (CLFE)*/
10123         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10124         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10125         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10126         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10127
10128         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10129 #if 0
10130         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10131         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10132 #endif
10133         { } /* end */
10134 };
10135
10136 static struct hda_channel_mode alc861_asus_modes[2] = {
10137         { 2, alc861_asus_ch2_init },
10138         { 6, alc861_asus_ch6_init },
10139 };
10140
10141 /* patch-ALC861 */
10142
10143 static struct snd_kcontrol_new alc861_base_mixer[] = {
10144         /* output mixer control */
10145         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10146         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10147         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10148         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10149         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10150
10151         /*Input mixer control */
10152         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10153            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10154         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10155         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10156         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10157         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10158         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10159         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10160         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10161         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10162
10163         /* Capture mixer control */
10164         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10165         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10166         {
10167                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10168                 .name = "Capture Source",
10169                 .count = 1,
10170                 .info = alc_mux_enum_info,
10171                 .get = alc_mux_enum_get,
10172                 .put = alc_mux_enum_put,
10173         },
10174         { } /* end */
10175 };
10176
10177 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10178         /* output mixer control */
10179         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10180         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10181         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10182         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10183         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10184
10185         /* Input mixer control */
10186         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10187            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10188         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10189         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10190         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10191         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10192         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10193         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10194         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10195         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10196
10197         /* Capture mixer control */
10198         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10199         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10200         {
10201                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10202                 .name = "Capture Source",
10203                 .count = 1,
10204                 .info = alc_mux_enum_info,
10205                 .get = alc_mux_enum_get,
10206                 .put = alc_mux_enum_put,
10207         },
10208         {
10209                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10210                 .name = "Channel Mode",
10211                 .info = alc_ch_mode_info,
10212                 .get = alc_ch_mode_get,
10213                 .put = alc_ch_mode_put,
10214                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10215         },
10216         { } /* end */
10217 };
10218
10219 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
10220         /* output mixer control */
10221         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10222         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10223         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10224         
10225         /*Capture mixer control */
10226         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10227         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10228         {
10229                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10230                 .name = "Capture Source",
10231                 .count = 1,
10232                 .info = alc_mux_enum_info,
10233                 .get = alc_mux_enum_get,
10234                 .put = alc_mux_enum_put,
10235         },
10236
10237         { } /* end */
10238 };
10239
10240 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10241         /* output mixer control */
10242         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10243         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10244         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10245         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10246         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10247
10248         /* Input mixer control */
10249         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10250            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10251         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10252         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10253         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10254         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10255         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10256         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10257         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10258         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10259
10260         /* Capture mixer control */
10261         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10262         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10263         {
10264                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10265                 .name = "Capture Source",
10266                 .count = 1,
10267                 .info = alc_mux_enum_info,
10268                 .get = alc_mux_enum_get,
10269                 .put = alc_mux_enum_put,
10270         },
10271         {
10272                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10273                 .name = "Channel Mode",
10274                 .info = alc_ch_mode_info,
10275                 .get = alc_ch_mode_get,
10276                 .put = alc_ch_mode_put,
10277                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10278         },
10279         { } /* end */
10280 };
10281
10282 static struct snd_kcontrol_new alc861_asus_mixer[] = {
10283         /* output mixer control */
10284         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10285         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10286         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10287         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10288         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10289
10290         /* Input mixer control */
10291         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10292         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10293         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10294         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10295         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10296         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10297         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10298         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10299         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10300         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10301
10302         /* Capture mixer control */
10303         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10304         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10305         {
10306                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10307                 .name = "Capture Source",
10308                 .count = 1,
10309                 .info = alc_mux_enum_info,
10310                 .get = alc_mux_enum_get,
10311                 .put = alc_mux_enum_put,
10312         },
10313         {
10314                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10315                 .name = "Channel Mode",
10316                 .info = alc_ch_mode_info,
10317                 .get = alc_ch_mode_get,
10318                 .put = alc_ch_mode_put,
10319                 .private_value = ARRAY_SIZE(alc861_asus_modes),
10320         },
10321         { }
10322 };
10323
10324 /* additional mixer */
10325 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
10326         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10327         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10328         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10329         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10330         { }
10331 };
10332
10333 /*
10334  * generic initialization of ADC, input mixers and output mixers
10335  */
10336 static struct hda_verb alc861_base_init_verbs[] = {
10337         /*
10338          * Unmute ADC0 and set the default input to mic-in
10339          */
10340         /* port-A for surround (rear panel) */
10341         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10342         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10343         /* port-B for mic-in (rear panel) with vref */
10344         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10345         /* port-C for line-in (rear panel) */
10346         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10347         /* port-D for Front */
10348         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10349         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10350         /* port-E for HP out (front panel) */
10351         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10352         /* route front PCM to HP */
10353         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10354         /* port-F for mic-in (front panel) with vref */
10355         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10356         /* port-G for CLFE (rear panel) */
10357         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10358         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10359         /* port-H for side (rear panel) */
10360         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10361         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10362         /* CD-in */
10363         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10364         /* route front mic to ADC1*/
10365         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10366         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10367         
10368         /* Unmute DAC0~3 & spdif out*/
10369         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10370         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10371         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10372         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10373         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10374         
10375         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10376         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10377         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10378         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10379         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10380         
10381         /* Unmute Stereo Mixer 15 */
10382         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10383         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10384         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10385         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10386
10387         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10388         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10389         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10390         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10391         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10392         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10393         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10394         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10395         /* hp used DAC 3 (Front) */
10396         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10397         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10398
10399         { }
10400 };
10401
10402 static struct hda_verb alc861_threestack_init_verbs[] = {
10403         /*
10404          * Unmute ADC0 and set the default input to mic-in
10405          */
10406         /* port-A for surround (rear panel) */
10407         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10408         /* port-B for mic-in (rear panel) with vref */
10409         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10410         /* port-C for line-in (rear panel) */
10411         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10412         /* port-D for Front */
10413         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10414         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10415         /* port-E for HP out (front panel) */
10416         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10417         /* route front PCM to HP */
10418         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10419         /* port-F for mic-in (front panel) with vref */
10420         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10421         /* port-G for CLFE (rear panel) */
10422         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10423         /* port-H for side (rear panel) */
10424         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10425         /* CD-in */
10426         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10427         /* route front mic to ADC1*/
10428         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10429         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10430         /* Unmute DAC0~3 & spdif out*/
10431         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10432         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10433         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10434         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10435         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10436         
10437         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10438         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10439         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10440         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10441         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10442         
10443         /* Unmute Stereo Mixer 15 */
10444         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10445         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10446         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10447         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10448
10449         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10450         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10451         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10452         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10453         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10454         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10455         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10456         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10457         /* hp used DAC 3 (Front) */
10458         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10459         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10460         { }
10461 };
10462
10463 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
10464         /*
10465          * Unmute ADC0 and set the default input to mic-in
10466          */
10467         /* port-A for surround (rear panel) */
10468         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10469         /* port-B for mic-in (rear panel) with vref */
10470         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10471         /* port-C for line-in (rear panel) */
10472         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10473         /* port-D for Front */
10474         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10475         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10476         /* port-E for HP out (front panel) */
10477         /* this has to be set to VREF80 */
10478         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10479         /* route front PCM to HP */
10480         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10481         /* port-F for mic-in (front panel) with vref */
10482         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10483         /* port-G for CLFE (rear panel) */
10484         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10485         /* port-H for side (rear panel) */
10486         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10487         /* CD-in */
10488         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10489         /* route front mic to ADC1*/
10490         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10491         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10492         /* Unmute DAC0~3 & spdif out*/
10493         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10494         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10495         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10496         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10497         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10498         
10499         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10500         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10501         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10502         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10503         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10504         
10505         /* Unmute Stereo Mixer 15 */
10506         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10507         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10508         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10509         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10510
10511         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10512         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10513         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10514         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10515         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10516         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10517         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10518         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10519         /* hp used DAC 3 (Front) */
10520         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10521         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10522         { }
10523 };
10524
10525 static struct hda_verb alc861_asus_init_verbs[] = {
10526         /*
10527          * Unmute ADC0 and set the default input to mic-in
10528          */
10529         /* port-A for surround (rear panel)
10530          * according to codec#0 this is the HP jack
10531          */
10532         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
10533         /* route front PCM to HP */
10534         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
10535         /* port-B for mic-in (rear panel) with vref */
10536         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10537         /* port-C for line-in (rear panel) */
10538         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10539         /* port-D for Front */
10540         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10541         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10542         /* port-E for HP out (front panel) */
10543         /* this has to be set to VREF80 */
10544         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10545         /* route front PCM to HP */
10546         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10547         /* port-F for mic-in (front panel) with vref */
10548         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10549         /* port-G for CLFE (rear panel) */
10550         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10551         /* port-H for side (rear panel) */
10552         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10553         /* CD-in */
10554         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10555         /* route front mic to ADC1*/
10556         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10557         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10558         /* Unmute DAC0~3 & spdif out*/
10559         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10560         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10561         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10562         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10563         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10564         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10565         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10566         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10567         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10568         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10569         
10570         /* Unmute Stereo Mixer 15 */
10571         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10572         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10573         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10574         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10575
10576         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10577         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10578         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10579         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10580         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10581         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10582         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10583         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10584         /* hp used DAC 3 (Front) */
10585         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10586         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10587         { }
10588 };
10589
10590 /* additional init verbs for ASUS laptops */
10591 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10592         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10593         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10594         { }
10595 };
10596
10597 /*
10598  * generic initialization of ADC, input mixers and output mixers
10599  */
10600 static struct hda_verb alc861_auto_init_verbs[] = {
10601         /*
10602          * Unmute ADC0 and set the default input to mic-in
10603          */
10604         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
10605         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10606         
10607         /* Unmute DAC0~3 & spdif out*/
10608         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10609         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10610         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10611         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10612         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10613         
10614         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10615         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10616         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10617         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10618         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10619         
10620         /* Unmute Stereo Mixer 15 */
10621         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10622         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10623         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10624         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10625
10626         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10627         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10628         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10629         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10630         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10631         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10632         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10633         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10634
10635         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10636         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10637         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10638         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10639         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10640         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10641         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10642         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10643
10644         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
10645
10646         { }
10647 };
10648
10649 static struct hda_verb alc861_toshiba_init_verbs[] = {
10650         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10651
10652         { }
10653 };
10654
10655 /* toggle speaker-output according to the hp-jack state */
10656 static void alc861_toshiba_automute(struct hda_codec *codec)
10657 {
10658         unsigned int present;
10659
10660         present = snd_hda_codec_read(codec, 0x0f, 0,
10661                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10662         snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10663                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10664         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10665                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
10666 }
10667
10668 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10669                                        unsigned int res)
10670 {
10671         if ((res >> 26) == ALC880_HP_EVENT)
10672                 alc861_toshiba_automute(codec);
10673 }
10674
10675 /* pcm configuration: identiacal with ALC880 */
10676 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
10677 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
10678 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
10679 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
10680
10681
10682 #define ALC861_DIGOUT_NID       0x07
10683
10684 static struct hda_channel_mode alc861_8ch_modes[1] = {
10685         { 8, NULL }
10686 };
10687
10688 static hda_nid_t alc861_dac_nids[4] = {
10689         /* front, surround, clfe, side */
10690         0x03, 0x06, 0x05, 0x04
10691 };
10692
10693 static hda_nid_t alc660_dac_nids[3] = {
10694         /* front, clfe, surround */
10695         0x03, 0x05, 0x06
10696 };
10697
10698 static hda_nid_t alc861_adc_nids[1] = {
10699         /* ADC0-2 */
10700         0x08,
10701 };
10702
10703 static struct hda_input_mux alc861_capture_source = {
10704         .num_items = 5,
10705         .items = {
10706                 { "Mic", 0x0 },
10707                 { "Front Mic", 0x3 },
10708                 { "Line", 0x1 },
10709                 { "CD", 0x4 },
10710                 { "Mixer", 0x5 },
10711         },
10712 };
10713
10714 /* fill in the dac_nids table from the parsed pin configuration */
10715 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10716                                      const struct auto_pin_cfg *cfg)
10717 {
10718         int i;
10719         hda_nid_t nid;
10720
10721         spec->multiout.dac_nids = spec->private_dac_nids;
10722         for (i = 0; i < cfg->line_outs; i++) {
10723                 nid = cfg->line_out_pins[i];
10724                 if (nid) {
10725                         if (i >= ARRAY_SIZE(alc861_dac_nids))
10726                                 continue;
10727                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10728                 }
10729         }
10730         spec->multiout.num_dacs = cfg->line_outs;
10731         return 0;
10732 }
10733
10734 /* add playback controls from the parsed DAC table */
10735 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10736                                              const struct auto_pin_cfg *cfg)
10737 {
10738         char name[32];
10739         static const char *chname[4] = {
10740                 "Front", "Surround", NULL /*CLFE*/, "Side"
10741         };
10742         hda_nid_t nid;
10743         int i, idx, err;
10744
10745         for (i = 0; i < cfg->line_outs; i++) {
10746                 nid = spec->multiout.dac_nids[i];
10747                 if (!nid)
10748                         continue;
10749                 if (nid == 0x05) {
10750                         /* Center/LFE */
10751                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10752                                           "Center Playback Switch",
10753                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10754                                                               HDA_OUTPUT));
10755                         if (err < 0)
10756                                 return err;
10757                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10758                                           "LFE Playback Switch",
10759                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10760                                                               HDA_OUTPUT));
10761                         if (err < 0)
10762                                 return err;
10763                 } else {
10764                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10765                              idx++)
10766                                 if (nid == alc861_dac_nids[idx])
10767                                         break;
10768                         sprintf(name, "%s Playback Switch", chname[idx]);
10769                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10770                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10771                                                               HDA_OUTPUT));
10772                         if (err < 0)
10773                                 return err;
10774                 }
10775         }
10776         return 0;
10777 }
10778
10779 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10780 {
10781         int err;
10782         hda_nid_t nid;
10783
10784         if (!pin)
10785                 return 0;
10786
10787         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10788                 nid = 0x03;
10789                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10790                                   "Headphone Playback Switch",
10791                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10792                 if (err < 0)
10793                         return err;
10794                 spec->multiout.hp_nid = nid;
10795         }
10796         return 0;
10797 }
10798
10799 /* create playback/capture controls for input pins */
10800 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10801                                                 const struct auto_pin_cfg *cfg)
10802 {
10803         struct hda_input_mux *imux = &spec->private_imux;
10804         int i, err, idx, idx1;
10805
10806         for (i = 0; i < AUTO_PIN_LAST; i++) {
10807                 switch (cfg->input_pins[i]) {
10808                 case 0x0c:
10809                         idx1 = 1;
10810                         idx = 2;        /* Line In */
10811                         break;
10812                 case 0x0f:
10813                         idx1 = 2;
10814                         idx = 2;        /* Line In */
10815                         break;
10816                 case 0x0d:
10817                         idx1 = 0;
10818                         idx = 1;        /* Mic In */
10819                         break;
10820                 case 0x10:
10821                         idx1 = 3;
10822                         idx = 1;        /* Mic In */
10823                         break;
10824                 case 0x11:
10825                         idx1 = 4;
10826                         idx = 0;        /* CD */
10827                         break;
10828                 default:
10829                         continue;
10830                 }
10831
10832                 err = new_analog_input(spec, cfg->input_pins[i],
10833                                        auto_pin_cfg_labels[i], idx, 0x15);
10834                 if (err < 0)
10835                         return err;
10836
10837                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10838                 imux->items[imux->num_items].index = idx1;
10839                 imux->num_items++;
10840         }
10841         return 0;
10842 }
10843
10844 static struct snd_kcontrol_new alc861_capture_mixer[] = {
10845         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10846         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10847
10848         {
10849                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10850                 /* The multiple "Capture Source" controls confuse alsamixer
10851                  * So call somewhat different..
10852                  *FIXME: the controls appear in the "playback" view!
10853                  */
10854                 /* .name = "Capture Source", */
10855                 .name = "Input Source",
10856                 .count = 1,
10857                 .info = alc_mux_enum_info,
10858                 .get = alc_mux_enum_get,
10859                 .put = alc_mux_enum_put,
10860         },
10861         { } /* end */
10862 };
10863
10864 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10865                                               hda_nid_t nid,
10866                                               int pin_type, int dac_idx)
10867 {
10868         /* set as output */
10869
10870         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10871                             pin_type);
10872         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10873                             AMP_OUT_UNMUTE);
10874
10875 }
10876
10877 static void alc861_auto_init_multi_out(struct hda_codec *codec)
10878 {
10879         struct alc_spec *spec = codec->spec;
10880         int i;
10881
10882         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
10883         for (i = 0; i < spec->autocfg.line_outs; i++) {
10884                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10885                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10886                 if (nid)
10887                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
10888                                                           spec->multiout.dac_nids[i]);
10889         }
10890 }
10891
10892 static void alc861_auto_init_hp_out(struct hda_codec *codec)
10893 {
10894         struct alc_spec *spec = codec->spec;
10895         hda_nid_t pin;
10896
10897         pin = spec->autocfg.hp_pins[0];
10898         if (pin) /* connect to front */
10899                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
10900                                                   spec->multiout.dac_nids[0]);
10901 }
10902
10903 static void alc861_auto_init_analog_input(struct hda_codec *codec)
10904 {
10905         struct alc_spec *spec = codec->spec;
10906         int i;
10907
10908         for (i = 0; i < AUTO_PIN_LAST; i++) {
10909                 hda_nid_t nid = spec->autocfg.input_pins[i];
10910                 if (nid >= 0x0c && nid <= 0x11) {
10911                         snd_hda_codec_write(codec, nid, 0,
10912                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
10913                                             i <= AUTO_PIN_FRONT_MIC ?
10914                                             PIN_VREF80 : PIN_IN);
10915                 }
10916         }
10917 }
10918
10919 /* parse the BIOS configuration and set up the alc_spec */
10920 /* return 1 if successful, 0 if the proper config is not found,
10921  * or a negative error code
10922  */
10923 static int alc861_parse_auto_config(struct hda_codec *codec)
10924 {
10925         struct alc_spec *spec = codec->spec;
10926         int err;
10927         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
10928
10929         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10930                                            alc861_ignore);
10931         if (err < 0)
10932                 return err;
10933         if (!spec->autocfg.line_outs)
10934                 return 0; /* can't find valid BIOS pin config */
10935
10936         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
10937         if (err < 0)
10938                 return err;
10939         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
10940         if (err < 0)
10941                 return err;
10942         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
10943         if (err < 0)
10944                 return err;
10945         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
10946         if (err < 0)
10947                 return err;
10948
10949         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10950
10951         if (spec->autocfg.dig_out_pin)
10952                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
10953
10954         if (spec->kctl_alloc)
10955                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10956
10957         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
10958
10959         spec->num_mux_defs = 1;
10960         spec->input_mux = &spec->private_imux;
10961
10962         spec->adc_nids = alc861_adc_nids;
10963         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
10964         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
10965         spec->num_mixers++;
10966
10967         return 1;
10968 }
10969
10970 /* additional initialization for auto-configuration model */
10971 static void alc861_auto_init(struct hda_codec *codec)
10972 {
10973         alc861_auto_init_multi_out(codec);
10974         alc861_auto_init_hp_out(codec);
10975         alc861_auto_init_analog_input(codec);
10976 }
10977
10978 #ifdef CONFIG_SND_HDA_POWER_SAVE
10979 static struct hda_amp_list alc861_loopbacks[] = {
10980         { 0x15, HDA_INPUT, 0 },
10981         { 0x15, HDA_INPUT, 1 },
10982         { 0x15, HDA_INPUT, 2 },
10983         { 0x15, HDA_INPUT, 3 },
10984         { } /* end */
10985 };
10986 #endif
10987
10988
10989 /*
10990  * configuration and preset
10991  */
10992 static const char *alc861_models[ALC861_MODEL_LAST] = {
10993         [ALC861_3ST]            = "3stack",
10994         [ALC660_3ST]            = "3stack-660",
10995         [ALC861_3ST_DIG]        = "3stack-dig",
10996         [ALC861_6ST_DIG]        = "6stack-dig",
10997         [ALC861_UNIWILL_M31]    = "uniwill-m31",
10998         [ALC861_TOSHIBA]        = "toshiba",
10999         [ALC861_ASUS]           = "asus",
11000         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
11001         [ALC861_AUTO]           = "auto",
11002 };
11003
11004 static struct snd_pci_quirk alc861_cfg_tbl[] = {
11005         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
11006         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11007         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11008         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
11009         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
11010         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
11011         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
11012         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11013          *        Any other models that need this preset?
11014          */
11015         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
11016         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11017         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
11018         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
11019         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11020         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11021         /* FIXME: the below seems conflict */
11022         /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
11023         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
11024         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
11025         {}
11026 };
11027
11028 static struct alc_config_preset alc861_presets[] = {
11029         [ALC861_3ST] = {
11030                 .mixers = { alc861_3ST_mixer },
11031                 .init_verbs = { alc861_threestack_init_verbs },
11032                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11033                 .dac_nids = alc861_dac_nids,
11034                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11035                 .channel_mode = alc861_threestack_modes,
11036                 .need_dac_fix = 1,
11037                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11038                 .adc_nids = alc861_adc_nids,
11039                 .input_mux = &alc861_capture_source,
11040         },
11041         [ALC861_3ST_DIG] = {
11042                 .mixers = { alc861_base_mixer },
11043                 .init_verbs = { alc861_threestack_init_verbs },
11044                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11045                 .dac_nids = alc861_dac_nids,
11046                 .dig_out_nid = ALC861_DIGOUT_NID,
11047                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11048                 .channel_mode = alc861_threestack_modes,
11049                 .need_dac_fix = 1,
11050                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11051                 .adc_nids = alc861_adc_nids,
11052                 .input_mux = &alc861_capture_source,
11053         },
11054         [ALC861_6ST_DIG] = {
11055                 .mixers = { alc861_base_mixer },
11056                 .init_verbs = { alc861_base_init_verbs },
11057                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11058                 .dac_nids = alc861_dac_nids,
11059                 .dig_out_nid = ALC861_DIGOUT_NID,
11060                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11061                 .channel_mode = alc861_8ch_modes,
11062                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11063                 .adc_nids = alc861_adc_nids,
11064                 .input_mux = &alc861_capture_source,
11065         },
11066         [ALC660_3ST] = {
11067                 .mixers = { alc861_3ST_mixer },
11068                 .init_verbs = { alc861_threestack_init_verbs },
11069                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11070                 .dac_nids = alc660_dac_nids,
11071                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11072                 .channel_mode = alc861_threestack_modes,
11073                 .need_dac_fix = 1,
11074                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11075                 .adc_nids = alc861_adc_nids,
11076                 .input_mux = &alc861_capture_source,
11077         },
11078         [ALC861_UNIWILL_M31] = {
11079                 .mixers = { alc861_uniwill_m31_mixer },
11080                 .init_verbs = { alc861_uniwill_m31_init_verbs },
11081                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11082                 .dac_nids = alc861_dac_nids,
11083                 .dig_out_nid = ALC861_DIGOUT_NID,
11084                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11085                 .channel_mode = alc861_uniwill_m31_modes,
11086                 .need_dac_fix = 1,
11087                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11088                 .adc_nids = alc861_adc_nids,
11089                 .input_mux = &alc861_capture_source,
11090         },
11091         [ALC861_TOSHIBA] = {
11092                 .mixers = { alc861_toshiba_mixer },
11093                 .init_verbs = { alc861_base_init_verbs,
11094                                 alc861_toshiba_init_verbs },
11095                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11096                 .dac_nids = alc861_dac_nids,
11097                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11098                 .channel_mode = alc883_3ST_2ch_modes,
11099                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11100                 .adc_nids = alc861_adc_nids,
11101                 .input_mux = &alc861_capture_source,
11102                 .unsol_event = alc861_toshiba_unsol_event,
11103                 .init_hook = alc861_toshiba_automute,
11104         },
11105         [ALC861_ASUS] = {
11106                 .mixers = { alc861_asus_mixer },
11107                 .init_verbs = { alc861_asus_init_verbs },
11108                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11109                 .dac_nids = alc861_dac_nids,
11110                 .dig_out_nid = ALC861_DIGOUT_NID,
11111                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11112                 .channel_mode = alc861_asus_modes,
11113                 .need_dac_fix = 1,
11114                 .hp_nid = 0x06,
11115                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11116                 .adc_nids = alc861_adc_nids,
11117                 .input_mux = &alc861_capture_source,
11118         },
11119         [ALC861_ASUS_LAPTOP] = {
11120                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11121                 .init_verbs = { alc861_asus_init_verbs,
11122                                 alc861_asus_laptop_init_verbs },
11123                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11124                 .dac_nids = alc861_dac_nids,
11125                 .dig_out_nid = ALC861_DIGOUT_NID,
11126                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11127                 .channel_mode = alc883_3ST_2ch_modes,
11128                 .need_dac_fix = 1,
11129                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11130                 .adc_nids = alc861_adc_nids,
11131                 .input_mux = &alc861_capture_source,
11132         },
11133 };
11134
11135
11136 static int patch_alc861(struct hda_codec *codec)
11137 {
11138         struct alc_spec *spec;
11139         int board_config;
11140         int err;
11141
11142         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11143         if (spec == NULL)
11144                 return -ENOMEM;
11145
11146         codec->spec = spec;
11147
11148         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11149                                                   alc861_models,
11150                                                   alc861_cfg_tbl);
11151
11152         if (board_config < 0) {
11153                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11154                        "trying auto-probe from BIOS...\n");
11155                 board_config = ALC861_AUTO;
11156         }
11157
11158         if (board_config == ALC861_AUTO) {
11159                 /* automatic parse from the BIOS config */
11160                 err = alc861_parse_auto_config(codec);
11161                 if (err < 0) {
11162                         alc_free(codec);
11163                         return err;
11164                 } else if (!err) {
11165                         printk(KERN_INFO
11166                                "hda_codec: Cannot set up configuration "
11167                                "from BIOS.  Using base mode...\n");
11168                    board_config = ALC861_3ST_DIG;
11169                 }
11170         }
11171
11172         if (board_config != ALC861_AUTO)
11173                 setup_preset(spec, &alc861_presets[board_config]);
11174
11175         spec->stream_name_analog = "ALC861 Analog";
11176         spec->stream_analog_playback = &alc861_pcm_analog_playback;
11177         spec->stream_analog_capture = &alc861_pcm_analog_capture;
11178
11179         spec->stream_name_digital = "ALC861 Digital";
11180         spec->stream_digital_playback = &alc861_pcm_digital_playback;
11181         spec->stream_digital_capture = &alc861_pcm_digital_capture;
11182
11183         codec->patch_ops = alc_patch_ops;
11184         if (board_config == ALC861_AUTO)
11185                 spec->init_hook = alc861_auto_init;
11186 #ifdef CONFIG_SND_HDA_POWER_SAVE
11187         if (!spec->loopback.amplist)
11188                 spec->loopback.amplist = alc861_loopbacks;
11189 #endif
11190                 
11191         return 0;
11192 }
11193
11194 /*
11195  * ALC861-VD support
11196  *
11197  * Based on ALC882
11198  *
11199  * In addition, an independent DAC
11200  */
11201 #define ALC861VD_DIGOUT_NID     0x06
11202
11203 static hda_nid_t alc861vd_dac_nids[4] = {
11204         /* front, surr, clfe, side surr */
11205         0x02, 0x03, 0x04, 0x05
11206 };
11207
11208 /* dac_nids for ALC660vd are in a different order - according to
11209  * Realtek's driver.
11210  * This should probably tesult in a different mixer for 6stack models
11211  * of ALC660vd codecs, but for now there is only 3stack mixer
11212  * - and it is the same as in 861vd.
11213  * adc_nids in ALC660vd are (is) the same as in 861vd
11214  */
11215 static hda_nid_t alc660vd_dac_nids[3] = {
11216         /* front, rear, clfe, rear_surr */
11217         0x02, 0x04, 0x03
11218 };
11219
11220 static hda_nid_t alc861vd_adc_nids[1] = {
11221         /* ADC0 */
11222         0x09,
11223 };
11224
11225 /* input MUX */
11226 /* FIXME: should be a matrix-type input source selection */
11227 static struct hda_input_mux alc861vd_capture_source = {
11228         .num_items = 4,
11229         .items = {
11230                 { "Mic", 0x0 },
11231                 { "Front Mic", 0x1 },
11232                 { "Line", 0x2 },
11233                 { "CD", 0x4 },
11234         },
11235 };
11236
11237 static struct hda_input_mux alc861vd_dallas_capture_source = {
11238         .num_items = 3,
11239         .items = {
11240                 { "Front Mic", 0x0 },
11241                 { "ATAPI Mic", 0x1 },
11242                 { "Line In", 0x5 },
11243         },
11244 };
11245
11246 static struct hda_input_mux alc861vd_hp_capture_source = {
11247         .num_items = 2,
11248         .items = {
11249                 { "Front Mic", 0x0 },
11250                 { "ATAPI Mic", 0x1 },
11251         },
11252 };
11253
11254 #define alc861vd_mux_enum_info alc_mux_enum_info
11255 #define alc861vd_mux_enum_get alc_mux_enum_get
11256
11257 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11258                                 struct snd_ctl_elem_value *ucontrol)
11259 {
11260         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11261         struct alc_spec *spec = codec->spec;
11262         const struct hda_input_mux *imux = spec->input_mux;
11263         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11264         static hda_nid_t capture_mixers[1] = { 0x22 };
11265         hda_nid_t nid = capture_mixers[adc_idx];
11266         unsigned int *cur_val = &spec->cur_mux[adc_idx];
11267         unsigned int i, idx;
11268
11269         idx = ucontrol->value.enumerated.item[0];
11270         if (idx >= imux->num_items)
11271                 idx = imux->num_items - 1;
11272         if (*cur_val == idx)
11273                 return 0;
11274         for (i = 0; i < imux->num_items; i++) {
11275                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11276                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11277                                          imux->items[i].index,
11278                                          HDA_AMP_MUTE, v);
11279         }
11280         *cur_val = idx;
11281         return 1;
11282 }
11283
11284 /*
11285  * 2ch mode
11286  */
11287 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11288         { 2, NULL }
11289 };
11290
11291 /*
11292  * 6ch mode
11293  */
11294 static struct hda_verb alc861vd_6stack_ch6_init[] = {
11295         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11296         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11297         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11298         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11299         { } /* end */
11300 };
11301
11302 /*
11303  * 8ch mode
11304  */
11305 static struct hda_verb alc861vd_6stack_ch8_init[] = {
11306         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11307         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11308         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11309         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11310         { } /* end */
11311 };
11312
11313 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11314         { 6, alc861vd_6stack_ch6_init },
11315         { 8, alc861vd_6stack_ch8_init },
11316 };
11317
11318 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11319         {
11320                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11321                 .name = "Channel Mode",
11322                 .info = alc_ch_mode_info,
11323                 .get = alc_ch_mode_get,
11324                 .put = alc_ch_mode_put,
11325         },
11326         { } /* end */
11327 };
11328
11329 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11330         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11331         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11332
11333         {
11334                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11335                 /* The multiple "Capture Source" controls confuse alsamixer
11336                  * So call somewhat different..
11337                  *FIXME: the controls appear in the "playback" view!
11338                  */
11339                 /* .name = "Capture Source", */
11340                 .name = "Input Source",
11341                 .count = 1,
11342                 .info = alc861vd_mux_enum_info,
11343                 .get = alc861vd_mux_enum_get,
11344                 .put = alc861vd_mux_enum_put,
11345         },
11346         { } /* end */
11347 };
11348
11349 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11350  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11351  */
11352 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11353         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11354         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11355
11356         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11357         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11358
11359         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11360                                 HDA_OUTPUT),
11361         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11362                                 HDA_OUTPUT),
11363         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11364         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11365
11366         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11367         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11368
11369         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11370
11371         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11372         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11373         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11374
11375         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11376         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11377         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11378
11379         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11380         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11381
11382         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11383         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11384
11385         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11386         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11387
11388         { } /* end */
11389 };
11390
11391 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11392         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11393         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11394
11395         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11396
11397         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11398         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11399         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11400
11401         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11402         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11403         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11404
11405         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11406         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11407
11408         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11409         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11410
11411         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11412         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11413
11414         { } /* end */
11415 };
11416
11417 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11418         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11419         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11420         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11421
11422         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11423
11424         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11425         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11426         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11427
11428         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11429         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11430         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11431
11432         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11433         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11434
11435         { } /* end */
11436 };
11437
11438 /* Pin assignment: Front=0x14, HP = 0x15,
11439  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
11440  */
11441 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
11442         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11443         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11444         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11445         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11446         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11447         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11448         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11449         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11450         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
11451         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
11452         { } /* end */
11453 };
11454
11455 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
11456  *                 Front Mic=0x18, ATAPI Mic = 0x19,
11457  */
11458 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
11459         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11460         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11461         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11462         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11463         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11464         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11465         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11466         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11467         
11468         { } /* end */
11469 };
11470
11471 /*
11472  * generic initialization of ADC, input mixers and output mixers
11473  */
11474 static struct hda_verb alc861vd_volume_init_verbs[] = {
11475         /*
11476          * Unmute ADC0 and set the default input to mic-in
11477          */
11478         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11479         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11480
11481         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
11482          * the analog-loopback mixer widget
11483          */
11484         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11485         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11486         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11487         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11488         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11489         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11490
11491         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
11492         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11493         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11494         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11495         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11496
11497         /*
11498          * Set up output mixers (0x02 - 0x05)
11499          */
11500         /* set vol=0 to output mixers */
11501         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11502         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11503         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11504         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11505
11506         /* set up input amps for analog loopback */
11507         /* Amp Indices: DAC = 0, mixer = 1 */
11508         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11509         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11510         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11511         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11512         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11513         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11514         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11515         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11516
11517         { }
11518 };
11519
11520 /*
11521  * 3-stack pin configuration:
11522  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
11523  */
11524 static struct hda_verb alc861vd_3stack_init_verbs[] = {
11525         /*
11526          * Set pin mode and muting
11527          */
11528         /* set front pin widgets 0x14 for output */
11529         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11530         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11531         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11532
11533         /* Mic (rear) pin: input vref at 80% */
11534         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11535         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11536         /* Front Mic pin: input vref at 80% */
11537         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11538         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11539         /* Line In pin: input */
11540         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11541         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11542         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11543         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11544         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11545         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11546         /* CD pin widget for input */
11547         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11548
11549         { }
11550 };
11551
11552 /*
11553  * 6-stack pin configuration:
11554  */
11555 static struct hda_verb alc861vd_6stack_init_verbs[] = {
11556         /*
11557          * Set pin mode and muting
11558          */
11559         /* set front pin widgets 0x14 for output */
11560         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11561         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11562         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11563
11564         /* Rear Pin: output 1 (0x0d) */
11565         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11566         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11567         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11568         /* CLFE Pin: output 2 (0x0e) */
11569         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11570         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11571         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11572         /* Side Pin: output 3 (0x0f) */
11573         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11574         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11575         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11576
11577         /* Mic (rear) pin: input vref at 80% */
11578         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11579         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11580         /* Front Mic pin: input vref at 80% */
11581         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11582         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11583         /* Line In pin: input */
11584         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11585         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11586         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11587         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11588         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11589         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11590         /* CD pin widget for input */
11591         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11592
11593         { }
11594 };
11595
11596 static struct hda_verb alc861vd_eapd_verbs[] = {
11597         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11598         { }
11599 };
11600
11601 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11602         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11603         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11604         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11605         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11606         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
11607         {}
11608 };
11609
11610 /* toggle speaker-output according to the hp-jack state */
11611 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11612 {
11613         unsigned int present;
11614         unsigned char bits;
11615
11616         present = snd_hda_codec_read(codec, 0x1b, 0,
11617                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11618         bits = present ? HDA_AMP_MUTE : 0;
11619         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11620                                  HDA_AMP_MUTE, bits);
11621 }
11622
11623 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11624 {
11625         unsigned int present;
11626         unsigned char bits;
11627
11628         present = snd_hda_codec_read(codec, 0x18, 0,
11629                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11630         bits = present ? HDA_AMP_MUTE : 0;
11631         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11632                                  HDA_AMP_MUTE, bits);
11633 }
11634
11635 static void alc861vd_lenovo_automute(struct hda_codec *codec)
11636 {
11637         alc861vd_lenovo_hp_automute(codec);
11638         alc861vd_lenovo_mic_automute(codec);
11639 }
11640
11641 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11642                                         unsigned int res)
11643 {
11644         switch (res >> 26) {
11645         case ALC880_HP_EVENT:
11646                 alc861vd_lenovo_hp_automute(codec);
11647                 break;
11648         case ALC880_MIC_EVENT:
11649                 alc861vd_lenovo_mic_automute(codec);
11650                 break;
11651         }
11652 }
11653
11654 static struct hda_verb alc861vd_dallas_verbs[] = {
11655         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11656         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11657         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11658         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11659
11660         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11661         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11662         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11663         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11664         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11665         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11666         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11667         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11668         
11669         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11670         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11671         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11672         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11673         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11674         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11675         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11676         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11677
11678         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11679         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11680         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11681         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11682         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11683         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11684         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11685         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11686
11687         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11688         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11689         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11690         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11691
11692         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11693         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
11694         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11695
11696         { } /* end */
11697 };
11698
11699 /* toggle speaker-output according to the hp-jack state */
11700 static void alc861vd_dallas_automute(struct hda_codec *codec)
11701 {
11702         unsigned int present;
11703
11704         present = snd_hda_codec_read(codec, 0x15, 0,
11705                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11706         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11707                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11708 }
11709
11710 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11711 {
11712         if ((res >> 26) == ALC880_HP_EVENT)
11713                 alc861vd_dallas_automute(codec);
11714 }
11715
11716 #ifdef CONFIG_SND_HDA_POWER_SAVE
11717 #define alc861vd_loopbacks      alc880_loopbacks
11718 #endif
11719
11720 /* pcm configuration: identiacal with ALC880 */
11721 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
11722 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
11723 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
11724 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
11725
11726 /*
11727  * configuration and preset
11728  */
11729 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11730         [ALC660VD_3ST]          = "3stack-660",
11731         [ALC660VD_3ST_DIG]      = "3stack-660-digout",
11732         [ALC861VD_3ST]          = "3stack",
11733         [ALC861VD_3ST_DIG]      = "3stack-digout",
11734         [ALC861VD_6ST_DIG]      = "6stack-digout",
11735         [ALC861VD_LENOVO]       = "lenovo",
11736         [ALC861VD_DALLAS]       = "dallas",
11737         [ALC861VD_HP]           = "hp",
11738         [ALC861VD_AUTO]         = "auto",
11739 };
11740
11741 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
11742         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11743         SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
11744         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
11745         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
11746         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
11747         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
11748         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
11749         /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
11750         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
11751         SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
11752         SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
11753         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11754         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
11755         SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
11756         {}
11757 };
11758
11759 static struct alc_config_preset alc861vd_presets[] = {
11760         [ALC660VD_3ST] = {
11761                 .mixers = { alc861vd_3st_mixer },
11762                 .init_verbs = { alc861vd_volume_init_verbs,
11763                                  alc861vd_3stack_init_verbs },
11764                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11765                 .dac_nids = alc660vd_dac_nids,
11766                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11767                 .adc_nids = alc861vd_adc_nids,
11768                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11769                 .channel_mode = alc861vd_3stack_2ch_modes,
11770                 .input_mux = &alc861vd_capture_source,
11771         },
11772         [ALC660VD_3ST_DIG] = {
11773                 .mixers = { alc861vd_3st_mixer },
11774                 .init_verbs = { alc861vd_volume_init_verbs,
11775                                  alc861vd_3stack_init_verbs },
11776                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11777                 .dac_nids = alc660vd_dac_nids,
11778                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11779                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11780                 .adc_nids = alc861vd_adc_nids,
11781                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11782                 .channel_mode = alc861vd_3stack_2ch_modes,
11783                 .input_mux = &alc861vd_capture_source,
11784         },
11785         [ALC861VD_3ST] = {
11786                 .mixers = { alc861vd_3st_mixer },
11787                 .init_verbs = { alc861vd_volume_init_verbs,
11788                                  alc861vd_3stack_init_verbs },
11789                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11790                 .dac_nids = alc861vd_dac_nids,
11791                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11792                 .channel_mode = alc861vd_3stack_2ch_modes,
11793                 .input_mux = &alc861vd_capture_source,
11794         },
11795         [ALC861VD_3ST_DIG] = {
11796                 .mixers = { alc861vd_3st_mixer },
11797                 .init_verbs = { alc861vd_volume_init_verbs,
11798                                  alc861vd_3stack_init_verbs },
11799                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11800                 .dac_nids = alc861vd_dac_nids,
11801                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11802                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11803                 .channel_mode = alc861vd_3stack_2ch_modes,
11804                 .input_mux = &alc861vd_capture_source,
11805         },
11806         [ALC861VD_6ST_DIG] = {
11807                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11808                 .init_verbs = { alc861vd_volume_init_verbs,
11809                                 alc861vd_6stack_init_verbs },
11810                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11811                 .dac_nids = alc861vd_dac_nids,
11812                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11813                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11814                 .channel_mode = alc861vd_6stack_modes,
11815                 .input_mux = &alc861vd_capture_source,
11816         },
11817         [ALC861VD_LENOVO] = {
11818                 .mixers = { alc861vd_lenovo_mixer },
11819                 .init_verbs = { alc861vd_volume_init_verbs,
11820                                 alc861vd_3stack_init_verbs,
11821                                 alc861vd_eapd_verbs,
11822                                 alc861vd_lenovo_unsol_verbs },
11823                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11824                 .dac_nids = alc660vd_dac_nids,
11825                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11826                 .adc_nids = alc861vd_adc_nids,
11827                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11828                 .channel_mode = alc861vd_3stack_2ch_modes,
11829                 .input_mux = &alc861vd_capture_source,
11830                 .unsol_event = alc861vd_lenovo_unsol_event,
11831                 .init_hook = alc861vd_lenovo_automute,
11832         },
11833         [ALC861VD_DALLAS] = {
11834                 .mixers = { alc861vd_dallas_mixer },
11835                 .init_verbs = { alc861vd_dallas_verbs },
11836                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11837                 .dac_nids = alc861vd_dac_nids,
11838                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11839                 .adc_nids = alc861vd_adc_nids,
11840                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11841                 .channel_mode = alc861vd_3stack_2ch_modes,
11842                 .input_mux = &alc861vd_dallas_capture_source,
11843                 .unsol_event = alc861vd_dallas_unsol_event,
11844                 .init_hook = alc861vd_dallas_automute,
11845         },
11846         [ALC861VD_HP] = {
11847                 .mixers = { alc861vd_hp_mixer },
11848                 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11849                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11850                 .dac_nids = alc861vd_dac_nids,
11851                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11852                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11853                 .adc_nids = alc861vd_adc_nids,
11854                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11855                 .channel_mode = alc861vd_3stack_2ch_modes,
11856                 .input_mux = &alc861vd_hp_capture_source,
11857                 .unsol_event = alc861vd_dallas_unsol_event,
11858                 .init_hook = alc861vd_dallas_automute,
11859         },              
11860 };
11861
11862 /*
11863  * BIOS auto configuration
11864  */
11865 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11866                                 hda_nid_t nid, int pin_type, int dac_idx)
11867 {
11868         /* set as output */
11869         snd_hda_codec_write(codec, nid, 0,
11870                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11871         snd_hda_codec_write(codec, nid, 0,
11872                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11873 }
11874
11875 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11876 {
11877         struct alc_spec *spec = codec->spec;
11878         int i;
11879
11880         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
11881         for (i = 0; i <= HDA_SIDE; i++) {
11882                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11883                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11884                 if (nid)
11885                         alc861vd_auto_set_output_and_unmute(codec, nid,
11886                                                             pin_type, i);
11887         }
11888 }
11889
11890
11891 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
11892 {
11893         struct alc_spec *spec = codec->spec;
11894         hda_nid_t pin;
11895
11896         pin = spec->autocfg.hp_pins[0];
11897         if (pin) /* connect to front and  use dac 0 */
11898                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11899 }
11900
11901 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
11902 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
11903
11904 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
11905 {
11906         struct alc_spec *spec = codec->spec;
11907         int i;
11908
11909         for (i = 0; i < AUTO_PIN_LAST; i++) {
11910                 hda_nid_t nid = spec->autocfg.input_pins[i];
11911                 if (alc861vd_is_input_pin(nid)) {
11912                         snd_hda_codec_write(codec, nid, 0,
11913                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
11914                                         i <= AUTO_PIN_FRONT_MIC ?
11915                                                         PIN_VREF80 : PIN_IN);
11916                         if (nid != ALC861VD_PIN_CD_NID)
11917                                 snd_hda_codec_write(codec, nid, 0,
11918                                                 AC_VERB_SET_AMP_GAIN_MUTE,
11919                                                 AMP_OUT_MUTE);
11920                 }
11921         }
11922 }
11923
11924 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
11925 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
11926
11927 /* add playback controls from the parsed DAC table */
11928 /* Based on ALC880 version. But ALC861VD has separate,
11929  * different NIDs for mute/unmute switch and volume control */
11930 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
11931                                              const struct auto_pin_cfg *cfg)
11932 {
11933         char name[32];
11934         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
11935         hda_nid_t nid_v, nid_s;
11936         int i, err;
11937
11938         for (i = 0; i < cfg->line_outs; i++) {
11939                 if (!spec->multiout.dac_nids[i])
11940                         continue;
11941                 nid_v = alc861vd_idx_to_mixer_vol(
11942                                 alc880_dac_to_idx(
11943                                         spec->multiout.dac_nids[i]));
11944                 nid_s = alc861vd_idx_to_mixer_switch(
11945                                 alc880_dac_to_idx(
11946                                         spec->multiout.dac_nids[i]));
11947
11948                 if (i == 2) {
11949                         /* Center/LFE */
11950                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11951                                           "Center Playback Volume",
11952                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
11953                                                               HDA_OUTPUT));
11954                         if (err < 0)
11955                                 return err;
11956                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11957                                           "LFE Playback Volume",
11958                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
11959                                                               HDA_OUTPUT));
11960                         if (err < 0)
11961                                 return err;
11962                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11963                                           "Center Playback Switch",
11964                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
11965                                                               HDA_INPUT));
11966                         if (err < 0)
11967                                 return err;
11968                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11969                                           "LFE Playback Switch",
11970                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
11971                                                               HDA_INPUT));
11972                         if (err < 0)
11973                                 return err;
11974                 } else {
11975                         sprintf(name, "%s Playback Volume", chname[i]);
11976                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11977                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
11978                                                               HDA_OUTPUT));
11979                         if (err < 0)
11980                                 return err;
11981                         sprintf(name, "%s Playback Switch", chname[i]);
11982                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11983                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
11984                                                               HDA_INPUT));
11985                         if (err < 0)
11986                                 return err;
11987                 }
11988         }
11989         return 0;
11990 }
11991
11992 /* add playback controls for speaker and HP outputs */
11993 /* Based on ALC880 version. But ALC861VD has separate,
11994  * different NIDs for mute/unmute switch and volume control */
11995 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
11996                                         hda_nid_t pin, const char *pfx)
11997 {
11998         hda_nid_t nid_v, nid_s;
11999         int err;
12000         char name[32];
12001
12002         if (!pin)
12003                 return 0;
12004
12005         if (alc880_is_fixed_pin(pin)) {
12006                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12007                 /* specify the DAC as the extra output */
12008                 if (!spec->multiout.hp_nid)
12009                         spec->multiout.hp_nid = nid_v;
12010                 else
12011                         spec->multiout.extra_out_nid[0] = nid_v;
12012                 /* control HP volume/switch on the output mixer amp */
12013                 nid_v = alc861vd_idx_to_mixer_vol(
12014                                 alc880_fixed_pin_idx(pin));
12015                 nid_s = alc861vd_idx_to_mixer_switch(
12016                                 alc880_fixed_pin_idx(pin));
12017
12018                 sprintf(name, "%s Playback Volume", pfx);
12019                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12020                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12021                 if (err < 0)
12022                         return err;
12023                 sprintf(name, "%s Playback Switch", pfx);
12024                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12025                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12026                 if (err < 0)
12027                         return err;
12028         } else if (alc880_is_multi_pin(pin)) {
12029                 /* set manual connection */
12030                 /* we have only a switch on HP-out PIN */
12031                 sprintf(name, "%s Playback Switch", pfx);
12032                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12033                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12034                 if (err < 0)
12035                         return err;
12036         }
12037         return 0;
12038 }
12039
12040 /* parse the BIOS configuration and set up the alc_spec
12041  * return 1 if successful, 0 if the proper config is not found,
12042  * or a negative error code
12043  * Based on ALC880 version - had to change it to override
12044  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12045 static int alc861vd_parse_auto_config(struct hda_codec *codec)
12046 {
12047         struct alc_spec *spec = codec->spec;
12048         int err;
12049         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12050
12051         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12052                                            alc861vd_ignore);
12053         if (err < 0)
12054                 return err;
12055         if (!spec->autocfg.line_outs)
12056                 return 0; /* can't find valid BIOS pin config */
12057
12058         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12059         if (err < 0)
12060                 return err;
12061         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12062         if (err < 0)
12063                 return err;
12064         err = alc861vd_auto_create_extra_out(spec,
12065                                              spec->autocfg.speaker_pins[0],
12066                                              "Speaker");
12067         if (err < 0)
12068                 return err;
12069         err = alc861vd_auto_create_extra_out(spec,
12070                                              spec->autocfg.hp_pins[0],
12071                                              "Headphone");
12072         if (err < 0)
12073                 return err;
12074         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12075         if (err < 0)
12076                 return err;
12077
12078         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12079
12080         if (spec->autocfg.dig_out_pin)
12081                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12082
12083         if (spec->kctl_alloc)
12084                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12085
12086         spec->init_verbs[spec->num_init_verbs++]
12087                 = alc861vd_volume_init_verbs;
12088
12089         spec->num_mux_defs = 1;
12090         spec->input_mux = &spec->private_imux;
12091
12092         err = alc_auto_add_mic_boost(codec);
12093         if (err < 0)
12094                 return err;
12095
12096         return 1;
12097 }
12098
12099 /* additional initialization for auto-configuration model */
12100 static void alc861vd_auto_init(struct hda_codec *codec)
12101 {
12102         alc861vd_auto_init_multi_out(codec);
12103         alc861vd_auto_init_hp_out(codec);
12104         alc861vd_auto_init_analog_input(codec);
12105 }
12106
12107 static int patch_alc861vd(struct hda_codec *codec)
12108 {
12109         struct alc_spec *spec;
12110         int err, board_config;
12111
12112         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12113         if (spec == NULL)
12114                 return -ENOMEM;
12115
12116         codec->spec = spec;
12117
12118         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12119                                                   alc861vd_models,
12120                                                   alc861vd_cfg_tbl);
12121
12122         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12123                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12124                         "ALC861VD, trying auto-probe from BIOS...\n");
12125                 board_config = ALC861VD_AUTO;
12126         }
12127
12128         if (board_config == ALC861VD_AUTO) {
12129                 /* automatic parse from the BIOS config */
12130                 err = alc861vd_parse_auto_config(codec);
12131                 if (err < 0) {
12132                         alc_free(codec);
12133                         return err;
12134                 } else if (!err) {
12135                         printk(KERN_INFO
12136                                "hda_codec: Cannot set up configuration "
12137                                "from BIOS.  Using base mode...\n");
12138                         board_config = ALC861VD_3ST;
12139                 }
12140         }
12141
12142         if (board_config != ALC861VD_AUTO)
12143                 setup_preset(spec, &alc861vd_presets[board_config]);
12144
12145         spec->stream_name_analog = "ALC861VD Analog";
12146         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12147         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12148
12149         spec->stream_name_digital = "ALC861VD Digital";
12150         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12151         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12152
12153         spec->adc_nids = alc861vd_adc_nids;
12154         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12155
12156         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12157         spec->num_mixers++;
12158
12159         codec->patch_ops = alc_patch_ops;
12160
12161         if (board_config == ALC861VD_AUTO)
12162                 spec->init_hook = alc861vd_auto_init;
12163 #ifdef CONFIG_SND_HDA_POWER_SAVE
12164         if (!spec->loopback.amplist)
12165                 spec->loopback.amplist = alc861vd_loopbacks;
12166 #endif
12167
12168         return 0;
12169 }
12170
12171 /*
12172  * ALC662 support
12173  *
12174  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12175  * configuration.  Each pin widget can choose any input DACs and a mixer.
12176  * Each ADC is connected from a mixer of all inputs.  This makes possible
12177  * 6-channel independent captures.
12178  *
12179  * In addition, an independent DAC for the multi-playback (not used in this
12180  * driver yet).
12181  */
12182 #define ALC662_DIGOUT_NID       0x06
12183 #define ALC662_DIGIN_NID        0x0a
12184
12185 static hda_nid_t alc662_dac_nids[4] = {
12186         /* front, rear, clfe, rear_surr */
12187         0x02, 0x03, 0x04
12188 };
12189
12190 static hda_nid_t alc662_adc_nids[1] = {
12191         /* ADC1-2 */
12192         0x09,
12193 };
12194 /* input MUX */
12195 /* FIXME: should be a matrix-type input source selection */
12196
12197 static struct hda_input_mux alc662_capture_source = {
12198         .num_items = 4,
12199         .items = {
12200                 { "Mic", 0x0 },
12201                 { "Front Mic", 0x1 },
12202                 { "Line", 0x2 },
12203                 { "CD", 0x4 },
12204         },
12205 };
12206
12207 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12208         .num_items = 2,
12209         .items = {
12210                 { "Mic", 0x1 },
12211                 { "Line", 0x2 },
12212         },
12213 };
12214
12215 static struct hda_input_mux alc662_eeepc_capture_source = {
12216         .num_items = 2,
12217         .items = {
12218                 { "i-Mic", 0x1 },
12219                 { "e-Mic", 0x0 },
12220         },
12221 };
12222
12223 #define alc662_mux_enum_info alc_mux_enum_info
12224 #define alc662_mux_enum_get alc_mux_enum_get
12225
12226 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12227                                struct snd_ctl_elem_value *ucontrol)
12228 {
12229         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12230         struct alc_spec *spec = codec->spec;
12231         const struct hda_input_mux *imux = spec->input_mux;
12232         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
12233         static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
12234         hda_nid_t nid = capture_mixers[adc_idx];
12235         unsigned int *cur_val = &spec->cur_mux[adc_idx];
12236         unsigned int i, idx;
12237
12238         idx = ucontrol->value.enumerated.item[0];
12239         if (idx >= imux->num_items)
12240                 idx = imux->num_items - 1;
12241         if (*cur_val == idx)
12242                 return 0;
12243         for (i = 0; i < imux->num_items; i++) {
12244                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12245                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12246                                          imux->items[i].index,
12247                                          HDA_AMP_MUTE, v);
12248         }
12249         *cur_val = idx;
12250         return 1;
12251 }
12252 /*
12253  * 2ch mode
12254  */
12255 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12256         { 2, NULL }
12257 };
12258
12259 /*
12260  * 2ch mode
12261  */
12262 static struct hda_verb alc662_3ST_ch2_init[] = {
12263         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12264         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12265         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12266         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12267         { } /* end */
12268 };
12269
12270 /*
12271  * 6ch mode
12272  */
12273 static struct hda_verb alc662_3ST_ch6_init[] = {
12274         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12275         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12276         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12277         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12278         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12279         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12280         { } /* end */
12281 };
12282
12283 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12284         { 2, alc662_3ST_ch2_init },
12285         { 6, alc662_3ST_ch6_init },
12286 };
12287
12288 /*
12289  * 2ch mode
12290  */
12291 static struct hda_verb alc662_sixstack_ch6_init[] = {
12292         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12293         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12294         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12295         { } /* end */
12296 };
12297
12298 /*
12299  * 6ch mode
12300  */
12301 static struct hda_verb alc662_sixstack_ch8_init[] = {
12302         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12303         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12304         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12305         { } /* end */
12306 };
12307
12308 static struct hda_channel_mode alc662_5stack_modes[2] = {
12309         { 2, alc662_sixstack_ch6_init },
12310         { 6, alc662_sixstack_ch8_init },
12311 };
12312
12313 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12314  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12315  */
12316
12317 static struct snd_kcontrol_new alc662_base_mixer[] = {
12318         /* output mixer control */
12319         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12320         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12321         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12322         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12323         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12324         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12325         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12326         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12327         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12328
12329         /*Input mixer control */
12330         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12331         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12332         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12333         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12334         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12335         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12336         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12337         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
12338
12339         /* Capture mixer control */
12340         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12341         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12342         {
12343                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12344                 .name = "Capture Source",
12345                 .count = 1,
12346                 .info = alc_mux_enum_info,
12347                 .get = alc_mux_enum_get,
12348                 .put = alc_mux_enum_put,
12349         },
12350         { } /* end */
12351 };
12352
12353 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12354         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12355         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12356         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12357         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12358         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12359         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12360         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12361         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12362         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12363         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12364         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12365         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12366         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12367         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12368         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12369         {
12370                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12371                 /* .name = "Capture Source", */
12372                 .name = "Input Source",
12373                 .count = 1,
12374                 .info = alc662_mux_enum_info,
12375                 .get = alc662_mux_enum_get,
12376                 .put = alc662_mux_enum_put,
12377         },
12378         { } /* end */
12379 };
12380
12381 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12382         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12383         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12384         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12385         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12386         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12387         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12388         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12389         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12390         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12391         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12392         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12393         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12394         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12395         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12396         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12397         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12398         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12399         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12400         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12401         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12402         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12403         {
12404                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12405                 /* .name = "Capture Source", */
12406                 .name = "Input Source",
12407                 .count = 1,
12408                 .info = alc662_mux_enum_info,
12409                 .get = alc662_mux_enum_get,
12410                 .put = alc662_mux_enum_put,
12411         },
12412         { } /* end */
12413 };
12414
12415 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12416         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12417         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12418         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12419         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
12420         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12421         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12422         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12423         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12424         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12425         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12426         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12427         {
12428                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12429                 /* .name = "Capture Source", */
12430                 .name = "Input Source",
12431                 .count = 1,
12432                 .info = alc662_mux_enum_info,
12433                 .get = alc662_mux_enum_get,
12434                 .put = alc662_mux_enum_put,
12435         },
12436         { } /* end */
12437 };
12438
12439 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
12440         HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12441
12442         HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12443         HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12444
12445         HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12446         HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12447         HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12448
12449         HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12450         HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12451         HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12452         { } /* end */
12453 };
12454
12455 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12456         {
12457                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12458                 .name = "Channel Mode",
12459                 .info = alc_ch_mode_info,
12460                 .get = alc_ch_mode_get,
12461                 .put = alc_ch_mode_put,
12462         },
12463         { } /* end */
12464 };
12465
12466 static struct hda_verb alc662_init_verbs[] = {
12467         /* ADC: mute amp left and right */
12468         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12469         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12470         /* Front mixer: unmute input/output amp left and right (volume = 0) */
12471
12472         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12473         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12474         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12475         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12476         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12477
12478         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12479         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12480         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12481         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12482         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12483         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12484
12485         /* Front Pin: output 0 (0x0c) */
12486         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12487         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12488
12489         /* Rear Pin: output 1 (0x0d) */
12490         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12491         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12492
12493         /* CLFE Pin: output 2 (0x0e) */
12494         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12495         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12496
12497         /* Mic (rear) pin: input vref at 80% */
12498         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12499         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12500         /* Front Mic pin: input vref at 80% */
12501         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12502         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12503         /* Line In pin: input */
12504         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12505         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12506         /* Line-2 In: Headphone output (output 0 - 0x0c) */
12507         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12508         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12509         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12510         /* CD pin widget for input */
12511         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12512
12513         /* FIXME: use matrix-type input source selection */
12514         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12515         /* Input mixer */
12516         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12517         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12518         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12519         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12520
12521         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12522         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12523         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12524         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12525         { }
12526 };
12527
12528 static struct hda_verb alc662_sue_init_verbs[] = {
12529         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
12530         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
12531         {}
12532 };
12533
12534 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12535         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12536         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12537         {}
12538 };
12539
12540 /*
12541  * generic initialization of ADC, input mixers and output mixers
12542  */
12543 static struct hda_verb alc662_auto_init_verbs[] = {
12544         /*
12545          * Unmute ADC and set the default input to mic-in
12546          */
12547         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12548         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12549
12550         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12551          * mixer widget
12552          * Note: PASD motherboards uses the Line In 2 as the input for front
12553          * panel mic (mic 2)
12554          */
12555         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12556         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12557         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12558         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12559         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12560         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12561
12562         /*
12563          * Set up output mixers (0x0c - 0x0f)
12564          */
12565         /* set vol=0 to output mixers */
12566         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12567         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12568         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12569
12570         /* set up input amps for analog loopback */
12571         /* Amp Indices: DAC = 0, mixer = 1 */
12572         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12573         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12574         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12575         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12576         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12577         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12578
12579
12580         /* FIXME: use matrix-type input source selection */
12581         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12582         /* Input mixer */
12583         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12584         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12585         { }
12586 };
12587
12588 /* capture mixer elements */
12589 static struct snd_kcontrol_new alc662_capture_mixer[] = {
12590         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12591         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12592         {
12593                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12594                 /* The multiple "Capture Source" controls confuse alsamixer
12595                  * So call somewhat different..
12596                  * FIXME: the controls appear in the "playback" view!
12597                  */
12598                 /* .name = "Capture Source", */
12599                 .name = "Input Source",
12600                 .count = 1,
12601                 .info = alc882_mux_enum_info,
12602                 .get = alc882_mux_enum_get,
12603                 .put = alc882_mux_enum_put,
12604         },
12605         { } /* end */
12606 };
12607
12608 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12609 {
12610         unsigned int present;
12611         unsigned char bits;
12612
12613         present = snd_hda_codec_read(codec, 0x14, 0,
12614                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12615         bits = present ? HDA_AMP_MUTE : 0;
12616         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12617                                  HDA_AMP_MUTE, bits);
12618 }
12619
12620 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12621 {
12622         unsigned int present;
12623         unsigned char bits;
12624
12625         present = snd_hda_codec_read(codec, 0x1b, 0,
12626                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12627         bits = present ? HDA_AMP_MUTE : 0;
12628         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12629                                  HDA_AMP_MUTE, bits);
12630         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12631                                  HDA_AMP_MUTE, bits);
12632 }
12633
12634 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12635                                            unsigned int res)
12636 {
12637         if ((res >> 26) == ALC880_HP_EVENT)
12638                 alc662_lenovo_101e_all_automute(codec);
12639         if ((res >> 26) == ALC880_FRONT_EVENT)
12640                 alc662_lenovo_101e_ispeaker_automute(codec);
12641 }
12642
12643 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12644 {
12645         unsigned int present;
12646
12647         present = snd_hda_codec_read(codec, 0x18, 0,
12648                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12649         snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12650                             0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12651         snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12652                             0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12653         snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12654                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12655         snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12656                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12657 }
12658
12659 /* unsolicited event for HP jack sensing */
12660 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12661                                      unsigned int res)
12662 {
12663         if ((res >> 26) == ALC880_HP_EVENT)
12664                 alc262_hippo1_automute( codec );
12665
12666         if ((res >> 26) == ALC880_MIC_EVENT)
12667                 alc662_eeepc_mic_automute(codec);
12668 }
12669
12670 static void alc662_eeepc_inithook(struct hda_codec *codec)
12671 {
12672         alc262_hippo1_automute( codec );
12673         alc662_eeepc_mic_automute(codec);
12674 }
12675
12676 #ifdef CONFIG_SND_HDA_POWER_SAVE
12677 #define alc662_loopbacks        alc880_loopbacks
12678 #endif
12679
12680
12681 /* pcm configuration: identiacal with ALC880 */
12682 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
12683 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
12684 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
12685 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
12686
12687 /*
12688  * configuration and preset
12689  */
12690 static const char *alc662_models[ALC662_MODEL_LAST] = {
12691         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
12692         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
12693         [ALC662_3ST_6ch]        = "3stack-6ch",
12694         [ALC662_5ST_DIG]        = "6stack-dig",
12695         [ALC662_LENOVO_101E]    = "lenovo-101e",
12696         [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
12697         [ALC662_AUTO]           = "auto",
12698 };
12699
12700 static struct snd_pci_quirk alc662_cfg_tbl[] = {
12701         SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12702         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12703         {}
12704 };
12705
12706 static struct alc_config_preset alc662_presets[] = {
12707         [ALC662_3ST_2ch_DIG] = {
12708                 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
12709                 .init_verbs = { alc662_init_verbs },
12710                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12711                 .dac_nids = alc662_dac_nids,
12712                 .dig_out_nid = ALC662_DIGOUT_NID,
12713                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12714                 .adc_nids = alc662_adc_nids,
12715                 .dig_in_nid = ALC662_DIGIN_NID,
12716                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12717                 .channel_mode = alc662_3ST_2ch_modes,
12718                 .input_mux = &alc662_capture_source,
12719         },
12720         [ALC662_3ST_6ch_DIG] = {
12721                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12722                             alc662_capture_mixer },
12723                 .init_verbs = { alc662_init_verbs },
12724                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12725                 .dac_nids = alc662_dac_nids,
12726                 .dig_out_nid = ALC662_DIGOUT_NID,
12727                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12728                 .adc_nids = alc662_adc_nids,
12729                 .dig_in_nid = ALC662_DIGIN_NID,
12730                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12731                 .channel_mode = alc662_3ST_6ch_modes,
12732                 .need_dac_fix = 1,
12733                 .input_mux = &alc662_capture_source,
12734         },
12735         [ALC662_3ST_6ch] = {
12736                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12737                             alc662_capture_mixer },
12738                 .init_verbs = { alc662_init_verbs },
12739                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12740                 .dac_nids = alc662_dac_nids,
12741                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12742                 .adc_nids = alc662_adc_nids,
12743                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12744                 .channel_mode = alc662_3ST_6ch_modes,
12745                 .need_dac_fix = 1,
12746                 .input_mux = &alc662_capture_source,
12747         },
12748         [ALC662_5ST_DIG] = {
12749                 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
12750                             alc662_capture_mixer },
12751                 .init_verbs = { alc662_init_verbs },
12752                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12753                 .dac_nids = alc662_dac_nids,
12754                 .dig_out_nid = ALC662_DIGOUT_NID,
12755                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12756                 .adc_nids = alc662_adc_nids,
12757                 .dig_in_nid = ALC662_DIGIN_NID,
12758                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12759                 .channel_mode = alc662_5stack_modes,
12760                 .input_mux = &alc662_capture_source,
12761         },
12762         [ALC662_LENOVO_101E] = {
12763                 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
12764                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12765                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12766                 .dac_nids = alc662_dac_nids,
12767                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12768                 .adc_nids = alc662_adc_nids,
12769                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12770                 .channel_mode = alc662_3ST_2ch_modes,
12771                 .input_mux = &alc662_lenovo_101e_capture_source,
12772                 .unsol_event = alc662_lenovo_101e_unsol_event,
12773                 .init_hook = alc662_lenovo_101e_all_automute,
12774         },
12775         [ALC662_ASUS_EEEPC_P701] = {
12776                 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12777                 .init_verbs = { alc662_init_verbs,
12778                                 alc662_eeepc_sue_init_verbs },
12779                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12780                 .dac_nids = alc662_dac_nids,
12781                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12782                 .adc_nids = alc662_adc_nids,
12783                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12784                 .channel_mode = alc662_3ST_2ch_modes,
12785                 .input_mux = &alc662_eeepc_capture_source,
12786                 .unsol_event = alc662_eeepc_unsol_event,
12787                 .init_hook = alc662_eeepc_inithook,
12788         },
12789
12790 };
12791
12792
12793 /*
12794  * BIOS auto configuration
12795  */
12796
12797 /* add playback controls from the parsed DAC table */
12798 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12799                                              const struct auto_pin_cfg *cfg)
12800 {
12801         char name[32];
12802         static const char *chname[4] = {
12803                 "Front", "Surround", NULL /*CLFE*/, "Side"
12804         };
12805         hda_nid_t nid;
12806         int i, err;
12807
12808         for (i = 0; i < cfg->line_outs; i++) {
12809                 if (!spec->multiout.dac_nids[i])
12810                         continue;
12811                 nid = alc880_idx_to_dac(i);
12812                 if (i == 2) {
12813                         /* Center/LFE */
12814                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
12815                                           "Center Playback Volume",
12816                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12817                                                               HDA_OUTPUT));
12818                         if (err < 0)
12819                                 return err;
12820                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
12821                                           "LFE Playback Volume",
12822                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12823                                                               HDA_OUTPUT));
12824                         if (err < 0)
12825                                 return err;
12826                         err = add_control(spec, ALC_CTL_BIND_MUTE,
12827                                           "Center Playback Switch",
12828                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12829                                                               HDA_INPUT));
12830                         if (err < 0)
12831                                 return err;
12832                         err = add_control(spec, ALC_CTL_BIND_MUTE,
12833                                           "LFE Playback Switch",
12834                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12835                                                               HDA_INPUT));
12836                         if (err < 0)
12837                                 return err;
12838                 } else {
12839                         sprintf(name, "%s Playback Volume", chname[i]);
12840                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12841                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12842                                                               HDA_OUTPUT));
12843                         if (err < 0)
12844                                 return err;
12845                         sprintf(name, "%s Playback Switch", chname[i]);
12846                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12847                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12848                                                               HDA_INPUT));
12849                         if (err < 0)
12850                                 return err;
12851                 }
12852         }
12853         return 0;
12854 }
12855
12856 /* add playback controls for speaker and HP outputs */
12857 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12858                                         const char *pfx)
12859 {
12860         hda_nid_t nid;
12861         int err;
12862         char name[32];
12863
12864         if (!pin)
12865                 return 0;
12866
12867         if (alc880_is_fixed_pin(pin)) {
12868                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12869                 /* printk("DAC nid=%x\n",nid); */
12870                 /* specify the DAC as the extra output */
12871                 if (!spec->multiout.hp_nid)
12872                         spec->multiout.hp_nid = nid;
12873                 else
12874                         spec->multiout.extra_out_nid[0] = nid;
12875                 /* control HP volume/switch on the output mixer amp */
12876                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12877                 sprintf(name, "%s Playback Volume", pfx);
12878                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12879                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12880                 if (err < 0)
12881                         return err;
12882                 sprintf(name, "%s Playback Switch", pfx);
12883                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12884                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12885                 if (err < 0)
12886                         return err;
12887         } else if (alc880_is_multi_pin(pin)) {
12888                 /* set manual connection */
12889                 /* we have only a switch on HP-out PIN */
12890                 sprintf(name, "%s Playback Switch", pfx);
12891                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12892                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12893                 if (err < 0)
12894                         return err;
12895         }
12896         return 0;
12897 }
12898
12899 /* create playback/capture controls for input pins */
12900 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12901                                                 const struct auto_pin_cfg *cfg)
12902 {
12903         struct hda_input_mux *imux = &spec->private_imux;
12904         int i, err, idx;
12905
12906         for (i = 0; i < AUTO_PIN_LAST; i++) {
12907                 if (alc880_is_input_pin(cfg->input_pins[i])) {
12908                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
12909                         err = new_analog_input(spec, cfg->input_pins[i],
12910                                                auto_pin_cfg_labels[i],
12911                                                idx, 0x0b);
12912                         if (err < 0)
12913                                 return err;
12914                         imux->items[imux->num_items].label =
12915                                 auto_pin_cfg_labels[i];
12916                         imux->items[imux->num_items].index =
12917                                 alc880_input_pin_idx(cfg->input_pins[i]);
12918                         imux->num_items++;
12919                 }
12920         }
12921         return 0;
12922 }
12923
12924 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12925                                               hda_nid_t nid, int pin_type,
12926                                               int dac_idx)
12927 {
12928         /* set as output */
12929         snd_hda_codec_write(codec, nid, 0,
12930                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12931         snd_hda_codec_write(codec, nid, 0,
12932                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12933         /* need the manual connection? */
12934         if (alc880_is_multi_pin(nid)) {
12935                 struct alc_spec *spec = codec->spec;
12936                 int idx = alc880_multi_pin_idx(nid);
12937                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
12938                                     AC_VERB_SET_CONNECT_SEL,
12939                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
12940         }
12941 }
12942
12943 static void alc662_auto_init_multi_out(struct hda_codec *codec)
12944 {
12945         struct alc_spec *spec = codec->spec;
12946         int i;
12947
12948         for (i = 0; i <= HDA_SIDE; i++) {
12949                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12950                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12951                 if (nid)
12952                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
12953                                                           i);
12954         }
12955 }
12956
12957 static void alc662_auto_init_hp_out(struct hda_codec *codec)
12958 {
12959         struct alc_spec *spec = codec->spec;
12960         hda_nid_t pin;
12961
12962         pin = spec->autocfg.hp_pins[0];
12963         if (pin) /* connect to front */
12964                 /* use dac 0 */
12965                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12966 }
12967
12968 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
12969 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
12970
12971 static void alc662_auto_init_analog_input(struct hda_codec *codec)
12972 {
12973         struct alc_spec *spec = codec->spec;
12974         int i;
12975
12976         for (i = 0; i < AUTO_PIN_LAST; i++) {
12977                 hda_nid_t nid = spec->autocfg.input_pins[i];
12978                 if (alc662_is_input_pin(nid)) {
12979                         snd_hda_codec_write(codec, nid, 0,
12980                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
12981                                             (i <= AUTO_PIN_FRONT_MIC ?
12982                                              PIN_VREF80 : PIN_IN));
12983                         if (nid != ALC662_PIN_CD_NID)
12984                                 snd_hda_codec_write(codec, nid, 0,
12985                                                     AC_VERB_SET_AMP_GAIN_MUTE,
12986                                                     AMP_OUT_MUTE);
12987                 }
12988         }
12989 }
12990
12991 static int alc662_parse_auto_config(struct hda_codec *codec)
12992 {
12993         struct alc_spec *spec = codec->spec;
12994         int err;
12995         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
12996
12997         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12998                                            alc662_ignore);
12999         if (err < 0)
13000                 return err;
13001         if (!spec->autocfg.line_outs)
13002                 return 0; /* can't find valid BIOS pin config */
13003
13004         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13005         if (err < 0)
13006                 return err;
13007         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13008         if (err < 0)
13009                 return err;
13010         err = alc662_auto_create_extra_out(spec,
13011                                            spec->autocfg.speaker_pins[0],
13012                                            "Speaker");
13013         if (err < 0)
13014                 return err;
13015         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13016                                            "Headphone");
13017         if (err < 0)
13018                 return err;
13019         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13020         if (err < 0)
13021                 return err;
13022
13023         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13024
13025         if (spec->autocfg.dig_out_pin)
13026                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13027
13028         if (spec->kctl_alloc)
13029                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13030
13031         spec->num_mux_defs = 1;
13032         spec->input_mux = &spec->private_imux;
13033         
13034         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
13035         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13036         spec->num_mixers++;
13037         return 1;
13038 }
13039
13040 /* additional initialization for auto-configuration model */
13041 static void alc662_auto_init(struct hda_codec *codec)
13042 {
13043         alc662_auto_init_multi_out(codec);
13044         alc662_auto_init_hp_out(codec);
13045         alc662_auto_init_analog_input(codec);
13046 }
13047
13048 static int patch_alc662(struct hda_codec *codec)
13049 {
13050         struct alc_spec *spec;
13051         int err, board_config;
13052
13053         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13054         if (!spec)
13055                 return -ENOMEM;
13056
13057         codec->spec = spec;
13058
13059         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13060                                                   alc662_models,
13061                                                   alc662_cfg_tbl);
13062         if (board_config < 0) {
13063                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13064                        "trying auto-probe from BIOS...\n");
13065                 board_config = ALC662_AUTO;
13066         }
13067
13068         if (board_config == ALC662_AUTO) {
13069                 /* automatic parse from the BIOS config */
13070                 err = alc662_parse_auto_config(codec);
13071                 if (err < 0) {
13072                         alc_free(codec);
13073                         return err;
13074                 } else if (!err) {
13075                         printk(KERN_INFO
13076                                "hda_codec: Cannot set up configuration "
13077                                "from BIOS.  Using base mode...\n");
13078                         board_config = ALC662_3ST_2ch_DIG;
13079                 }
13080         }
13081
13082         if (board_config != ALC662_AUTO)
13083                 setup_preset(spec, &alc662_presets[board_config]);
13084
13085         spec->stream_name_analog = "ALC662 Analog";
13086         spec->stream_analog_playback = &alc662_pcm_analog_playback;
13087         spec->stream_analog_capture = &alc662_pcm_analog_capture;
13088
13089         spec->stream_name_digital = "ALC662 Digital";
13090         spec->stream_digital_playback = &alc662_pcm_digital_playback;
13091         spec->stream_digital_capture = &alc662_pcm_digital_capture;
13092
13093         if (!spec->adc_nids && spec->input_mux) {
13094                 spec->adc_nids = alc662_adc_nids;
13095                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13096         }
13097
13098         codec->patch_ops = alc_patch_ops;
13099         if (board_config == ALC662_AUTO)
13100                 spec->init_hook = alc662_auto_init;
13101 #ifdef CONFIG_SND_HDA_POWER_SAVE
13102         if (!spec->loopback.amplist)
13103                 spec->loopback.amplist = alc662_loopbacks;
13104 #endif
13105
13106         return 0;
13107 }
13108
13109 /*
13110  * patch entries
13111  */
13112 struct hda_codec_preset snd_hda_preset_realtek[] = {
13113         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
13114         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
13115         { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
13116         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
13117         { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
13118         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
13119           .patch = patch_alc861 },
13120         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13121         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13122         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
13123         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13124           .patch = patch_alc883 },
13125         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13126           .patch = patch_alc662 },
13127         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
13128         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
13129         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
13130         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
13131         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
13132         { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
13133         {} /* terminator */
13134 };