[ALSA] hda-codec - Fix ALC268 acer model
[linux-2.6] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_BENQ_ED8,
96         ALC262_SONY_ASSAMD,
97         ALC262_BENQ_T31,
98         ALC262_AUTO,
99         ALC262_MODEL_LAST /* last tag */
100 };
101
102 /* ALC268 models */
103 enum {
104         ALC268_3ST,
105         ALC268_TOSHIBA,
106         ALC268_ACER,
107         ALC268_AUTO,
108         ALC268_MODEL_LAST /* last tag */
109 };
110
111 /* ALC861 models */
112 enum {
113         ALC861_3ST,
114         ALC660_3ST,
115         ALC861_3ST_DIG,
116         ALC861_6ST_DIG,
117         ALC861_UNIWILL_M31,
118         ALC861_TOSHIBA,
119         ALC861_ASUS,
120         ALC861_ASUS_LAPTOP,
121         ALC861_AUTO,
122         ALC861_MODEL_LAST,
123 };
124
125 /* ALC861-VD models */
126 enum {
127         ALC660VD_3ST,
128         ALC660VD_3ST_DIG,
129         ALC861VD_3ST,
130         ALC861VD_3ST_DIG,
131         ALC861VD_6ST_DIG,
132         ALC861VD_LENOVO,
133         ALC861VD_DALLAS,
134         ALC861VD_HP,
135         ALC861VD_AUTO,
136         ALC861VD_MODEL_LAST,
137 };
138
139 /* ALC662 models */
140 enum {
141         ALC662_3ST_2ch_DIG,
142         ALC662_3ST_6ch_DIG,
143         ALC662_3ST_6ch,
144         ALC662_5ST_DIG,
145         ALC662_LENOVO_101E,
146         ALC662_AUTO,
147         ALC662_MODEL_LAST,
148 };
149
150 /* ALC882 models */
151 enum {
152         ALC882_3ST_DIG,
153         ALC882_6ST_DIG,
154         ALC882_ARIMA,
155         ALC882_W2JC,
156         ALC882_TARGA,
157         ALC882_ASUS_A7J,
158         ALC885_MACPRO,
159         ALC885_MBP3,
160         ALC885_IMAC24,
161         ALC882_AUTO,
162         ALC882_MODEL_LAST,
163 };
164
165 /* ALC883 models */
166 enum {
167         ALC883_3ST_2ch_DIG,
168         ALC883_3ST_6ch_DIG,
169         ALC883_3ST_6ch,
170         ALC883_6ST_DIG,
171         ALC883_TARGA_DIG,
172         ALC883_TARGA_2ch_DIG,
173         ALC883_ACER,
174         ALC883_ACER_ASPIRE,
175         ALC883_MEDION,
176         ALC883_MEDION_MD2,      
177         ALC883_LAPTOP_EAPD,
178         ALC883_LENOVO_101E_2ch,
179         ALC883_LENOVO_NB0763,
180         ALC888_LENOVO_MS7195_DIG,               
181         ALC888_6ST_HP,
182         ALC888_3ST_HP,
183         ALC883_AUTO,
184         ALC883_MODEL_LAST,
185 };
186
187 /* for GPIO Poll */
188 #define GPIO_MASK       0x03
189
190 struct alc_spec {
191         /* codec parameterization */
192         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
193         unsigned int num_mixers;
194
195         const struct hda_verb *init_verbs[5];   /* initialization verbs
196                                                  * don't forget NULL
197                                                  * termination!
198                                                  */
199         unsigned int num_init_verbs;
200
201         char *stream_name_analog;       /* analog PCM stream */
202         struct hda_pcm_stream *stream_analog_playback;
203         struct hda_pcm_stream *stream_analog_capture;
204
205         char *stream_name_digital;      /* digital PCM stream */
206         struct hda_pcm_stream *stream_digital_playback;
207         struct hda_pcm_stream *stream_digital_capture;
208
209         /* playback */
210         struct hda_multi_out multiout;  /* playback set-up
211                                          * max_channels, dacs must be set
212                                          * dig_out_nid and hp_nid are optional
213                                          */
214
215         /* capture */
216         unsigned int num_adc_nids;
217         hda_nid_t *adc_nids;
218         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
219
220         /* capture source */
221         unsigned int num_mux_defs;
222         const struct hda_input_mux *input_mux;
223         unsigned int cur_mux[3];
224
225         /* channel model */
226         const struct hda_channel_mode *channel_mode;
227         int num_channel_mode;
228         int need_dac_fix;
229
230         /* PCM information */
231         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
232
233         /* dynamic controls, init_verbs and input_mux */
234         struct auto_pin_cfg autocfg;
235         unsigned int num_kctl_alloc, num_kctl_used;
236         struct snd_kcontrol_new *kctl_alloc;
237         struct hda_input_mux private_imux;
238         hda_nid_t private_dac_nids[5];
239
240         /* hooks */
241         void (*init_hook)(struct hda_codec *codec);
242         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
243
244         /* for pin sensing */
245         unsigned int sense_updated: 1;
246         unsigned int jack_present: 1;
247
248 #ifdef CONFIG_SND_HDA_POWER_SAVE
249         struct hda_loopback_check loopback;
250 #endif
251 };
252
253 /*
254  * configuration template - to be copied to the spec instance
255  */
256 struct alc_config_preset {
257         struct snd_kcontrol_new *mixers[5]; /* should be identical size
258                                              * with spec
259                                              */
260         const struct hda_verb *init_verbs[5];
261         unsigned int num_dacs;
262         hda_nid_t *dac_nids;
263         hda_nid_t dig_out_nid;          /* optional */
264         hda_nid_t hp_nid;               /* optional */
265         unsigned int num_adc_nids;
266         hda_nid_t *adc_nids;
267         hda_nid_t dig_in_nid;
268         unsigned int num_channel_mode;
269         const struct hda_channel_mode *channel_mode;
270         int need_dac_fix;
271         unsigned int num_mux_defs;
272         const struct hda_input_mux *input_mux;
273         void (*unsol_event)(struct hda_codec *, unsigned int);
274         void (*init_hook)(struct hda_codec *);
275 #ifdef CONFIG_SND_HDA_POWER_SAVE
276         struct hda_amp_list *loopbacks;
277 #endif
278 };
279
280
281 /*
282  * input MUX handling
283  */
284 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
285                              struct snd_ctl_elem_info *uinfo)
286 {
287         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
288         struct alc_spec *spec = codec->spec;
289         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
290         if (mux_idx >= spec->num_mux_defs)
291                 mux_idx = 0;
292         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
293 }
294
295 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
296                             struct snd_ctl_elem_value *ucontrol)
297 {
298         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
299         struct alc_spec *spec = codec->spec;
300         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
301
302         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
303         return 0;
304 }
305
306 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
307                             struct snd_ctl_elem_value *ucontrol)
308 {
309         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
310         struct alc_spec *spec = codec->spec;
311         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
312         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
313         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
314                                      spec->adc_nids[adc_idx],
315                                      &spec->cur_mux[adc_idx]);
316 }
317
318
319 /*
320  * channel mode setting
321  */
322 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
323                             struct snd_ctl_elem_info *uinfo)
324 {
325         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
326         struct alc_spec *spec = codec->spec;
327         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
328                                     spec->num_channel_mode);
329 }
330
331 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
332                            struct snd_ctl_elem_value *ucontrol)
333 {
334         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335         struct alc_spec *spec = codec->spec;
336         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
337                                    spec->num_channel_mode,
338                                    spec->multiout.max_channels);
339 }
340
341 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
342                            struct snd_ctl_elem_value *ucontrol)
343 {
344         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
345         struct alc_spec *spec = codec->spec;
346         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
347                                       spec->num_channel_mode,
348                                       &spec->multiout.max_channels);
349         if (err >= 0 && spec->need_dac_fix)
350                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
351         return err;
352 }
353
354 /*
355  * Control the mode of pin widget settings via the mixer.  "pc" is used
356  * instead of "%" to avoid consequences of accidently treating the % as 
357  * being part of a format specifier.  Maximum allowed length of a value is
358  * 63 characters plus NULL terminator.
359  *
360  * Note: some retasking pin complexes seem to ignore requests for input
361  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
362  * are requested.  Therefore order this list so that this behaviour will not
363  * cause problems when mixer clients move through the enum sequentially.
364  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
365  * March 2006.
366  */
367 static char *alc_pin_mode_names[] = {
368         "Mic 50pc bias", "Mic 80pc bias",
369         "Line in", "Line out", "Headphone out",
370 };
371 static unsigned char alc_pin_mode_values[] = {
372         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
373 };
374 /* The control can present all 5 options, or it can limit the options based
375  * in the pin being assumed to be exclusively an input or an output pin.  In
376  * addition, "input" pins may or may not process the mic bias option
377  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
378  * accept requests for bias as of chip versions up to March 2006) and/or
379  * wiring in the computer.
380  */
381 #define ALC_PIN_DIR_IN              0x00
382 #define ALC_PIN_DIR_OUT             0x01
383 #define ALC_PIN_DIR_INOUT           0x02
384 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
385 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
386
387 /* Info about the pin modes supported by the different pin direction modes. 
388  * For each direction the minimum and maximum values are given.
389  */
390 static signed char alc_pin_mode_dir_info[5][2] = {
391         { 0, 2 },    /* ALC_PIN_DIR_IN */
392         { 3, 4 },    /* ALC_PIN_DIR_OUT */
393         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
394         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
395         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
396 };
397 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
398 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
399 #define alc_pin_mode_n_items(_dir) \
400         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
401
402 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
403                              struct snd_ctl_elem_info *uinfo)
404 {
405         unsigned int item_num = uinfo->value.enumerated.item;
406         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
407
408         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
409         uinfo->count = 1;
410         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
411
412         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
413                 item_num = alc_pin_mode_min(dir);
414         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
415         return 0;
416 }
417
418 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
419                             struct snd_ctl_elem_value *ucontrol)
420 {
421         unsigned int i;
422         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
423         hda_nid_t nid = kcontrol->private_value & 0xffff;
424         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
425         long *valp = ucontrol->value.integer.value;
426         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
427                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
428                                                  0x00);
429
430         /* Find enumerated value for current pinctl setting */
431         i = alc_pin_mode_min(dir);
432         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
433                 i++;
434         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
435         return 0;
436 }
437
438 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
439                             struct snd_ctl_elem_value *ucontrol)
440 {
441         signed int change;
442         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
443         hda_nid_t nid = kcontrol->private_value & 0xffff;
444         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
445         long val = *ucontrol->value.integer.value;
446         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
447                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
448                                                  0x00);
449
450         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
451                 val = alc_pin_mode_min(dir);
452
453         change = pinctl != alc_pin_mode_values[val];
454         if (change) {
455                 /* Set pin mode to that requested */
456                 snd_hda_codec_write_cache(codec, nid, 0,
457                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
458                                           alc_pin_mode_values[val]);
459
460                 /* Also enable the retasking pin's input/output as required 
461                  * for the requested pin mode.  Enum values of 2 or less are
462                  * input modes.
463                  *
464                  * Dynamically switching the input/output buffers probably
465                  * reduces noise slightly (particularly on input) so we'll
466                  * do it.  However, having both input and output buffers
467                  * enabled simultaneously doesn't seem to be problematic if
468                  * this turns out to be necessary in the future.
469                  */
470                 if (val <= 2) {
471                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
472                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
473                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
474                                                  HDA_AMP_MUTE, 0);
475                 } else {
476                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
477                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
478                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
479                                                  HDA_AMP_MUTE, 0);
480                 }
481         }
482         return change;
483 }
484
485 #define ALC_PIN_MODE(xname, nid, dir) \
486         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
487           .info = alc_pin_mode_info, \
488           .get = alc_pin_mode_get, \
489           .put = alc_pin_mode_put, \
490           .private_value = nid | (dir<<16) }
491
492 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
493  * together using a mask with more than one bit set.  This control is
494  * currently used only by the ALC260 test model.  At this stage they are not
495  * needed for any "production" models.
496  */
497 #ifdef CONFIG_SND_DEBUG
498 #define alc_gpio_data_info      snd_ctl_boolean_mono_info
499
500 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
501                              struct snd_ctl_elem_value *ucontrol)
502 {
503         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
504         hda_nid_t nid = kcontrol->private_value & 0xffff;
505         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
506         long *valp = ucontrol->value.integer.value;
507         unsigned int val = snd_hda_codec_read(codec, nid, 0,
508                                               AC_VERB_GET_GPIO_DATA, 0x00);
509
510         *valp = (val & mask) != 0;
511         return 0;
512 }
513 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
514                              struct snd_ctl_elem_value *ucontrol)
515 {
516         signed int change;
517         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
518         hda_nid_t nid = kcontrol->private_value & 0xffff;
519         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
520         long val = *ucontrol->value.integer.value;
521         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
522                                                     AC_VERB_GET_GPIO_DATA,
523                                                     0x00);
524
525         /* Set/unset the masked GPIO bit(s) as needed */
526         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
527         if (val == 0)
528                 gpio_data &= ~mask;
529         else
530                 gpio_data |= mask;
531         snd_hda_codec_write_cache(codec, nid, 0,
532                                   AC_VERB_SET_GPIO_DATA, gpio_data);
533
534         return change;
535 }
536 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
537         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
538           .info = alc_gpio_data_info, \
539           .get = alc_gpio_data_get, \
540           .put = alc_gpio_data_put, \
541           .private_value = nid | (mask<<16) }
542 #endif   /* CONFIG_SND_DEBUG */
543
544 /* A switch control to allow the enabling of the digital IO pins on the
545  * ALC260.  This is incredibly simplistic; the intention of this control is
546  * to provide something in the test model allowing digital outputs to be
547  * identified if present.  If models are found which can utilise these
548  * outputs a more complete mixer control can be devised for those models if
549  * necessary.
550  */
551 #ifdef CONFIG_SND_DEBUG
552 #define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
553
554 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
555                               struct snd_ctl_elem_value *ucontrol)
556 {
557         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
558         hda_nid_t nid = kcontrol->private_value & 0xffff;
559         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
560         long *valp = ucontrol->value.integer.value;
561         unsigned int val = snd_hda_codec_read(codec, nid, 0,
562                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
563
564         *valp = (val & mask) != 0;
565         return 0;
566 }
567 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
568                               struct snd_ctl_elem_value *ucontrol)
569 {
570         signed int change;
571         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
572         hda_nid_t nid = kcontrol->private_value & 0xffff;
573         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
574         long val = *ucontrol->value.integer.value;
575         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
576                                                     AC_VERB_GET_DIGI_CONVERT,
577                                                     0x00);
578
579         /* Set/unset the masked control bit(s) as needed */
580         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
581         if (val==0)
582                 ctrl_data &= ~mask;
583         else
584                 ctrl_data |= mask;
585         snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
586                                   ctrl_data);
587
588         return change;
589 }
590 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
591         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
592           .info = alc_spdif_ctrl_info, \
593           .get = alc_spdif_ctrl_get, \
594           .put = alc_spdif_ctrl_put, \
595           .private_value = nid | (mask<<16) }
596 #endif   /* CONFIG_SND_DEBUG */
597
598 /*
599  * set up from the preset table
600  */
601 static void setup_preset(struct alc_spec *spec,
602                          const struct alc_config_preset *preset)
603 {
604         int i;
605
606         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
607                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
608         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
609              i++)
610                 spec->init_verbs[spec->num_init_verbs++] =
611                         preset->init_verbs[i];
612         
613         spec->channel_mode = preset->channel_mode;
614         spec->num_channel_mode = preset->num_channel_mode;
615         spec->need_dac_fix = preset->need_dac_fix;
616
617         spec->multiout.max_channels = spec->channel_mode[0].channels;
618
619         spec->multiout.num_dacs = preset->num_dacs;
620         spec->multiout.dac_nids = preset->dac_nids;
621         spec->multiout.dig_out_nid = preset->dig_out_nid;
622         spec->multiout.hp_nid = preset->hp_nid;
623         
624         spec->num_mux_defs = preset->num_mux_defs;
625         if (!spec->num_mux_defs)
626                 spec->num_mux_defs = 1;
627         spec->input_mux = preset->input_mux;
628
629         spec->num_adc_nids = preset->num_adc_nids;
630         spec->adc_nids = preset->adc_nids;
631         spec->dig_in_nid = preset->dig_in_nid;
632
633         spec->unsol_event = preset->unsol_event;
634         spec->init_hook = preset->init_hook;
635 #ifdef CONFIG_SND_HDA_POWER_SAVE
636         spec->loopback.amplist = preset->loopbacks;
637 #endif
638 }
639
640 /* Enable GPIO mask and set output */
641 static struct hda_verb alc_gpio1_init_verbs[] = {
642         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
643         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
644         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
645         { }
646 };
647
648 static struct hda_verb alc_gpio2_init_verbs[] = {
649         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
650         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
651         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
652         { }
653 };
654
655 static struct hda_verb alc_gpio3_init_verbs[] = {
656         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
657         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
658         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
659         { }
660 };
661
662 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
663  *      31 ~ 16 :       Manufacture ID
664  *      15 ~ 8  :       SKU ID
665  *      7  ~ 0  :       Assembly ID
666  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
667  */
668 static void alc_subsystem_id(struct hda_codec *codec,
669                              unsigned int porta, unsigned int porte,
670                              unsigned int portd)
671 {
672         unsigned int ass, tmp;
673
674         ass = codec->subsystem_id;
675         if (!(ass & 1))
676                 return;
677
678         /* Override */
679         tmp = (ass & 0x38) >> 3;        /* external Amp control */
680         switch (tmp) {
681         case 1:
682                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
683                 break;
684         case 3:
685                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
686                 break;
687         case 7:
688                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
689                 break;
690         case 5:
691                 switch (codec->vendor_id) {
692                 case 0x10ec0862:
693                 case 0x10ec0660:
694                 case 0x10ec0662:        
695                 case 0x10ec0267:
696                 case 0x10ec0268:
697                         snd_hda_codec_write(codec, 0x14, 0,
698                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
699                         snd_hda_codec_write(codec, 0x15, 0,
700                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
701                         return;
702                 }
703         case 6:
704                 if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
705                         hda_nid_t port = 0;
706                         tmp = (ass & 0x1800) >> 11;
707                         switch (tmp) {
708                         case 0: port = porta; break;
709                         case 1: port = porte; break;
710                         case 2: port = portd; break;
711                         }
712                         if (port)
713                                 snd_hda_codec_write(codec, port, 0,
714                                                     AC_VERB_SET_EAPD_BTLENABLE,
715                                                     2);
716                 }
717                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
718                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
719                                     (tmp == 5 ? 0x3040 : 0x3050));
720                 break;
721         }
722 }
723
724 /*
725  * Fix-up pin default configurations
726  */
727
728 struct alc_pincfg {
729         hda_nid_t nid;
730         u32 val;
731 };
732
733 static void alc_fix_pincfg(struct hda_codec *codec,
734                            const struct snd_pci_quirk *quirk,
735                            const struct alc_pincfg **pinfix)
736 {
737         const struct alc_pincfg *cfg;
738
739         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
740         if (!quirk)
741                 return;
742
743         cfg = pinfix[quirk->value];
744         for (; cfg->nid; cfg++) {
745                 int i;
746                 u32 val = cfg->val;
747                 for (i = 0; i < 4; i++) {
748                         snd_hda_codec_write(codec, cfg->nid, 0,
749                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
750                                     val & 0xff);
751                         val >>= 8;
752                 }
753         }
754 }
755
756 /*
757  * ALC880 3-stack model
758  *
759  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
760  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
761  *                 F-Mic = 0x1b, HP = 0x19
762  */
763
764 static hda_nid_t alc880_dac_nids[4] = {
765         /* front, rear, clfe, rear_surr */
766         0x02, 0x05, 0x04, 0x03
767 };
768
769 static hda_nid_t alc880_adc_nids[3] = {
770         /* ADC0-2 */
771         0x07, 0x08, 0x09,
772 };
773
774 /* The datasheet says the node 0x07 is connected from inputs,
775  * but it shows zero connection in the real implementation on some devices.
776  * Note: this is a 915GAV bug, fixed on 915GLV
777  */
778 static hda_nid_t alc880_adc_nids_alt[2] = {
779         /* ADC1-2 */
780         0x08, 0x09,
781 };
782
783 #define ALC880_DIGOUT_NID       0x06
784 #define ALC880_DIGIN_NID        0x0a
785
786 static struct hda_input_mux alc880_capture_source = {
787         .num_items = 4,
788         .items = {
789                 { "Mic", 0x0 },
790                 { "Front Mic", 0x3 },
791                 { "Line", 0x2 },
792                 { "CD", 0x4 },
793         },
794 };
795
796 /* channel source setting (2/6 channel selection for 3-stack) */
797 /* 2ch mode */
798 static struct hda_verb alc880_threestack_ch2_init[] = {
799         /* set line-in to input, mute it */
800         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
801         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
802         /* set mic-in to input vref 80%, mute it */
803         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
804         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
805         { } /* end */
806 };
807
808 /* 6ch mode */
809 static struct hda_verb alc880_threestack_ch6_init[] = {
810         /* set line-in to output, unmute it */
811         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
812         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
813         /* set mic-in to output, unmute it */
814         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
815         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
816         { } /* end */
817 };
818
819 static struct hda_channel_mode alc880_threestack_modes[2] = {
820         { 2, alc880_threestack_ch2_init },
821         { 6, alc880_threestack_ch6_init },
822 };
823
824 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
825         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
826         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
827         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
828         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
829         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
830         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
831         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
832         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
833         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
834         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
835         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
836         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
837         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
838         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
839         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
840         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
841         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
842         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
843         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
844         {
845                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
846                 .name = "Channel Mode",
847                 .info = alc_ch_mode_info,
848                 .get = alc_ch_mode_get,
849                 .put = alc_ch_mode_put,
850         },
851         { } /* end */
852 };
853
854 /* capture mixer elements */
855 static struct snd_kcontrol_new alc880_capture_mixer[] = {
856         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
857         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
858         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
859         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
860         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
861         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
862         {
863                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
864                 /* The multiple "Capture Source" controls confuse alsamixer
865                  * So call somewhat different..
866                  * FIXME: the controls appear in the "playback" view!
867                  */
868                 /* .name = "Capture Source", */
869                 .name = "Input Source",
870                 .count = 3,
871                 .info = alc_mux_enum_info,
872                 .get = alc_mux_enum_get,
873                 .put = alc_mux_enum_put,
874         },
875         { } /* end */
876 };
877
878 /* capture mixer elements (in case NID 0x07 not available) */
879 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
880         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
881         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
882         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
883         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
884         {
885                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
886                 /* The multiple "Capture Source" controls confuse alsamixer
887                  * So call somewhat different..
888                  * FIXME: the controls appear in the "playback" view!
889                  */
890                 /* .name = "Capture Source", */
891                 .name = "Input Source",
892                 .count = 2,
893                 .info = alc_mux_enum_info,
894                 .get = alc_mux_enum_get,
895                 .put = alc_mux_enum_put,
896         },
897         { } /* end */
898 };
899
900
901
902 /*
903  * ALC880 5-stack model
904  *
905  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
906  *      Side = 0x02 (0xd)
907  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
908  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
909  */
910
911 /* additional mixers to alc880_three_stack_mixer */
912 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
913         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
914         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
915         { } /* end */
916 };
917
918 /* channel source setting (6/8 channel selection for 5-stack) */
919 /* 6ch mode */
920 static struct hda_verb alc880_fivestack_ch6_init[] = {
921         /* set line-in to input, mute it */
922         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
923         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
924         { } /* end */
925 };
926
927 /* 8ch mode */
928 static struct hda_verb alc880_fivestack_ch8_init[] = {
929         /* set line-in to output, unmute it */
930         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
931         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
932         { } /* end */
933 };
934
935 static struct hda_channel_mode alc880_fivestack_modes[2] = {
936         { 6, alc880_fivestack_ch6_init },
937         { 8, alc880_fivestack_ch8_init },
938 };
939
940
941 /*
942  * ALC880 6-stack model
943  *
944  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
945  *      Side = 0x05 (0x0f)
946  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
947  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
948  */
949
950 static hda_nid_t alc880_6st_dac_nids[4] = {
951         /* front, rear, clfe, rear_surr */
952         0x02, 0x03, 0x04, 0x05
953 };
954
955 static struct hda_input_mux alc880_6stack_capture_source = {
956         .num_items = 4,
957         .items = {
958                 { "Mic", 0x0 },
959                 { "Front Mic", 0x1 },
960                 { "Line", 0x2 },
961                 { "CD", 0x4 },
962         },
963 };
964
965 /* fixed 8-channels */
966 static struct hda_channel_mode alc880_sixstack_modes[1] = {
967         { 8, NULL },
968 };
969
970 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
971         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
972         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
973         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
974         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
975         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
976         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
977         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
978         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
979         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
980         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
981         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
982         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
983         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
984         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
985         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
986         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
987         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
988         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
989         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
990         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
991         {
992                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
993                 .name = "Channel Mode",
994                 .info = alc_ch_mode_info,
995                 .get = alc_ch_mode_get,
996                 .put = alc_ch_mode_put,
997         },
998         { } /* end */
999 };
1000
1001
1002 /*
1003  * ALC880 W810 model
1004  *
1005  * W810 has rear IO for:
1006  * Front (DAC 02)
1007  * Surround (DAC 03)
1008  * Center/LFE (DAC 04)
1009  * Digital out (06)
1010  *
1011  * The system also has a pair of internal speakers, and a headphone jack.
1012  * These are both connected to Line2 on the codec, hence to DAC 02.
1013  * 
1014  * There is a variable resistor to control the speaker or headphone
1015  * volume. This is a hardware-only device without a software API.
1016  *
1017  * Plugging headphones in will disable the internal speakers. This is
1018  * implemented in hardware, not via the driver using jack sense. In
1019  * a similar fashion, plugging into the rear socket marked "front" will
1020  * disable both the speakers and headphones.
1021  *
1022  * For input, there's a microphone jack, and an "audio in" jack.
1023  * These may not do anything useful with this driver yet, because I
1024  * haven't setup any initialization verbs for these yet...
1025  */
1026
1027 static hda_nid_t alc880_w810_dac_nids[3] = {
1028         /* front, rear/surround, clfe */
1029         0x02, 0x03, 0x04
1030 };
1031
1032 /* fixed 6 channels */
1033 static struct hda_channel_mode alc880_w810_modes[1] = {
1034         { 6, NULL }
1035 };
1036
1037 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1038 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1039         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1040         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1041         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1042         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1043         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1044         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1045         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1046         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1047         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1048         { } /* end */
1049 };
1050
1051
1052 /*
1053  * Z710V model
1054  *
1055  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1056  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1057  *                 Line = 0x1a
1058  */
1059
1060 static hda_nid_t alc880_z71v_dac_nids[1] = {
1061         0x02
1062 };
1063 #define ALC880_Z71V_HP_DAC      0x03
1064
1065 /* fixed 2 channels */
1066 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1067         { 2, NULL }
1068 };
1069
1070 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1071         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1072         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1073         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1074         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1075         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1076         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1077         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1078         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1079         { } /* end */
1080 };
1081
1082
1083 /* FIXME! */
1084 /*
1085  * ALC880 F1734 model
1086  *
1087  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1088  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1089  */
1090
1091 static hda_nid_t alc880_f1734_dac_nids[1] = {
1092         0x03
1093 };
1094 #define ALC880_F1734_HP_DAC     0x02
1095
1096 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1097         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1098         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1099         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1100         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1101         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1102         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1103         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1104         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1105         { } /* end */
1106 };
1107
1108
1109 /* FIXME! */
1110 /*
1111  * ALC880 ASUS model
1112  *
1113  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1114  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1115  *  Mic = 0x18, Line = 0x1a
1116  */
1117
1118 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1119 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1120
1121 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1122         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1123         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1124         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1125         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1126         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1127         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1128         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1129         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1130         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1131         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1132         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1133         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1134         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1135         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1136         {
1137                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1138                 .name = "Channel Mode",
1139                 .info = alc_ch_mode_info,
1140                 .get = alc_ch_mode_get,
1141                 .put = alc_ch_mode_put,
1142         },
1143         { } /* end */
1144 };
1145
1146 /* FIXME! */
1147 /*
1148  * ALC880 ASUS W1V model
1149  *
1150  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1151  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1152  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1153  */
1154
1155 /* additional mixers to alc880_asus_mixer */
1156 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1157         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1158         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1159         { } /* end */
1160 };
1161
1162 /* additional mixers to alc880_asus_mixer */
1163 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1164         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1165         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1166         { } /* end */
1167 };
1168
1169 /* TCL S700 */
1170 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1171         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1172         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1173         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1174         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1175         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1176         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1177         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1178         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1179         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1180         {
1181                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1182                 /* The multiple "Capture Source" controls confuse alsamixer
1183                  * So call somewhat different..
1184                  * FIXME: the controls appear in the "playback" view!
1185                  */
1186                 /* .name = "Capture Source", */
1187                 .name = "Input Source",
1188                 .count = 1,
1189                 .info = alc_mux_enum_info,
1190                 .get = alc_mux_enum_get,
1191                 .put = alc_mux_enum_put,
1192         },
1193         { } /* end */
1194 };
1195
1196 /* Uniwill */
1197 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1198         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1199         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1200         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1201         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1202         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1203         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1204         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1205         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1206         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1207         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1208         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1209         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1210         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1211         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1212         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1213         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1214         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1215         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1216         {
1217                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1218                 .name = "Channel Mode",
1219                 .info = alc_ch_mode_info,
1220                 .get = alc_ch_mode_get,
1221                 .put = alc_ch_mode_put,
1222         },
1223         { } /* end */
1224 };
1225
1226 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1227         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1228         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1229         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1230         HDA_BIND_MUTE("Speaker 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("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1234         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1235         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1236         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1237         { } /* end */
1238 };
1239
1240 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1241         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1242         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1243         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1244         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1245         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1246         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1247         { } /* end */
1248 };
1249
1250 /*
1251  * build control elements
1252  */
1253 static int alc_build_controls(struct hda_codec *codec)
1254 {
1255         struct alc_spec *spec = codec->spec;
1256         int err;
1257         int i;
1258
1259         for (i = 0; i < spec->num_mixers; i++) {
1260                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1261                 if (err < 0)
1262                         return err;
1263         }
1264
1265         if (spec->multiout.dig_out_nid) {
1266                 err = snd_hda_create_spdif_out_ctls(codec,
1267                                                     spec->multiout.dig_out_nid);
1268                 if (err < 0)
1269                         return err;
1270         }
1271         if (spec->dig_in_nid) {
1272                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1273                 if (err < 0)
1274                         return err;
1275         }
1276         return 0;
1277 }
1278
1279
1280 /*
1281  * initialize the codec volumes, etc
1282  */
1283
1284 /*
1285  * generic initialization of ADC, input mixers and output mixers
1286  */
1287 static struct hda_verb alc880_volume_init_verbs[] = {
1288         /*
1289          * Unmute ADC0-2 and set the default input to mic-in
1290          */
1291         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1292         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1293         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1294         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1295         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1296         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1297
1298         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1299          * mixer widget
1300          * Note: PASD motherboards uses the Line In 2 as the input for front
1301          * panel mic (mic 2)
1302          */
1303         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1304         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1305         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1306         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1307         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1308         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1309         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1310         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1311
1312         /*
1313          * Set up output mixers (0x0c - 0x0f)
1314          */
1315         /* set vol=0 to output mixers */
1316         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1317         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1318         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1319         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1320         /* set up input amps for analog loopback */
1321         /* Amp Indices: DAC = 0, mixer = 1 */
1322         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1323         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1324         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1325         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1326         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1327         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1328         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1329         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1330
1331         { }
1332 };
1333
1334 /*
1335  * 3-stack pin configuration:
1336  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1337  */
1338 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1339         /*
1340          * preset connection lists of input pins
1341          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1342          */
1343         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1344         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1345         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1346
1347         /*
1348          * Set pin mode and muting
1349          */
1350         /* set front pin widgets 0x14 for output */
1351         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1352         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1353         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1354         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1355         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1356         /* Mic2 (as headphone out) for HP output */
1357         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1358         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1359         /* Line In pin widget for input */
1360         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1361         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1362         /* Line2 (as front mic) pin widget for input and vref at 80% */
1363         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1364         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1365         /* CD pin widget for input */
1366         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1367
1368         { }
1369 };
1370
1371 /*
1372  * 5-stack pin configuration:
1373  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1374  * line-in/side = 0x1a, f-mic = 0x1b
1375  */
1376 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1377         /*
1378          * preset connection lists of input pins
1379          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1380          */
1381         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1382         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1383
1384         /*
1385          * Set pin mode and muting
1386          */
1387         /* set pin widgets 0x14-0x17 for output */
1388         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1389         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1390         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1391         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1392         /* unmute pins for output (no gain on this amp) */
1393         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1394         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1395         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1396         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1397
1398         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1399         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1400         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1401         /* Mic2 (as headphone out) for HP output */
1402         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1403         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1404         /* Line In pin widget for input */
1405         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1406         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1407         /* Line2 (as front mic) pin widget for input and vref at 80% */
1408         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1409         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1410         /* CD pin widget for input */
1411         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1412
1413         { }
1414 };
1415
1416 /*
1417  * W810 pin configuration:
1418  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1419  */
1420 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1421         /* hphone/speaker input selector: front DAC */
1422         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1423
1424         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1425         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1426         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1427         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1428         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1429         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1430
1431         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1432         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1433
1434         { }
1435 };
1436
1437 /*
1438  * Z71V pin configuration:
1439  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1440  */
1441 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1442         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1443         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1444         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1445         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1446
1447         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1448         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1449         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1450         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1451
1452         { }
1453 };
1454
1455 /*
1456  * 6-stack pin configuration:
1457  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1458  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1459  */
1460 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1461         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1462
1463         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1464         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1466         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1468         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1469         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1470         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1471
1472         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1473         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1474         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1475         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1476         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1477         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1478         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1479         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1480         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1481         
1482         { }
1483 };
1484
1485 /*
1486  * Uniwill pin configuration:
1487  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1488  * line = 0x1a
1489  */
1490 static struct hda_verb alc880_uniwill_init_verbs[] = {
1491         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1492
1493         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1494         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1496         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1497         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1498         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1500         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1501         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1502         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1503         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1504         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1505         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1506         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1507
1508         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1509         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1510         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1511         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1512         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1513         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1514         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1515         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1516         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1517
1518         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1519         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1520
1521         { }
1522 };
1523
1524 /*
1525 * Uniwill P53
1526 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1527  */
1528 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1529         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1530
1531         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1532         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1533         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1534         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1535         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1536         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1537         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1538         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1539         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1540         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1541         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1542         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1543
1544         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1545         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1546         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1547         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1548         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1549         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1550
1551         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1552         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1553
1554         { }
1555 };
1556
1557 static struct hda_verb alc880_beep_init_verbs[] = {
1558         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1559         { }
1560 };
1561
1562 /* toggle speaker-output according to the hp-jack state */
1563 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1564 {
1565         unsigned int present;
1566         unsigned char bits;
1567
1568         present = snd_hda_codec_read(codec, 0x14, 0,
1569                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1570         bits = present ? HDA_AMP_MUTE : 0;
1571         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1572                                  HDA_AMP_MUTE, bits);
1573         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1574                                  HDA_AMP_MUTE, bits);
1575 }
1576
1577 /* auto-toggle front mic */
1578 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1579 {
1580         unsigned int present;
1581         unsigned char bits;
1582
1583         present = snd_hda_codec_read(codec, 0x18, 0,
1584                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1585         bits = present ? HDA_AMP_MUTE : 0;
1586         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1587 }
1588
1589 static void alc880_uniwill_automute(struct hda_codec *codec)
1590 {
1591         alc880_uniwill_hp_automute(codec);
1592         alc880_uniwill_mic_automute(codec);
1593 }
1594
1595 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1596                                        unsigned int res)
1597 {
1598         /* Looks like the unsol event is incompatible with the standard
1599          * definition.  4bit tag is placed at 28 bit!
1600          */
1601         switch (res >> 28) {
1602         case ALC880_HP_EVENT:
1603                 alc880_uniwill_hp_automute(codec);
1604                 break;
1605         case ALC880_MIC_EVENT:
1606                 alc880_uniwill_mic_automute(codec);
1607                 break;
1608         }
1609 }
1610
1611 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1612 {
1613         unsigned int present;
1614         unsigned char bits;
1615
1616         present = snd_hda_codec_read(codec, 0x14, 0,
1617                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1618         bits = present ? HDA_AMP_MUTE : 0;
1619         snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1620 }
1621
1622 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1623 {
1624         unsigned int present;
1625         
1626         present = snd_hda_codec_read(codec, 0x21, 0,
1627                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1628         present &= HDA_AMP_VOLMASK;
1629         snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1630                                  HDA_AMP_VOLMASK, present);
1631         snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1632                                  HDA_AMP_VOLMASK, present);
1633 }
1634
1635 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1636                                            unsigned int res)
1637 {
1638         /* Looks like the unsol event is incompatible with the standard
1639          * definition.  4bit tag is placed at 28 bit!
1640          */
1641         if ((res >> 28) == ALC880_HP_EVENT)
1642                 alc880_uniwill_p53_hp_automute(codec);
1643         if ((res >> 28) == ALC880_DCVOL_EVENT)
1644                 alc880_uniwill_p53_dcvol_automute(codec);
1645 }
1646
1647 /* FIXME! */
1648 /*
1649  * F1734 pin configuration:
1650  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1651  */
1652 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1653         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1654         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1655         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1656         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1657
1658         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1659         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1660         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1661         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1662
1663         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1664         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1665         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1666         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1667         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1668         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1669         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1670         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1672
1673         { }
1674 };
1675
1676 /* FIXME! */
1677 /*
1678  * ASUS pin configuration:
1679  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1680  */
1681 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1682         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1683         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1684         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1685         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
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_OUT},
1690         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1694         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1695
1696         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1697         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1698         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1699         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1700         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1701         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1702         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1703         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1705         
1706         { }
1707 };
1708
1709 /* Enable GPIO mask and set output */
1710 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1711 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1712
1713 /* Clevo m520g init */
1714 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1715         /* headphone output */
1716         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1717         /* line-out */
1718         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1719         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1720         /* Line-in */
1721         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1722         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1723         /* CD */
1724         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1725         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1726         /* Mic1 (rear panel) */
1727         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1728         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1729         /* Mic2 (front panel) */
1730         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1731         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732         /* headphone */
1733         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1734         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1735         /* change to EAPD mode */
1736         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1737         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1738
1739         { }
1740 };
1741
1742 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1743         /* change to EAPD mode */
1744         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1745         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1746
1747         /* Headphone output */
1748         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1749         /* Front output*/
1750         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1751         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1752
1753         /* Line In pin widget for input */
1754         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1755         /* CD pin widget for input */
1756         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1757         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1758         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1759
1760         /* change to EAPD mode */
1761         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1762         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1763
1764         { }
1765 };
1766
1767 /*
1768  * LG m1 express dual
1769  *
1770  * Pin assignment:
1771  *   Rear Line-In/Out (blue): 0x14
1772  *   Build-in Mic-In: 0x15
1773  *   Speaker-out: 0x17
1774  *   HP-Out (green): 0x1b
1775  *   Mic-In/Out (red): 0x19
1776  *   SPDIF-Out: 0x1e
1777  */
1778
1779 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1780 static hda_nid_t alc880_lg_dac_nids[3] = {
1781         0x05, 0x02, 0x03
1782 };
1783
1784 /* seems analog CD is not working */
1785 static struct hda_input_mux alc880_lg_capture_source = {
1786         .num_items = 3,
1787         .items = {
1788                 { "Mic", 0x1 },
1789                 { "Line", 0x5 },
1790                 { "Internal Mic", 0x6 },
1791         },
1792 };
1793
1794 /* 2,4,6 channel modes */
1795 static struct hda_verb alc880_lg_ch2_init[] = {
1796         /* set line-in and mic-in to input */
1797         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1798         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1799         { }
1800 };
1801
1802 static struct hda_verb alc880_lg_ch4_init[] = {
1803         /* set line-in to out and mic-in to input */
1804         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1805         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1806         { }
1807 };
1808
1809 static struct hda_verb alc880_lg_ch6_init[] = {
1810         /* set line-in and mic-in to output */
1811         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1812         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1813         { }
1814 };
1815
1816 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1817         { 2, alc880_lg_ch2_init },
1818         { 4, alc880_lg_ch4_init },
1819         { 6, alc880_lg_ch6_init },
1820 };
1821
1822 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1823         /* FIXME: it's not really "master" but front channels */
1824         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1825         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1826         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1827         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1828         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1829         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1830         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1831         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1832         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1833         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1834         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1835         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1836         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1837         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1838         {
1839                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1840                 .name = "Channel Mode",
1841                 .info = alc_ch_mode_info,
1842                 .get = alc_ch_mode_get,
1843                 .put = alc_ch_mode_put,
1844         },
1845         { } /* end */
1846 };
1847
1848 static struct hda_verb alc880_lg_init_verbs[] = {
1849         /* set capture source to mic-in */
1850         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1851         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1852         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1853         /* mute all amp mixer inputs */
1854         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1855         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1856         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1857         /* line-in to input */
1858         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1859         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1860         /* built-in mic */
1861         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1862         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863         /* speaker-out */
1864         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1865         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866         /* mic-in to input */
1867         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1868         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1869         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870         /* HP-out */
1871         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1872         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1873         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874         /* jack sense */
1875         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1876         { }
1877 };
1878
1879 /* toggle speaker-output according to the hp-jack state */
1880 static void alc880_lg_automute(struct hda_codec *codec)
1881 {
1882         unsigned int present;
1883         unsigned char bits;
1884
1885         present = snd_hda_codec_read(codec, 0x1b, 0,
1886                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1887         bits = present ? HDA_AMP_MUTE : 0;
1888         snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
1889                                  HDA_AMP_MUTE, bits);
1890 }
1891
1892 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1893 {
1894         /* Looks like the unsol event is incompatible with the standard
1895          * definition.  4bit tag is placed at 28 bit!
1896          */
1897         if ((res >> 28) == 0x01)
1898                 alc880_lg_automute(codec);
1899 }
1900
1901 /*
1902  * LG LW20
1903  *
1904  * Pin assignment:
1905  *   Speaker-out: 0x14
1906  *   Mic-In: 0x18
1907  *   Built-in Mic-In: 0x19
1908  *   Line-In: 0x1b
1909  *   HP-Out: 0x1a
1910  *   SPDIF-Out: 0x1e
1911  */
1912
1913 static struct hda_input_mux alc880_lg_lw_capture_source = {
1914         .num_items = 3,
1915         .items = {
1916                 { "Mic", 0x0 },
1917                 { "Internal Mic", 0x1 },
1918                 { "Line In", 0x2 },
1919         },
1920 };
1921
1922 #define alc880_lg_lw_modes alc880_threestack_modes
1923
1924 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1925         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1926         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1927         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1928         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1929         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1930         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1931         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1932         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1933         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1934         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1935         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1936         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1937         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1938         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1939         {
1940                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1941                 .name = "Channel Mode",
1942                 .info = alc_ch_mode_info,
1943                 .get = alc_ch_mode_get,
1944                 .put = alc_ch_mode_put,
1945         },
1946         { } /* end */
1947 };
1948
1949 static struct hda_verb alc880_lg_lw_init_verbs[] = {
1950         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1951         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1952         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1953
1954         /* set capture source to mic-in */
1955         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1956         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1957         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1958         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1959         /* speaker-out */
1960         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1961         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1962         /* HP-out */
1963         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1964         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1965         /* mic-in to input */
1966         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1967         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1968         /* built-in mic */
1969         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1970         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1971         /* jack sense */
1972         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1973         { }
1974 };
1975
1976 /* toggle speaker-output according to the hp-jack state */
1977 static void alc880_lg_lw_automute(struct hda_codec *codec)
1978 {
1979         unsigned int present;
1980         unsigned char bits;
1981
1982         present = snd_hda_codec_read(codec, 0x1b, 0,
1983                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1984         bits = present ? HDA_AMP_MUTE : 0;
1985         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1986                                  HDA_AMP_MUTE, bits);
1987 }
1988
1989 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1990 {
1991         /* Looks like the unsol event is incompatible with the standard
1992          * definition.  4bit tag is placed at 28 bit!
1993          */
1994         if ((res >> 28) == 0x01)
1995                 alc880_lg_lw_automute(codec);
1996 }
1997
1998 #ifdef CONFIG_SND_HDA_POWER_SAVE
1999 static struct hda_amp_list alc880_loopbacks[] = {
2000         { 0x0b, HDA_INPUT, 0 },
2001         { 0x0b, HDA_INPUT, 1 },
2002         { 0x0b, HDA_INPUT, 2 },
2003         { 0x0b, HDA_INPUT, 3 },
2004         { 0x0b, HDA_INPUT, 4 },
2005         { } /* end */
2006 };
2007
2008 static struct hda_amp_list alc880_lg_loopbacks[] = {
2009         { 0x0b, HDA_INPUT, 1 },
2010         { 0x0b, HDA_INPUT, 6 },
2011         { 0x0b, HDA_INPUT, 7 },
2012         { } /* end */
2013 };
2014 #endif
2015
2016 /*
2017  * Common callbacks
2018  */
2019
2020 static int alc_init(struct hda_codec *codec)
2021 {
2022         struct alc_spec *spec = codec->spec;
2023         unsigned int i;
2024
2025         for (i = 0; i < spec->num_init_verbs; i++)
2026                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2027
2028         if (spec->init_hook)
2029                 spec->init_hook(codec);
2030
2031         return 0;
2032 }
2033
2034 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2035 {
2036         struct alc_spec *spec = codec->spec;
2037
2038         if (spec->unsol_event)
2039                 spec->unsol_event(codec, res);
2040 }
2041
2042 #ifdef CONFIG_SND_HDA_POWER_SAVE
2043 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2044 {
2045         struct alc_spec *spec = codec->spec;
2046         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2047 }
2048 #endif
2049
2050 /*
2051  * Analog playback callbacks
2052  */
2053 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2054                                     struct hda_codec *codec,
2055                                     struct snd_pcm_substream *substream)
2056 {
2057         struct alc_spec *spec = codec->spec;
2058         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2059 }
2060
2061 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2062                                        struct hda_codec *codec,
2063                                        unsigned int stream_tag,
2064                                        unsigned int format,
2065                                        struct snd_pcm_substream *substream)
2066 {
2067         struct alc_spec *spec = codec->spec;
2068         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2069                                                 stream_tag, format, substream);
2070 }
2071
2072 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2073                                        struct hda_codec *codec,
2074                                        struct snd_pcm_substream *substream)
2075 {
2076         struct alc_spec *spec = codec->spec;
2077         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2078 }
2079
2080 /*
2081  * Digital out
2082  */
2083 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2084                                         struct hda_codec *codec,
2085                                         struct snd_pcm_substream *substream)
2086 {
2087         struct alc_spec *spec = codec->spec;
2088         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2089 }
2090
2091 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2092                                            struct hda_codec *codec,
2093                                            unsigned int stream_tag,
2094                                            unsigned int format,
2095                                            struct snd_pcm_substream *substream)
2096 {
2097         struct alc_spec *spec = codec->spec;
2098         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2099                                              stream_tag, format, substream);
2100 }
2101
2102 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2103                                          struct hda_codec *codec,
2104                                          struct snd_pcm_substream *substream)
2105 {
2106         struct alc_spec *spec = codec->spec;
2107         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2108 }
2109
2110 /*
2111  * Analog capture
2112  */
2113 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2114                                       struct hda_codec *codec,
2115                                       unsigned int stream_tag,
2116                                       unsigned int format,
2117                                       struct snd_pcm_substream *substream)
2118 {
2119         struct alc_spec *spec = codec->spec;
2120
2121         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2122                                    stream_tag, 0, format);
2123         return 0;
2124 }
2125
2126 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2127                                       struct hda_codec *codec,
2128                                       struct snd_pcm_substream *substream)
2129 {
2130         struct alc_spec *spec = codec->spec;
2131
2132         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2133                                    0, 0, 0);
2134         return 0;
2135 }
2136
2137
2138 /*
2139  */
2140 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2141         .substreams = 1,
2142         .channels_min = 2,
2143         .channels_max = 8,
2144         /* NID is set in alc_build_pcms */
2145         .ops = {
2146                 .open = alc880_playback_pcm_open,
2147                 .prepare = alc880_playback_pcm_prepare,
2148                 .cleanup = alc880_playback_pcm_cleanup
2149         },
2150 };
2151
2152 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2153         .substreams = 2,
2154         .channels_min = 2,
2155         .channels_max = 2,
2156         /* NID is set in alc_build_pcms */
2157         .ops = {
2158                 .prepare = alc880_capture_pcm_prepare,
2159                 .cleanup = alc880_capture_pcm_cleanup
2160         },
2161 };
2162
2163 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2164         .substreams = 1,
2165         .channels_min = 2,
2166         .channels_max = 2,
2167         /* NID is set in alc_build_pcms */
2168         .ops = {
2169                 .open = alc880_dig_playback_pcm_open,
2170                 .close = alc880_dig_playback_pcm_close,
2171                 .prepare = alc880_dig_playback_pcm_prepare
2172         },
2173 };
2174
2175 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2176         .substreams = 1,
2177         .channels_min = 2,
2178         .channels_max = 2,
2179         /* NID is set in alc_build_pcms */
2180 };
2181
2182 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2183 static struct hda_pcm_stream alc_pcm_null_playback = {
2184         .substreams = 0,
2185         .channels_min = 0,
2186         .channels_max = 0,
2187 };
2188
2189 static int alc_build_pcms(struct hda_codec *codec)
2190 {
2191         struct alc_spec *spec = codec->spec;
2192         struct hda_pcm *info = spec->pcm_rec;
2193         int i;
2194
2195         codec->num_pcms = 1;
2196         codec->pcm_info = info;
2197
2198         info->name = spec->stream_name_analog;
2199         if (spec->stream_analog_playback) {
2200                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2201                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2202                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2203         }
2204         if (spec->stream_analog_capture) {
2205                 snd_assert(spec->adc_nids, return -EINVAL);
2206                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2207                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2208         }
2209
2210         if (spec->channel_mode) {
2211                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2212                 for (i = 0; i < spec->num_channel_mode; i++) {
2213                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2214                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2215                         }
2216                 }
2217         }
2218
2219         /* SPDIF for stream index #1 */
2220         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2221                 codec->num_pcms = 2;
2222                 info = spec->pcm_rec + 1;
2223                 info->name = spec->stream_name_digital;
2224                 if (spec->multiout.dig_out_nid &&
2225                     spec->stream_digital_playback) {
2226                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2227                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2228                 }
2229                 if (spec->dig_in_nid &&
2230                     spec->stream_digital_capture) {
2231                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2232                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2233                 }
2234         }
2235
2236         /* If the use of more than one ADC is requested for the current
2237          * model, configure a second analog capture-only PCM.
2238          */
2239         /* Additional Analaog capture for index #2 */
2240         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2241             spec->adc_nids) {
2242                 codec->num_pcms = 3;
2243                 info = spec->pcm_rec + 2;
2244                 info->name = spec->stream_name_analog;
2245                 /* No playback stream for second PCM */
2246                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2247                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2248                 if (spec->stream_analog_capture) {
2249                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2250                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2251                 }
2252         }
2253
2254         return 0;
2255 }
2256
2257 static void alc_free(struct hda_codec *codec)
2258 {
2259         struct alc_spec *spec = codec->spec;
2260         unsigned int i;
2261
2262         if (!spec)
2263                 return;
2264
2265         if (spec->kctl_alloc) {
2266                 for (i = 0; i < spec->num_kctl_used; i++)
2267                         kfree(spec->kctl_alloc[i].name);
2268                 kfree(spec->kctl_alloc);
2269         }
2270         kfree(spec);
2271 }
2272
2273 /*
2274  */
2275 static struct hda_codec_ops alc_patch_ops = {
2276         .build_controls = alc_build_controls,
2277         .build_pcms = alc_build_pcms,
2278         .init = alc_init,
2279         .free = alc_free,
2280         .unsol_event = alc_unsol_event,
2281 #ifdef CONFIG_SND_HDA_POWER_SAVE
2282         .check_power_status = alc_check_power_status,
2283 #endif
2284 };
2285
2286
2287 /*
2288  * Test configuration for debugging
2289  *
2290  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2291  * enum controls.
2292  */
2293 #ifdef CONFIG_SND_DEBUG
2294 static hda_nid_t alc880_test_dac_nids[4] = {
2295         0x02, 0x03, 0x04, 0x05
2296 };
2297
2298 static struct hda_input_mux alc880_test_capture_source = {
2299         .num_items = 7,
2300         .items = {
2301                 { "In-1", 0x0 },
2302                 { "In-2", 0x1 },
2303                 { "In-3", 0x2 },
2304                 { "In-4", 0x3 },
2305                 { "CD", 0x4 },
2306                 { "Front", 0x5 },
2307                 { "Surround", 0x6 },
2308         },
2309 };
2310
2311 static struct hda_channel_mode alc880_test_modes[4] = {
2312         { 2, NULL },
2313         { 4, NULL },
2314         { 6, NULL },
2315         { 8, NULL },
2316 };
2317
2318 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2319                                  struct snd_ctl_elem_info *uinfo)
2320 {
2321         static char *texts[] = {
2322                 "N/A", "Line Out", "HP Out",
2323                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2324         };
2325         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2326         uinfo->count = 1;
2327         uinfo->value.enumerated.items = 8;
2328         if (uinfo->value.enumerated.item >= 8)
2329                 uinfo->value.enumerated.item = 7;
2330         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2331         return 0;
2332 }
2333
2334 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2335                                 struct snd_ctl_elem_value *ucontrol)
2336 {
2337         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2338         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2339         unsigned int pin_ctl, item = 0;
2340
2341         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2342                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2343         if (pin_ctl & AC_PINCTL_OUT_EN) {
2344                 if (pin_ctl & AC_PINCTL_HP_EN)
2345                         item = 2;
2346                 else
2347                         item = 1;
2348         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2349                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2350                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2351                 case AC_PINCTL_VREF_50:  item = 4; break;
2352                 case AC_PINCTL_VREF_GRD: item = 5; break;
2353                 case AC_PINCTL_VREF_80:  item = 6; break;
2354                 case AC_PINCTL_VREF_100: item = 7; break;
2355                 }
2356         }
2357         ucontrol->value.enumerated.item[0] = item;
2358         return 0;
2359 }
2360
2361 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2362                                 struct snd_ctl_elem_value *ucontrol)
2363 {
2364         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2365         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2366         static unsigned int ctls[] = {
2367                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2368                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2369                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2370                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2371                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2372                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2373         };
2374         unsigned int old_ctl, new_ctl;
2375
2376         old_ctl = snd_hda_codec_read(codec, nid, 0,
2377                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2378         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2379         if (old_ctl != new_ctl) {
2380                 int val;
2381                 snd_hda_codec_write_cache(codec, nid, 0,
2382                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
2383                                           new_ctl);
2384                 val = ucontrol->value.enumerated.item[0] >= 3 ?
2385                         HDA_AMP_MUTE : 0;
2386                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2387                                          HDA_AMP_MUTE, val);
2388                 return 1;
2389         }
2390         return 0;
2391 }
2392
2393 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2394                                  struct snd_ctl_elem_info *uinfo)
2395 {
2396         static char *texts[] = {
2397                 "Front", "Surround", "CLFE", "Side"
2398         };
2399         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2400         uinfo->count = 1;
2401         uinfo->value.enumerated.items = 4;
2402         if (uinfo->value.enumerated.item >= 4)
2403                 uinfo->value.enumerated.item = 3;
2404         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2405         return 0;
2406 }
2407
2408 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2409                                 struct snd_ctl_elem_value *ucontrol)
2410 {
2411         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2412         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2413         unsigned int sel;
2414
2415         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2416         ucontrol->value.enumerated.item[0] = sel & 3;
2417         return 0;
2418 }
2419
2420 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2421                                 struct snd_ctl_elem_value *ucontrol)
2422 {
2423         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2424         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2425         unsigned int sel;
2426
2427         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2428         if (ucontrol->value.enumerated.item[0] != sel) {
2429                 sel = ucontrol->value.enumerated.item[0] & 3;
2430                 snd_hda_codec_write_cache(codec, nid, 0,
2431                                           AC_VERB_SET_CONNECT_SEL, sel);
2432                 return 1;
2433         }
2434         return 0;
2435 }
2436
2437 #define PIN_CTL_TEST(xname,nid) {                       \
2438                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2439                         .name = xname,                 \
2440                         .info = alc_test_pin_ctl_info, \
2441                         .get = alc_test_pin_ctl_get,   \
2442                         .put = alc_test_pin_ctl_put,   \
2443                         .private_value = nid           \
2444                         }
2445
2446 #define PIN_SRC_TEST(xname,nid) {                       \
2447                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2448                         .name = xname,                 \
2449                         .info = alc_test_pin_src_info, \
2450                         .get = alc_test_pin_src_get,   \
2451                         .put = alc_test_pin_src_put,   \
2452                         .private_value = nid           \
2453                         }
2454
2455 static struct snd_kcontrol_new alc880_test_mixer[] = {
2456         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2457         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2458         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2459         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2460         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2461         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2462         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2463         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2464         PIN_CTL_TEST("Front Pin Mode", 0x14),
2465         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2466         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2467         PIN_CTL_TEST("Side Pin Mode", 0x17),
2468         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2469         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2470         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2471         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2472         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2473         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2474         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2475         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2476         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2477         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2478         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2479         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2480         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2481         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2482         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2483         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2484         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2485         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2486         {
2487                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2488                 .name = "Channel Mode",
2489                 .info = alc_ch_mode_info,
2490                 .get = alc_ch_mode_get,
2491                 .put = alc_ch_mode_put,
2492         },
2493         { } /* end */
2494 };
2495
2496 static struct hda_verb alc880_test_init_verbs[] = {
2497         /* Unmute inputs of 0x0c - 0x0f */
2498         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2499         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2500         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2501         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2502         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2503         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2504         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2505         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2506         /* Vol output for 0x0c-0x0f */
2507         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2508         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2509         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2510         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2511         /* Set output pins 0x14-0x17 */
2512         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2513         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2514         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2515         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2516         /* Unmute output pins 0x14-0x17 */
2517         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2518         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2519         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2520         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2521         /* Set input pins 0x18-0x1c */
2522         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2523         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2524         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2525         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2526         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2527         /* Mute input pins 0x18-0x1b */
2528         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2529         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2531         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2532         /* ADC set up */
2533         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2534         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2535         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2536         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2537         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2538         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2539         /* Analog input/passthru */
2540         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2541         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2542         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2543         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2544         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2545         { }
2546 };
2547 #endif
2548
2549 /*
2550  */
2551
2552 static const char *alc880_models[ALC880_MODEL_LAST] = {
2553         [ALC880_3ST]            = "3stack",
2554         [ALC880_TCL_S700]       = "tcl",
2555         [ALC880_3ST_DIG]        = "3stack-digout",
2556         [ALC880_CLEVO]          = "clevo",
2557         [ALC880_5ST]            = "5stack",
2558         [ALC880_5ST_DIG]        = "5stack-digout",
2559         [ALC880_W810]           = "w810",
2560         [ALC880_Z71V]           = "z71v",
2561         [ALC880_6ST]            = "6stack",
2562         [ALC880_6ST_DIG]        = "6stack-digout",
2563         [ALC880_ASUS]           = "asus",
2564         [ALC880_ASUS_W1V]       = "asus-w1v",
2565         [ALC880_ASUS_DIG]       = "asus-dig",
2566         [ALC880_ASUS_DIG2]      = "asus-dig2",
2567         [ALC880_UNIWILL_DIG]    = "uniwill",
2568         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2569         [ALC880_FUJITSU]        = "fujitsu",
2570         [ALC880_F1734]          = "F1734",
2571         [ALC880_LG]             = "lg",
2572         [ALC880_LG_LW]          = "lg-lw",
2573 #ifdef CONFIG_SND_DEBUG
2574         [ALC880_TEST]           = "test",
2575 #endif
2576         [ALC880_AUTO]           = "auto",
2577 };
2578
2579 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2580         /* Broken BIOS configuration */
2581         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2582         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2583
2584         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2585         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2586         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2587         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2588         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2589         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2590         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2591         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2592         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2593
2594         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2595         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2596
2597         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2598         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2599         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2600         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2601         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2602         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2603         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2604         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2605         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2606         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2607         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2608         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2609         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2610         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2611         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2612
2613         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2614         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2615         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2616         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2617         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2618         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2619         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2620         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2621         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2622         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2623         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2624         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2625         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2626         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2627         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2628         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2629         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2630         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2631
2632         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2633         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2634         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2635         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2636
2637         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2638         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2639         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2640         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2641
2642         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2643         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2644         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2645         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2646
2647         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2648         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2649         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2650         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2651         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2652         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2653         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2654         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2655         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2656         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2657         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2658
2659         {}
2660 };
2661
2662 /*
2663  * ALC880 codec presets
2664  */
2665 static struct alc_config_preset alc880_presets[] = {
2666         [ALC880_3ST] = {
2667                 .mixers = { alc880_three_stack_mixer },
2668                 .init_verbs = { alc880_volume_init_verbs,
2669                                 alc880_pin_3stack_init_verbs },
2670                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2671                 .dac_nids = alc880_dac_nids,
2672                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2673                 .channel_mode = alc880_threestack_modes,
2674                 .need_dac_fix = 1,
2675                 .input_mux = &alc880_capture_source,
2676         },
2677         [ALC880_3ST_DIG] = {
2678                 .mixers = { alc880_three_stack_mixer },
2679                 .init_verbs = { alc880_volume_init_verbs,
2680                                 alc880_pin_3stack_init_verbs },
2681                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2682                 .dac_nids = alc880_dac_nids,
2683                 .dig_out_nid = ALC880_DIGOUT_NID,
2684                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2685                 .channel_mode = alc880_threestack_modes,
2686                 .need_dac_fix = 1,
2687                 .input_mux = &alc880_capture_source,
2688         },
2689         [ALC880_TCL_S700] = {
2690                 .mixers = { alc880_tcl_s700_mixer },
2691                 .init_verbs = { alc880_volume_init_verbs,
2692                                 alc880_pin_tcl_S700_init_verbs,
2693                                 alc880_gpio2_init_verbs },
2694                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2695                 .dac_nids = alc880_dac_nids,
2696                 .hp_nid = 0x03,
2697                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2698                 .channel_mode = alc880_2_jack_modes,
2699                 .input_mux = &alc880_capture_source,
2700         },
2701         [ALC880_5ST] = {
2702                 .mixers = { alc880_three_stack_mixer,
2703                             alc880_five_stack_mixer},
2704                 .init_verbs = { alc880_volume_init_verbs,
2705                                 alc880_pin_5stack_init_verbs },
2706                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2707                 .dac_nids = alc880_dac_nids,
2708                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2709                 .channel_mode = alc880_fivestack_modes,
2710                 .input_mux = &alc880_capture_source,
2711         },
2712         [ALC880_5ST_DIG] = {
2713                 .mixers = { alc880_three_stack_mixer,
2714                             alc880_five_stack_mixer },
2715                 .init_verbs = { alc880_volume_init_verbs,
2716                                 alc880_pin_5stack_init_verbs },
2717                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2718                 .dac_nids = alc880_dac_nids,
2719                 .dig_out_nid = ALC880_DIGOUT_NID,
2720                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2721                 .channel_mode = alc880_fivestack_modes,
2722                 .input_mux = &alc880_capture_source,
2723         },
2724         [ALC880_6ST] = {
2725                 .mixers = { alc880_six_stack_mixer },
2726                 .init_verbs = { alc880_volume_init_verbs,
2727                                 alc880_pin_6stack_init_verbs },
2728                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2729                 .dac_nids = alc880_6st_dac_nids,
2730                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2731                 .channel_mode = alc880_sixstack_modes,
2732                 .input_mux = &alc880_6stack_capture_source,
2733         },
2734         [ALC880_6ST_DIG] = {
2735                 .mixers = { alc880_six_stack_mixer },
2736                 .init_verbs = { alc880_volume_init_verbs,
2737                                 alc880_pin_6stack_init_verbs },
2738                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2739                 .dac_nids = alc880_6st_dac_nids,
2740                 .dig_out_nid = ALC880_DIGOUT_NID,
2741                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2742                 .channel_mode = alc880_sixstack_modes,
2743                 .input_mux = &alc880_6stack_capture_source,
2744         },
2745         [ALC880_W810] = {
2746                 .mixers = { alc880_w810_base_mixer },
2747                 .init_verbs = { alc880_volume_init_verbs,
2748                                 alc880_pin_w810_init_verbs,
2749                                 alc880_gpio2_init_verbs },
2750                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2751                 .dac_nids = alc880_w810_dac_nids,
2752                 .dig_out_nid = ALC880_DIGOUT_NID,
2753                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2754                 .channel_mode = alc880_w810_modes,
2755                 .input_mux = &alc880_capture_source,
2756         },
2757         [ALC880_Z71V] = {
2758                 .mixers = { alc880_z71v_mixer },
2759                 .init_verbs = { alc880_volume_init_verbs,
2760                                 alc880_pin_z71v_init_verbs },
2761                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2762                 .dac_nids = alc880_z71v_dac_nids,
2763                 .dig_out_nid = ALC880_DIGOUT_NID,
2764                 .hp_nid = 0x03,
2765                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2766                 .channel_mode = alc880_2_jack_modes,
2767                 .input_mux = &alc880_capture_source,
2768         },
2769         [ALC880_F1734] = {
2770                 .mixers = { alc880_f1734_mixer },
2771                 .init_verbs = { alc880_volume_init_verbs,
2772                                 alc880_pin_f1734_init_verbs },
2773                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2774                 .dac_nids = alc880_f1734_dac_nids,
2775                 .hp_nid = 0x02,
2776                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2777                 .channel_mode = alc880_2_jack_modes,
2778                 .input_mux = &alc880_capture_source,
2779         },
2780         [ALC880_ASUS] = {
2781                 .mixers = { alc880_asus_mixer },
2782                 .init_verbs = { alc880_volume_init_verbs,
2783                                 alc880_pin_asus_init_verbs,
2784                                 alc880_gpio1_init_verbs },
2785                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2786                 .dac_nids = alc880_asus_dac_nids,
2787                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2788                 .channel_mode = alc880_asus_modes,
2789                 .need_dac_fix = 1,
2790                 .input_mux = &alc880_capture_source,
2791         },
2792         [ALC880_ASUS_DIG] = {
2793                 .mixers = { alc880_asus_mixer },
2794                 .init_verbs = { alc880_volume_init_verbs,
2795                                 alc880_pin_asus_init_verbs,
2796                                 alc880_gpio1_init_verbs },
2797                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2798                 .dac_nids = alc880_asus_dac_nids,
2799                 .dig_out_nid = ALC880_DIGOUT_NID,
2800                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2801                 .channel_mode = alc880_asus_modes,
2802                 .need_dac_fix = 1,
2803                 .input_mux = &alc880_capture_source,
2804         },
2805         [ALC880_ASUS_DIG2] = {
2806                 .mixers = { alc880_asus_mixer },
2807                 .init_verbs = { alc880_volume_init_verbs,
2808                                 alc880_pin_asus_init_verbs,
2809                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2810                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2811                 .dac_nids = alc880_asus_dac_nids,
2812                 .dig_out_nid = ALC880_DIGOUT_NID,
2813                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2814                 .channel_mode = alc880_asus_modes,
2815                 .need_dac_fix = 1,
2816                 .input_mux = &alc880_capture_source,
2817         },
2818         [ALC880_ASUS_W1V] = {
2819                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2820                 .init_verbs = { alc880_volume_init_verbs,
2821                                 alc880_pin_asus_init_verbs,
2822                                 alc880_gpio1_init_verbs },
2823                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2824                 .dac_nids = alc880_asus_dac_nids,
2825                 .dig_out_nid = ALC880_DIGOUT_NID,
2826                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2827                 .channel_mode = alc880_asus_modes,
2828                 .need_dac_fix = 1,
2829                 .input_mux = &alc880_capture_source,
2830         },
2831         [ALC880_UNIWILL_DIG] = {
2832                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2833                 .init_verbs = { alc880_volume_init_verbs,
2834                                 alc880_pin_asus_init_verbs },
2835                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2836                 .dac_nids = alc880_asus_dac_nids,
2837                 .dig_out_nid = ALC880_DIGOUT_NID,
2838                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2839                 .channel_mode = alc880_asus_modes,
2840                 .need_dac_fix = 1,
2841                 .input_mux = &alc880_capture_source,
2842         },
2843         [ALC880_UNIWILL] = {
2844                 .mixers = { alc880_uniwill_mixer },
2845                 .init_verbs = { alc880_volume_init_verbs,
2846                                 alc880_uniwill_init_verbs },
2847                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2848                 .dac_nids = alc880_asus_dac_nids,
2849                 .dig_out_nid = ALC880_DIGOUT_NID,
2850                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2851                 .channel_mode = alc880_threestack_modes,
2852                 .need_dac_fix = 1,
2853                 .input_mux = &alc880_capture_source,
2854                 .unsol_event = alc880_uniwill_unsol_event,
2855                 .init_hook = alc880_uniwill_automute,
2856         },
2857         [ALC880_UNIWILL_P53] = {
2858                 .mixers = { alc880_uniwill_p53_mixer },
2859                 .init_verbs = { alc880_volume_init_verbs,
2860                                 alc880_uniwill_p53_init_verbs },
2861                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2862                 .dac_nids = alc880_asus_dac_nids,
2863                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2864                 .channel_mode = alc880_threestack_modes,
2865                 .input_mux = &alc880_capture_source,
2866                 .unsol_event = alc880_uniwill_p53_unsol_event,
2867                 .init_hook = alc880_uniwill_p53_hp_automute,
2868         },
2869         [ALC880_FUJITSU] = {
2870                 .mixers = { alc880_fujitsu_mixer,
2871                             alc880_pcbeep_mixer, },
2872                 .init_verbs = { alc880_volume_init_verbs,
2873                                 alc880_uniwill_p53_init_verbs,
2874                                 alc880_beep_init_verbs },
2875                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2876                 .dac_nids = alc880_dac_nids,
2877                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2878                 .channel_mode = alc880_2_jack_modes,
2879                 .input_mux = &alc880_capture_source,
2880                 .unsol_event = alc880_uniwill_p53_unsol_event,
2881                 .init_hook = alc880_uniwill_p53_hp_automute,
2882         },
2883         [ALC880_CLEVO] = {
2884                 .mixers = { alc880_three_stack_mixer },
2885                 .init_verbs = { alc880_volume_init_verbs,
2886                                 alc880_pin_clevo_init_verbs },
2887                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2888                 .dac_nids = alc880_dac_nids,
2889                 .hp_nid = 0x03,
2890                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2891                 .channel_mode = alc880_threestack_modes,
2892                 .need_dac_fix = 1,
2893                 .input_mux = &alc880_capture_source,
2894         },
2895         [ALC880_LG] = {
2896                 .mixers = { alc880_lg_mixer },
2897                 .init_verbs = { alc880_volume_init_verbs,
2898                                 alc880_lg_init_verbs },
2899                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2900                 .dac_nids = alc880_lg_dac_nids,
2901                 .dig_out_nid = ALC880_DIGOUT_NID,
2902                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2903                 .channel_mode = alc880_lg_ch_modes,
2904                 .need_dac_fix = 1,
2905                 .input_mux = &alc880_lg_capture_source,
2906                 .unsol_event = alc880_lg_unsol_event,
2907                 .init_hook = alc880_lg_automute,
2908 #ifdef CONFIG_SND_HDA_POWER_SAVE
2909                 .loopbacks = alc880_lg_loopbacks,
2910 #endif
2911         },
2912         [ALC880_LG_LW] = {
2913                 .mixers = { alc880_lg_lw_mixer },
2914                 .init_verbs = { alc880_volume_init_verbs,
2915                                 alc880_lg_lw_init_verbs },
2916                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2917                 .dac_nids = alc880_dac_nids,
2918                 .dig_out_nid = ALC880_DIGOUT_NID,
2919                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2920                 .channel_mode = alc880_lg_lw_modes,
2921                 .input_mux = &alc880_lg_lw_capture_source,
2922                 .unsol_event = alc880_lg_lw_unsol_event,
2923                 .init_hook = alc880_lg_lw_automute,
2924         },
2925 #ifdef CONFIG_SND_DEBUG
2926         [ALC880_TEST] = {
2927                 .mixers = { alc880_test_mixer },
2928                 .init_verbs = { alc880_test_init_verbs },
2929                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2930                 .dac_nids = alc880_test_dac_nids,
2931                 .dig_out_nid = ALC880_DIGOUT_NID,
2932                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2933                 .channel_mode = alc880_test_modes,
2934                 .input_mux = &alc880_test_capture_source,
2935         },
2936 #endif
2937 };
2938
2939 /*
2940  * Automatic parse of I/O pins from the BIOS configuration
2941  */
2942
2943 #define NUM_CONTROL_ALLOC       32
2944 #define NUM_VERB_ALLOC          32
2945
2946 enum {
2947         ALC_CTL_WIDGET_VOL,
2948         ALC_CTL_WIDGET_MUTE,
2949         ALC_CTL_BIND_MUTE,
2950 };
2951 static struct snd_kcontrol_new alc880_control_templates[] = {
2952         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2953         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2954         HDA_BIND_MUTE(NULL, 0, 0, 0),
2955 };
2956
2957 /* add dynamic controls */
2958 static int add_control(struct alc_spec *spec, int type, const char *name,
2959                        unsigned long val)
2960 {
2961         struct snd_kcontrol_new *knew;
2962
2963         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2964                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2965
2966                 /* array + terminator */
2967                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2968                 if (!knew)
2969                         return -ENOMEM;
2970                 if (spec->kctl_alloc) {
2971                         memcpy(knew, spec->kctl_alloc,
2972                                sizeof(*knew) * spec->num_kctl_alloc);
2973                         kfree(spec->kctl_alloc);
2974                 }
2975                 spec->kctl_alloc = knew;
2976                 spec->num_kctl_alloc = num;
2977         }
2978
2979         knew = &spec->kctl_alloc[spec->num_kctl_used];
2980         *knew = alc880_control_templates[type];
2981         knew->name = kstrdup(name, GFP_KERNEL);
2982         if (!knew->name)
2983                 return -ENOMEM;
2984         knew->private_value = val;
2985         spec->num_kctl_used++;
2986         return 0;
2987 }
2988
2989 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
2990 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
2991 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
2992 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
2993 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
2994 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
2995 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
2996 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
2997 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
2998 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
2999 #define ALC880_PIN_CD_NID               0x1c
3000
3001 /* fill in the dac_nids table from the parsed pin configuration */
3002 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3003                                      const struct auto_pin_cfg *cfg)
3004 {
3005         hda_nid_t nid;
3006         int assigned[4];
3007         int i, j;
3008
3009         memset(assigned, 0, sizeof(assigned));
3010         spec->multiout.dac_nids = spec->private_dac_nids;
3011
3012         /* check the pins hardwired to audio widget */
3013         for (i = 0; i < cfg->line_outs; i++) {
3014                 nid = cfg->line_out_pins[i];
3015                 if (alc880_is_fixed_pin(nid)) {
3016                         int idx = alc880_fixed_pin_idx(nid);
3017                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3018                         assigned[idx] = 1;
3019                 }
3020         }
3021         /* left pins can be connect to any audio widget */
3022         for (i = 0; i < cfg->line_outs; i++) {
3023                 nid = cfg->line_out_pins[i];
3024                 if (alc880_is_fixed_pin(nid))
3025                         continue;
3026                 /* search for an empty channel */
3027                 for (j = 0; j < cfg->line_outs; j++) {
3028                         if (!assigned[j]) {
3029                                 spec->multiout.dac_nids[i] =
3030                                         alc880_idx_to_dac(j);
3031                                 assigned[j] = 1;
3032                                 break;
3033                         }
3034                 }
3035         }
3036         spec->multiout.num_dacs = cfg->line_outs;
3037         return 0;
3038 }
3039
3040 /* add playback controls from the parsed DAC table */
3041 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3042                                              const struct auto_pin_cfg *cfg)
3043 {
3044         char name[32];
3045         static const char *chname[4] = {
3046                 "Front", "Surround", NULL /*CLFE*/, "Side"
3047         };
3048         hda_nid_t nid;
3049         int i, err;
3050
3051         for (i = 0; i < cfg->line_outs; i++) {
3052                 if (!spec->multiout.dac_nids[i])
3053                         continue;
3054                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3055                 if (i == 2) {
3056                         /* Center/LFE */
3057                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3058                                           "Center Playback Volume",
3059                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3060                                                               HDA_OUTPUT));
3061                         if (err < 0)
3062                                 return err;
3063                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3064                                           "LFE Playback Volume",
3065                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3066                                                               HDA_OUTPUT));
3067                         if (err < 0)
3068                                 return err;
3069                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3070                                           "Center Playback Switch",
3071                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3072                                                               HDA_INPUT));
3073                         if (err < 0)
3074                                 return err;
3075                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3076                                           "LFE Playback Switch",
3077                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3078                                                               HDA_INPUT));
3079                         if (err < 0)
3080                                 return err;
3081                 } else {
3082                         sprintf(name, "%s Playback Volume", chname[i]);
3083                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3084                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3085                                                               HDA_OUTPUT));
3086                         if (err < 0)
3087                                 return err;
3088                         sprintf(name, "%s Playback Switch", chname[i]);
3089                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3090                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3091                                                               HDA_INPUT));
3092                         if (err < 0)
3093                                 return err;
3094                 }
3095         }
3096         return 0;
3097 }
3098
3099 /* add playback controls for speaker and HP outputs */
3100 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3101                                         const char *pfx)
3102 {
3103         hda_nid_t nid;
3104         int err;
3105         char name[32];
3106
3107         if (!pin)
3108                 return 0;
3109
3110         if (alc880_is_fixed_pin(pin)) {
3111                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3112                 /* specify the DAC as the extra output */
3113                 if (!spec->multiout.hp_nid)
3114                         spec->multiout.hp_nid = nid;
3115                 else
3116                         spec->multiout.extra_out_nid[0] = nid;
3117                 /* control HP volume/switch on the output mixer amp */
3118                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3119                 sprintf(name, "%s Playback Volume", pfx);
3120                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3121                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3122                 if (err < 0)
3123                         return err;
3124                 sprintf(name, "%s Playback Switch", pfx);
3125                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3126                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3127                 if (err < 0)
3128                         return err;
3129         } else if (alc880_is_multi_pin(pin)) {
3130                 /* set manual connection */
3131                 /* we have only a switch on HP-out PIN */
3132                 sprintf(name, "%s Playback Switch", pfx);
3133                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3134                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3135                 if (err < 0)
3136                         return err;
3137         }
3138         return 0;
3139 }
3140
3141 /* create input playback/capture controls for the given pin */
3142 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3143                             const char *ctlname,
3144                             int idx, hda_nid_t mix_nid)
3145 {
3146         char name[32];
3147         int err;
3148
3149         sprintf(name, "%s Playback Volume", ctlname);
3150         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3151                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3152         if (err < 0)
3153                 return err;
3154         sprintf(name, "%s Playback Switch", ctlname);
3155         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3156                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3157         if (err < 0)
3158                 return err;
3159         return 0;
3160 }
3161
3162 /* create playback/capture controls for input pins */
3163 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3164                                                 const struct auto_pin_cfg *cfg)
3165 {
3166         struct hda_input_mux *imux = &spec->private_imux;
3167         int i, err, idx;
3168
3169         for (i = 0; i < AUTO_PIN_LAST; i++) {
3170                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3171                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3172                         err = new_analog_input(spec, cfg->input_pins[i],
3173                                                auto_pin_cfg_labels[i],
3174                                                idx, 0x0b);
3175                         if (err < 0)
3176                                 return err;
3177                         imux->items[imux->num_items].label =
3178                                 auto_pin_cfg_labels[i];
3179                         imux->items[imux->num_items].index =
3180                                 alc880_input_pin_idx(cfg->input_pins[i]);
3181                         imux->num_items++;
3182                 }
3183         }
3184         return 0;
3185 }
3186
3187 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3188                                               hda_nid_t nid, int pin_type,
3189                                               int dac_idx)
3190 {
3191         /* set as output */
3192         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3193                             pin_type);
3194         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3195                             AMP_OUT_UNMUTE);
3196         /* need the manual connection? */
3197         if (alc880_is_multi_pin(nid)) {
3198                 struct alc_spec *spec = codec->spec;
3199                 int idx = alc880_multi_pin_idx(nid);
3200                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3201                                     AC_VERB_SET_CONNECT_SEL,
3202                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3203         }
3204 }
3205
3206 static int get_pin_type(int line_out_type)
3207 {
3208         if (line_out_type == AUTO_PIN_HP_OUT)
3209                 return PIN_HP;
3210         else
3211                 return PIN_OUT;
3212 }
3213
3214 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3215 {
3216         struct alc_spec *spec = codec->spec;
3217         int i;
3218         
3219         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3220         for (i = 0; i < spec->autocfg.line_outs; i++) {
3221                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3222                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3223                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3224         }
3225 }
3226
3227 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3228 {
3229         struct alc_spec *spec = codec->spec;
3230         hda_nid_t pin;
3231
3232         pin = spec->autocfg.speaker_pins[0];
3233         if (pin) /* connect to front */
3234                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3235         pin = spec->autocfg.hp_pins[0];
3236         if (pin) /* connect to front */
3237                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3238 }
3239
3240 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3241 {
3242         struct alc_spec *spec = codec->spec;
3243         int i;
3244
3245         for (i = 0; i < AUTO_PIN_LAST; i++) {
3246                 hda_nid_t nid = spec->autocfg.input_pins[i];
3247                 if (alc880_is_input_pin(nid)) {
3248                         snd_hda_codec_write(codec, nid, 0,
3249                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3250                                             i <= AUTO_PIN_FRONT_MIC ?
3251                                             PIN_VREF80 : PIN_IN);
3252                         if (nid != ALC880_PIN_CD_NID)
3253                                 snd_hda_codec_write(codec, nid, 0,
3254                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3255                                                     AMP_OUT_MUTE);
3256                 }
3257         }
3258 }
3259
3260 /* parse the BIOS configuration and set up the alc_spec */
3261 /* return 1 if successful, 0 if the proper config is not found,
3262  * or a negative error code
3263  */
3264 static int alc880_parse_auto_config(struct hda_codec *codec)
3265 {
3266         struct alc_spec *spec = codec->spec;
3267         int err;
3268         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3269
3270         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3271                                            alc880_ignore);
3272         if (err < 0)
3273                 return err;
3274         if (!spec->autocfg.line_outs)
3275                 return 0; /* can't find valid BIOS pin config */
3276
3277         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3278         if (err < 0)
3279                 return err;
3280         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3281         if (err < 0)
3282                 return err;
3283         err = alc880_auto_create_extra_out(spec,
3284                                            spec->autocfg.speaker_pins[0],
3285                                            "Speaker");
3286         if (err < 0)
3287                 return err;
3288         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3289                                            "Headphone");
3290         if (err < 0)
3291                 return err;
3292         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3293         if (err < 0)
3294                 return err;
3295
3296         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3297
3298         if (spec->autocfg.dig_out_pin)
3299                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3300         if (spec->autocfg.dig_in_pin)
3301                 spec->dig_in_nid = ALC880_DIGIN_NID;
3302
3303         if (spec->kctl_alloc)
3304                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3305
3306         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3307
3308         spec->num_mux_defs = 1;
3309         spec->input_mux = &spec->private_imux;
3310
3311         return 1;
3312 }
3313
3314 /* additional initialization for auto-configuration model */
3315 static void alc880_auto_init(struct hda_codec *codec)
3316 {
3317         alc880_auto_init_multi_out(codec);
3318         alc880_auto_init_extra_out(codec);
3319         alc880_auto_init_analog_input(codec);
3320 }
3321
3322 /*
3323  * OK, here we have finally the patch for ALC880
3324  */
3325
3326 static int patch_alc880(struct hda_codec *codec)
3327 {
3328         struct alc_spec *spec;
3329         int board_config;
3330         int err;
3331
3332         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3333         if (spec == NULL)
3334                 return -ENOMEM;
3335
3336         codec->spec = spec;
3337
3338         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3339                                                   alc880_models,
3340                                                   alc880_cfg_tbl);
3341         if (board_config < 0) {
3342                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3343                        "trying auto-probe from BIOS...\n");
3344                 board_config = ALC880_AUTO;
3345         }
3346
3347         if (board_config == ALC880_AUTO) {
3348                 /* automatic parse from the BIOS config */
3349                 err = alc880_parse_auto_config(codec);
3350                 if (err < 0) {
3351                         alc_free(codec);
3352                         return err;
3353                 } else if (!err) {
3354                         printk(KERN_INFO
3355                                "hda_codec: Cannot set up configuration "
3356                                "from BIOS.  Using 3-stack mode...\n");
3357                         board_config = ALC880_3ST;
3358                 }
3359         }
3360
3361         if (board_config != ALC880_AUTO)
3362                 setup_preset(spec, &alc880_presets[board_config]);
3363
3364         spec->stream_name_analog = "ALC880 Analog";
3365         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3366         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3367
3368         spec->stream_name_digital = "ALC880 Digital";
3369         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3370         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3371
3372         if (!spec->adc_nids && spec->input_mux) {
3373                 /* check whether NID 0x07 is valid */
3374                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3375                 /* get type */
3376                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3377                 if (wcap != AC_WID_AUD_IN) {
3378                         spec->adc_nids = alc880_adc_nids_alt;
3379                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3380                         spec->mixers[spec->num_mixers] =
3381                                 alc880_capture_alt_mixer;
3382                         spec->num_mixers++;
3383                 } else {
3384                         spec->adc_nids = alc880_adc_nids;
3385                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3386                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3387                         spec->num_mixers++;
3388                 }
3389         }
3390
3391         codec->patch_ops = alc_patch_ops;
3392         if (board_config == ALC880_AUTO)
3393                 spec->init_hook = alc880_auto_init;
3394 #ifdef CONFIG_SND_HDA_POWER_SAVE
3395         if (!spec->loopback.amplist)
3396                 spec->loopback.amplist = alc880_loopbacks;
3397 #endif
3398
3399         return 0;
3400 }
3401
3402
3403 /*
3404  * ALC260 support
3405  */
3406
3407 static hda_nid_t alc260_dac_nids[1] = {
3408         /* front */
3409         0x02,
3410 };
3411
3412 static hda_nid_t alc260_adc_nids[1] = {
3413         /* ADC0 */
3414         0x04,
3415 };
3416
3417 static hda_nid_t alc260_adc_nids_alt[1] = {
3418         /* ADC1 */
3419         0x05,
3420 };
3421
3422 static hda_nid_t alc260_hp_adc_nids[2] = {
3423         /* ADC1, 0 */
3424         0x05, 0x04
3425 };
3426
3427 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3428  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3429  */
3430 static hda_nid_t alc260_dual_adc_nids[2] = {
3431         /* ADC0, ADC1 */
3432         0x04, 0x05
3433 };
3434
3435 #define ALC260_DIGOUT_NID       0x03
3436 #define ALC260_DIGIN_NID        0x06
3437
3438 static struct hda_input_mux alc260_capture_source = {
3439         .num_items = 4,
3440         .items = {
3441                 { "Mic", 0x0 },
3442                 { "Front Mic", 0x1 },
3443                 { "Line", 0x2 },
3444                 { "CD", 0x4 },
3445         },
3446 };
3447
3448 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3449  * headphone jack and the internal CD lines since these are the only pins at
3450  * which audio can appear.  For flexibility, also allow the option of
3451  * recording the mixer output on the second ADC (ADC0 doesn't have a
3452  * connection to the mixer output).
3453  */
3454 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3455         {
3456                 .num_items = 3,
3457                 .items = {
3458                         { "Mic/Line", 0x0 },
3459                         { "CD", 0x4 },
3460                         { "Headphone", 0x2 },
3461                 },
3462         },
3463         {
3464                 .num_items = 4,
3465                 .items = {
3466                         { "Mic/Line", 0x0 },
3467                         { "CD", 0x4 },
3468                         { "Headphone", 0x2 },
3469                         { "Mixer", 0x5 },
3470                 },
3471         },
3472
3473 };
3474
3475 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3476  * the Fujitsu S702x, but jacks are marked differently.
3477  */
3478 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3479         {
3480                 .num_items = 4,
3481                 .items = {
3482                         { "Mic", 0x0 },
3483                         { "Line", 0x2 },
3484                         { "CD", 0x4 },
3485                         { "Headphone", 0x5 },
3486                 },
3487         },
3488         {
3489                 .num_items = 5,
3490                 .items = {
3491                         { "Mic", 0x0 },
3492                         { "Line", 0x2 },
3493                         { "CD", 0x4 },
3494                         { "Headphone", 0x6 },
3495                         { "Mixer", 0x5 },
3496                 },
3497         },
3498 };
3499 /*
3500  * This is just place-holder, so there's something for alc_build_pcms to look
3501  * at when it calculates the maximum number of channels. ALC260 has no mixer
3502  * element which allows changing the channel mode, so the verb list is
3503  * never used.
3504  */
3505 static struct hda_channel_mode alc260_modes[1] = {
3506         { 2, NULL },
3507 };
3508
3509
3510 /* Mixer combinations
3511  *
3512  * basic: base_output + input + pc_beep + capture
3513  * HP: base_output + input + capture_alt
3514  * HP_3013: hp_3013 + input + capture
3515  * fujitsu: fujitsu + capture
3516  * acer: acer + capture
3517  */
3518
3519 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3520         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3521         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3522         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3523         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3524         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3525         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3526         { } /* end */
3527 };
3528
3529 static struct snd_kcontrol_new alc260_input_mixer[] = {
3530         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3531         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3532         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3533         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3534         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3535         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3536         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3537         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3538         { } /* end */
3539 };
3540
3541 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3542         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3543         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3544         { } /* end */
3545 };
3546
3547 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3548         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3549         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3550         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3551         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3552         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3553         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3554         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3555         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3556         { } /* end */
3557 };
3558
3559 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3560  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3561  */
3562 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3563         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3564         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3565         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3566         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3567         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3568         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3569         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3570         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3571         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3572         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3573         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3574         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3575         { } /* end */
3576 };
3577
3578 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3579  * versions of the ALC260 don't act on requests to enable mic bias from NID
3580  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3581  * datasheet doesn't mention this restriction.  At this stage it's not clear
3582  * whether this behaviour is intentional or is a hardware bug in chip
3583  * revisions available in early 2006.  Therefore for now allow the
3584  * "Headphone Jack Mode" control to span all choices, but if it turns out
3585  * that the lack of mic bias for this NID is intentional we could change the
3586  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3587  *
3588  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3589  * don't appear to make the mic bias available from the "line" jack, even
3590  * though the NID used for this jack (0x14) can supply it.  The theory is
3591  * that perhaps Acer have included blocking capacitors between the ALC260
3592  * and the output jack.  If this turns out to be the case for all such
3593  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3594  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3595  *
3596  * The C20x Tablet series have a mono internal speaker which is controlled
3597  * via the chip's Mono sum widget and pin complex, so include the necessary
3598  * controls for such models.  On models without a "mono speaker" the control
3599  * won't do anything.
3600  */
3601 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3602         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3603         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3604         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3605         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3606                               HDA_OUTPUT),
3607         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3608                            HDA_INPUT),
3609         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3610         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3611         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3612         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3613         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3614         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3615         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3616         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3617         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3618         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3619         { } /* end */
3620 };
3621
3622 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3623  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3624  */
3625 static struct snd_kcontrol_new alc260_will_mixer[] = {
3626         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3627         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3628         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3629         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3630         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3631         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3632         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3633         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3634         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3635         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3636         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3637         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3638         { } /* end */
3639 };
3640
3641 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3642  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3643  */
3644 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3645         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3646         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3647         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3648         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3649         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3650         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3651         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3652         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3653         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3654         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3655         { } /* end */
3656 };
3657
3658 /* capture mixer elements */
3659 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3660         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3661         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3662         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3663         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3664         {
3665                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3666                 /* The multiple "Capture Source" controls confuse alsamixer
3667                  * So call somewhat different..
3668                  * FIXME: the controls appear in the "playback" view!
3669                  */
3670                 /* .name = "Capture Source", */
3671                 .name = "Input Source",
3672                 .count = 2,
3673                 .info = alc_mux_enum_info,
3674                 .get = alc_mux_enum_get,
3675                 .put = alc_mux_enum_put,
3676         },
3677         { } /* end */
3678 };
3679
3680 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3681         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3682         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3683         {
3684                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3685                 /* The multiple "Capture Source" controls confuse alsamixer
3686                  * So call somewhat different..
3687                  * FIXME: the controls appear in the "playback" view!
3688                  */
3689                 /* .name = "Capture Source", */
3690                 .name = "Input Source",
3691                 .count = 1,
3692                 .info = alc_mux_enum_info,
3693                 .get = alc_mux_enum_get,
3694                 .put = alc_mux_enum_put,
3695         },
3696         { } /* end */
3697 };
3698
3699 /*
3700  * initialization verbs
3701  */
3702 static struct hda_verb alc260_init_verbs[] = {
3703         /* Line In pin widget for input */
3704         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3705         /* CD pin widget for input */
3706         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3707         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3708         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3709         /* Mic2 (front panel) pin widget for input and vref at 80% */
3710         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3711         /* LINE-2 is used for line-out in rear */
3712         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3713         /* select line-out */
3714         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3715         /* LINE-OUT pin */
3716         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3717         /* enable HP */
3718         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3719         /* enable Mono */
3720         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3721         /* mute capture amp left and right */
3722         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3723         /* set connection select to line in (default select for this ADC) */
3724         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3725         /* mute capture amp left and right */
3726         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3727         /* set connection select to line in (default select for this ADC) */
3728         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3729         /* set vol=0 Line-Out mixer amp left and right */
3730         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3731         /* unmute pin widget amp left and right (no gain on this amp) */
3732         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3733         /* set vol=0 HP mixer amp left and right */
3734         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3735         /* unmute pin widget amp left and right (no gain on this amp) */
3736         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3737         /* set vol=0 Mono mixer amp left and right */
3738         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3739         /* unmute pin widget amp left and right (no gain on this amp) */
3740         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3741         /* unmute LINE-2 out pin */
3742         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3743         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3744          * Line In 2 = 0x03
3745          */
3746         /* mute analog inputs */
3747         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3748         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3749         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3750         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3751         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3752         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3753         /* mute Front out path */
3754         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3755         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3756         /* mute Headphone out path */
3757         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3758         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3759         /* mute Mono out path */
3760         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3761         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3762         { }
3763 };
3764
3765 #if 0 /* should be identical with alc260_init_verbs? */
3766 static struct hda_verb alc260_hp_init_verbs[] = {
3767         /* Headphone and output */
3768         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3769         /* mono output */
3770         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3771         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3772         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3773         /* Mic2 (front panel) pin widget for input and vref at 80% */
3774         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3775         /* Line In pin widget for input */
3776         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3777         /* Line-2 pin widget for output */
3778         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3779         /* CD pin widget for input */
3780         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3781         /* unmute amp left and right */
3782         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3783         /* set connection select to line in (default select for this ADC) */
3784         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3785         /* unmute Line-Out mixer amp left and right (volume = 0) */
3786         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3787         /* mute pin widget amp left and right (no gain on this amp) */
3788         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3789         /* unmute HP mixer amp left and right (volume = 0) */
3790         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3791         /* mute pin widget amp left and right (no gain on this amp) */
3792         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3793         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3794          * Line In 2 = 0x03
3795          */
3796         /* mute analog inputs */
3797         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3798         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3799         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3800         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3801         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3802         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3803         /* Unmute Front out path */
3804         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3805         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3806         /* Unmute Headphone out path */
3807         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3808         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3809         /* Unmute Mono out path */
3810         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3811         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3812         { }
3813 };
3814 #endif
3815
3816 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3817         /* Line out and output */
3818         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3819         /* mono output */
3820         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3821         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3822         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3823         /* Mic2 (front panel) pin widget for input and vref at 80% */
3824         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3825         /* Line In pin widget for input */
3826         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3827         /* Headphone pin widget for output */
3828         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3829         /* CD pin widget for input */
3830         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3831         /* unmute amp left and right */
3832         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3833         /* set connection select to line in (default select for this ADC) */
3834         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3835         /* unmute Line-Out mixer amp left and right (volume = 0) */
3836         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3837         /* mute pin widget amp left and right (no gain on this amp) */
3838         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3839         /* unmute HP mixer amp left and right (volume = 0) */
3840         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3841         /* mute pin widget amp left and right (no gain on this amp) */
3842         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3843         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3844          * Line In 2 = 0x03
3845          */
3846         /* mute analog inputs */
3847         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3848         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3849         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3850         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3851         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3852         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3853         /* Unmute Front out path */
3854         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3855         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3856         /* Unmute Headphone out path */
3857         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3858         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3859         /* Unmute Mono out path */
3860         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3861         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3862         { }
3863 };
3864
3865 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3866  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3867  * audio = 0x16, internal speaker = 0x10.
3868  */
3869 static struct hda_verb alc260_fujitsu_init_verbs[] = {
3870         /* Disable all GPIOs */
3871         {0x01, AC_VERB_SET_GPIO_MASK, 0},
3872         /* Internal speaker is connected to headphone pin */
3873         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3874         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3875         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3876         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3877         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3878         /* Ensure all other unused pins are disabled and muted. */
3879         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3880         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3881         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3882         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3883         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3884         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3885         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3886         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3887
3888         /* Disable digital (SPDIF) pins */
3889         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3890         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3891
3892         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
3893          * when acting as an output.
3894          */
3895         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3896
3897         /* Start with output sum widgets muted and their output gains at min */
3898         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3899         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3900         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3901         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3902         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3903         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3904         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3905         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3906         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3907
3908         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3909         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3910         /* Unmute Line1 pin widget output buffer since it starts as an output.
3911          * If the pin mode is changed by the user the pin mode control will
3912          * take care of enabling the pin's input/output buffers as needed.
3913          * Therefore there's no need to enable the input buffer at this
3914          * stage.
3915          */
3916         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3917         /* Unmute input buffer of pin widget used for Line-in (no equiv 
3918          * mixer ctrl)
3919          */
3920         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3921
3922         /* Mute capture amp left and right */
3923         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3924         /* Set ADC connection select to match default mixer setting - line 
3925          * in (on mic1 pin)
3926          */
3927         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3928
3929         /* Do the same for the second ADC: mute capture input amp and
3930          * set ADC connection to line in (on mic1 pin)
3931          */
3932         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3933         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3934
3935         /* Mute all inputs to mixer widget (even unconnected ones) */
3936         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3937         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3938         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3939         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3940         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3941         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3942         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3943         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3944
3945         { }
3946 };
3947
3948 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3949  * similar laptops (adapted from Fujitsu init verbs).
3950  */
3951 static struct hda_verb alc260_acer_init_verbs[] = {
3952         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3953          * the headphone jack.  Turn this on and rely on the standard mute
3954          * methods whenever the user wants to turn these outputs off.
3955          */
3956         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3957         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3958         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3959         /* Internal speaker/Headphone jack is connected to Line-out pin */
3960         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3961         /* Internal microphone/Mic jack is connected to Mic1 pin */
3962         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3963         /* Line In jack is connected to Line1 pin */
3964         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3965         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3966         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3967         /* Ensure all other unused pins are disabled and muted. */
3968         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3969         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3970         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3971         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3972         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3973         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3974         /* Disable digital (SPDIF) pins */
3975         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3976         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3977
3978         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
3979          * bus when acting as outputs.
3980          */
3981         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3982         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3983
3984         /* Start with output sum widgets muted and their output gains at min */
3985         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3986         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3987         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3988         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3989         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3990         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3991         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3992         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3993         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3994
3995         /* Unmute Line-out pin widget amp left and right
3996          * (no equiv mixer ctrl)
3997          */
3998         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3999         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4000         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4001         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4002          * inputs. If the pin mode is changed by the user the pin mode control
4003          * will take care of enabling the pin's input/output buffers as needed.
4004          * Therefore there's no need to enable the input buffer at this
4005          * stage.
4006          */
4007         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4008         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4009
4010         /* Mute capture amp left and right */
4011         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4012         /* Set ADC connection select to match default mixer setting - mic
4013          * (on mic1 pin)
4014          */
4015         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4016
4017         /* Do similar with the second ADC: mute capture input amp and
4018          * set ADC connection to mic to match ALSA's default state.
4019          */
4020         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4021         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4022
4023         /* Mute all inputs to mixer widget (even unconnected ones) */
4024         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4025         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4026         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4027         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4028         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4029         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4030         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4031         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4032
4033         { }
4034 };
4035
4036 static struct hda_verb alc260_will_verbs[] = {
4037         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4038         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4039         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4040         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4041         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4042         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4043         {}
4044 };
4045
4046 static struct hda_verb alc260_replacer_672v_verbs[] = {
4047         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4048         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4049         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4050
4051         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4052         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4053         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4054
4055         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4056         {}
4057 };
4058
4059 /* toggle speaker-output according to the hp-jack state */
4060 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4061 {
4062         unsigned int present;
4063
4064         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4065         present = snd_hda_codec_read(codec, 0x0f, 0,
4066                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4067         if (present) {
4068                 snd_hda_codec_write_cache(codec, 0x01, 0,
4069                                           AC_VERB_SET_GPIO_DATA, 1);
4070                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4071                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4072                                           PIN_HP);
4073         } else {
4074                 snd_hda_codec_write_cache(codec, 0x01, 0,
4075                                           AC_VERB_SET_GPIO_DATA, 0);
4076                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4077                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4078                                           PIN_OUT);
4079         }
4080 }
4081
4082 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4083                                        unsigned int res)
4084 {
4085         if ((res >> 26) == ALC880_HP_EVENT)
4086                 alc260_replacer_672v_automute(codec);
4087 }
4088
4089 /* Test configuration for debugging, modelled after the ALC880 test
4090  * configuration.
4091  */
4092 #ifdef CONFIG_SND_DEBUG
4093 static hda_nid_t alc260_test_dac_nids[1] = {
4094         0x02,
4095 };
4096 static hda_nid_t alc260_test_adc_nids[2] = {
4097         0x04, 0x05,
4098 };
4099 /* For testing the ALC260, each input MUX needs its own definition since
4100  * the signal assignments are different.  This assumes that the first ADC 
4101  * is NID 0x04.
4102  */
4103 static struct hda_input_mux alc260_test_capture_sources[2] = {
4104         {
4105                 .num_items = 7,
4106                 .items = {
4107                         { "MIC1 pin", 0x0 },
4108                         { "MIC2 pin", 0x1 },
4109                         { "LINE1 pin", 0x2 },
4110                         { "LINE2 pin", 0x3 },
4111                         { "CD pin", 0x4 },
4112                         { "LINE-OUT pin", 0x5 },
4113                         { "HP-OUT pin", 0x6 },
4114                 },
4115         },
4116         {
4117                 .num_items = 8,
4118                 .items = {
4119                         { "MIC1 pin", 0x0 },
4120                         { "MIC2 pin", 0x1 },
4121                         { "LINE1 pin", 0x2 },
4122                         { "LINE2 pin", 0x3 },
4123                         { "CD pin", 0x4 },
4124                         { "Mixer", 0x5 },
4125                         { "LINE-OUT pin", 0x6 },
4126                         { "HP-OUT pin", 0x7 },
4127                 },
4128         },
4129 };
4130 static struct snd_kcontrol_new alc260_test_mixer[] = {
4131         /* Output driver widgets */
4132         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4133         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4134         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4135         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4136         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4137         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4138
4139         /* Modes for retasking pin widgets
4140          * Note: the ALC260 doesn't seem to act on requests to enable mic
4141          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4142          * mention this restriction.  At this stage it's not clear whether
4143          * this behaviour is intentional or is a hardware bug in chip
4144          * revisions available at least up until early 2006.  Therefore for
4145          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4146          * choices, but if it turns out that the lack of mic bias for these
4147          * NIDs is intentional we could change their modes from
4148          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4149          */
4150         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4151         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4152         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4153         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4154         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4155         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4156
4157         /* Loopback mixer controls */
4158         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4159         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4160         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4161         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4162         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4163         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4164         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4165         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4166         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4167         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4168         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4169         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4170         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4171         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4172         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4173         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4174
4175         /* Controls for GPIO pins, assuming they are configured as outputs */
4176         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4177         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4178         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4179         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4180
4181         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4182          * is ambigious as to which NID is which; testing on laptops which
4183          * make this output available should provide clarification. 
4184          */
4185         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4186         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4187
4188         { } /* end */
4189 };
4190 static struct hda_verb alc260_test_init_verbs[] = {
4191         /* Enable all GPIOs as outputs with an initial value of 0 */
4192         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4193         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4194         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4195
4196         /* Enable retasking pins as output, initially without power amp */
4197         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4198         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4199         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4200         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4201         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4202         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4203
4204         /* Disable digital (SPDIF) pins initially, but users can enable
4205          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4206          * payload also sets the generation to 0, output to be in "consumer"
4207          * PCM format, copyright asserted, no pre-emphasis and no validity
4208          * control.
4209          */
4210         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4211         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4212
4213         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4214          * OUT1 sum bus when acting as an output.
4215          */
4216         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4217         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4218         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4219         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4220
4221         /* Start with output sum widgets muted and their output gains at min */
4222         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4223         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4224         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4225         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4226         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4227         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4228         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4229         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4230         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4231
4232         /* Unmute retasking pin widget output buffers since the default
4233          * state appears to be output.  As the pin mode is changed by the
4234          * user the pin mode control will take care of enabling the pin's
4235          * input/output buffers as needed.
4236          */
4237         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4238         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4239         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4240         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4241         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4242         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4243         /* Also unmute the mono-out pin widget */
4244         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4245
4246         /* Mute capture amp left and right */
4247         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4248         /* Set ADC connection select to match default mixer setting (mic1
4249          * pin)
4250          */
4251         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4252
4253         /* Do the same for the second ADC: mute capture input amp and
4254          * set ADC connection to mic1 pin
4255          */
4256         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4257         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4258
4259         /* Mute all inputs to mixer widget (even unconnected ones) */
4260         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4261         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4262         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4263         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4264         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4265         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4266         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4267         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4268
4269         { }
4270 };
4271 #endif
4272
4273 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4274         .substreams = 1,
4275         .channels_min = 2,
4276         .channels_max = 2,
4277 };
4278
4279 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4280         .substreams = 1,
4281         .channels_min = 2,
4282         .channels_max = 2,
4283 };
4284
4285 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4286 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4287
4288 /*
4289  * for BIOS auto-configuration
4290  */
4291
4292 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4293                                         const char *pfx)
4294 {
4295         hda_nid_t nid_vol;
4296         unsigned long vol_val, sw_val;
4297         char name[32];
4298         int err;
4299
4300         if (nid >= 0x0f && nid < 0x11) {
4301                 nid_vol = nid - 0x7;
4302                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4303                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4304         } else if (nid == 0x11) {
4305                 nid_vol = nid - 0x7;
4306                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4307                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4308         } else if (nid >= 0x12 && nid <= 0x15) {
4309                 nid_vol = 0x08;
4310                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4311                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4312         } else
4313                 return 0; /* N/A */
4314         
4315         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4316         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4317         if (err < 0)
4318                 return err;
4319         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4320         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4321         if (err < 0)
4322                 return err;
4323         return 1;
4324 }
4325
4326 /* add playback controls from the parsed DAC table */
4327 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4328                                              const struct auto_pin_cfg *cfg)
4329 {
4330         hda_nid_t nid;
4331         int err;
4332
4333         spec->multiout.num_dacs = 1;
4334         spec->multiout.dac_nids = spec->private_dac_nids;
4335         spec->multiout.dac_nids[0] = 0x02;
4336
4337         nid = cfg->line_out_pins[0];
4338         if (nid) {
4339                 err = alc260_add_playback_controls(spec, nid, "Front");
4340                 if (err < 0)
4341                         return err;
4342         }
4343
4344         nid = cfg->speaker_pins[0];
4345         if (nid) {
4346                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4347                 if (err < 0)
4348                         return err;
4349         }
4350
4351         nid = cfg->hp_pins[0];
4352         if (nid) {
4353                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4354                 if (err < 0)
4355                         return err;
4356         }
4357         return 0;
4358 }
4359
4360 /* create playback/capture controls for input pins */
4361 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4362                                                 const struct auto_pin_cfg *cfg)
4363 {
4364         struct hda_input_mux *imux = &spec->private_imux;
4365         int i, err, idx;
4366
4367         for (i = 0; i < AUTO_PIN_LAST; i++) {
4368                 if (cfg->input_pins[i] >= 0x12) {
4369                         idx = cfg->input_pins[i] - 0x12;
4370                         err = new_analog_input(spec, cfg->input_pins[i],
4371                                                auto_pin_cfg_labels[i], idx,
4372                                                0x07);
4373                         if (err < 0)
4374                                 return err;
4375                         imux->items[imux->num_items].label =
4376                                 auto_pin_cfg_labels[i];
4377                         imux->items[imux->num_items].index = idx;
4378                         imux->num_items++;
4379                 }
4380                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4381                         idx = cfg->input_pins[i] - 0x09;
4382                         err = new_analog_input(spec, cfg->input_pins[i],
4383                                                auto_pin_cfg_labels[i], idx,
4384                                                0x07);
4385                         if (err < 0)
4386                                 return err;
4387                         imux->items[imux->num_items].label =
4388                                 auto_pin_cfg_labels[i];
4389                         imux->items[imux->num_items].index = idx;
4390                         imux->num_items++;
4391                 }
4392         }
4393         return 0;
4394 }
4395
4396 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4397                                               hda_nid_t nid, int pin_type,
4398                                               int sel_idx)
4399 {
4400         /* set as output */
4401         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4402                             pin_type);
4403         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4404                             AMP_OUT_UNMUTE);
4405         /* need the manual connection? */
4406         if (nid >= 0x12) {
4407                 int idx = nid - 0x12;
4408                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4409                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4410         }
4411 }
4412
4413 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4414 {
4415         struct alc_spec *spec = codec->spec;
4416         hda_nid_t nid;
4417
4418         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4419         nid = spec->autocfg.line_out_pins[0];
4420         if (nid) {
4421                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4422                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4423         }
4424         
4425         nid = spec->autocfg.speaker_pins[0];
4426         if (nid)
4427                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4428
4429         nid = spec->autocfg.hp_pins[0];
4430         if (nid)
4431                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4432 }
4433
4434 #define ALC260_PIN_CD_NID               0x16
4435 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4436 {
4437         struct alc_spec *spec = codec->spec;
4438         int i;
4439
4440         for (i = 0; i < AUTO_PIN_LAST; i++) {
4441                 hda_nid_t nid = spec->autocfg.input_pins[i];
4442                 if (nid >= 0x12) {
4443                         snd_hda_codec_write(codec, nid, 0,
4444                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4445                                             i <= AUTO_PIN_FRONT_MIC ?
4446                                             PIN_VREF80 : PIN_IN);
4447                         if (nid != ALC260_PIN_CD_NID)
4448                                 snd_hda_codec_write(codec, nid, 0,
4449                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4450                                                     AMP_OUT_MUTE);
4451                 }
4452         }
4453 }
4454
4455 /*
4456  * generic initialization of ADC, input mixers and output mixers
4457  */
4458 static struct hda_verb alc260_volume_init_verbs[] = {
4459         /*
4460          * Unmute ADC0-1 and set the default input to mic-in
4461          */
4462         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4463         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4464         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4465         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4466         
4467         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4468          * mixer widget
4469          * Note: PASD motherboards uses the Line In 2 as the input for
4470          * front panel mic (mic 2)
4471          */
4472         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4473         /* mute analog inputs */
4474         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4475         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4476         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4477         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4478         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4479
4480         /*
4481          * Set up output mixers (0x08 - 0x0a)
4482          */
4483         /* set vol=0 to output mixers */
4484         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4485         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4486         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4487         /* set up input amps for analog loopback */
4488         /* Amp Indices: DAC = 0, mixer = 1 */
4489         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4490         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4491         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4492         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4493         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4494         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4495         
4496         { }
4497 };
4498
4499 static int alc260_parse_auto_config(struct hda_codec *codec)
4500 {
4501         struct alc_spec *spec = codec->spec;
4502         unsigned int wcap;
4503         int err;
4504         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4505
4506         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4507                                            alc260_ignore);
4508         if (err < 0)
4509                 return err;
4510         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4511         if (err < 0)
4512                 return err;
4513         if (!spec->kctl_alloc)
4514                 return 0; /* can't find valid BIOS pin config */
4515         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4516         if (err < 0)
4517                 return err;
4518
4519         spec->multiout.max_channels = 2;
4520
4521         if (spec->autocfg.dig_out_pin)
4522                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4523         if (spec->kctl_alloc)
4524                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4525
4526         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4527
4528         spec->num_mux_defs = 1;
4529         spec->input_mux = &spec->private_imux;
4530
4531         /* check whether NID 0x04 is valid */
4532         wcap = get_wcaps(codec, 0x04);
4533         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4534         if (wcap != AC_WID_AUD_IN) {
4535                 spec->adc_nids = alc260_adc_nids_alt;
4536                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4537                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4538         } else {
4539                 spec->adc_nids = alc260_adc_nids;
4540                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4541                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4542         }
4543         spec->num_mixers++;
4544
4545         return 1;
4546 }
4547
4548 /* additional initialization for auto-configuration model */
4549 static void alc260_auto_init(struct hda_codec *codec)
4550 {
4551         alc260_auto_init_multi_out(codec);
4552         alc260_auto_init_analog_input(codec);
4553 }
4554
4555 #ifdef CONFIG_SND_HDA_POWER_SAVE
4556 static struct hda_amp_list alc260_loopbacks[] = {
4557         { 0x07, HDA_INPUT, 0 },
4558         { 0x07, HDA_INPUT, 1 },
4559         { 0x07, HDA_INPUT, 2 },
4560         { 0x07, HDA_INPUT, 3 },
4561         { 0x07, HDA_INPUT, 4 },
4562         { } /* end */
4563 };
4564 #endif
4565
4566 /*
4567  * ALC260 configurations
4568  */
4569 static const char *alc260_models[ALC260_MODEL_LAST] = {
4570         [ALC260_BASIC]          = "basic",
4571         [ALC260_HP]             = "hp",
4572         [ALC260_HP_3013]        = "hp-3013",
4573         [ALC260_FUJITSU_S702X]  = "fujitsu",
4574         [ALC260_ACER]           = "acer",
4575         [ALC260_WILL]           = "will",
4576         [ALC260_REPLACER_672V]  = "replacer",
4577 #ifdef CONFIG_SND_DEBUG
4578         [ALC260_TEST]           = "test",
4579 #endif
4580         [ALC260_AUTO]           = "auto",
4581 };
4582
4583 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4584         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4585         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4586         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4587         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4588         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4589         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4590         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4591         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4592         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4593         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4594         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4595         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4596         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4597         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4598         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4599         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4600         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4601         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4602         {}
4603 };
4604
4605 static struct alc_config_preset alc260_presets[] = {
4606         [ALC260_BASIC] = {
4607                 .mixers = { alc260_base_output_mixer,
4608                             alc260_input_mixer,
4609                             alc260_pc_beep_mixer,
4610                             alc260_capture_mixer },
4611                 .init_verbs = { alc260_init_verbs },
4612                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4613                 .dac_nids = alc260_dac_nids,
4614                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4615                 .adc_nids = alc260_adc_nids,
4616                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4617                 .channel_mode = alc260_modes,
4618                 .input_mux = &alc260_capture_source,
4619         },
4620         [ALC260_HP] = {
4621                 .mixers = { alc260_base_output_mixer,
4622                             alc260_input_mixer,
4623                             alc260_capture_alt_mixer },
4624                 .init_verbs = { alc260_init_verbs },
4625                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4626                 .dac_nids = alc260_dac_nids,
4627                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4628                 .adc_nids = alc260_hp_adc_nids,
4629                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4630                 .channel_mode = alc260_modes,
4631                 .input_mux = &alc260_capture_source,
4632         },
4633         [ALC260_HP_3013] = {
4634                 .mixers = { alc260_hp_3013_mixer,
4635                             alc260_input_mixer,
4636                             alc260_capture_alt_mixer },
4637                 .init_verbs = { alc260_hp_3013_init_verbs },
4638                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4639                 .dac_nids = alc260_dac_nids,
4640                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4641                 .adc_nids = alc260_hp_adc_nids,
4642                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4643                 .channel_mode = alc260_modes,
4644                 .input_mux = &alc260_capture_source,
4645         },
4646         [ALC260_FUJITSU_S702X] = {
4647                 .mixers = { alc260_fujitsu_mixer,
4648                             alc260_capture_mixer },
4649                 .init_verbs = { alc260_fujitsu_init_verbs },
4650                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4651                 .dac_nids = alc260_dac_nids,
4652                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4653                 .adc_nids = alc260_dual_adc_nids,
4654                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4655                 .channel_mode = alc260_modes,
4656                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4657                 .input_mux = alc260_fujitsu_capture_sources,
4658         },
4659         [ALC260_ACER] = {
4660                 .mixers = { alc260_acer_mixer,
4661                             alc260_capture_mixer },
4662                 .init_verbs = { alc260_acer_init_verbs },
4663                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4664                 .dac_nids = alc260_dac_nids,
4665                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4666                 .adc_nids = alc260_dual_adc_nids,
4667                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4668                 .channel_mode = alc260_modes,
4669                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4670                 .input_mux = alc260_acer_capture_sources,
4671         },
4672         [ALC260_WILL] = {
4673                 .mixers = { alc260_will_mixer,
4674                             alc260_capture_mixer },
4675                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4676                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4677                 .dac_nids = alc260_dac_nids,
4678                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4679                 .adc_nids = alc260_adc_nids,
4680                 .dig_out_nid = ALC260_DIGOUT_NID,
4681                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4682                 .channel_mode = alc260_modes,
4683                 .input_mux = &alc260_capture_source,
4684         },
4685         [ALC260_REPLACER_672V] = {
4686                 .mixers = { alc260_replacer_672v_mixer,
4687                             alc260_capture_mixer },
4688                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4689                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4690                 .dac_nids = alc260_dac_nids,
4691                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4692                 .adc_nids = alc260_adc_nids,
4693                 .dig_out_nid = ALC260_DIGOUT_NID,
4694                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4695                 .channel_mode = alc260_modes,
4696                 .input_mux = &alc260_capture_source,
4697                 .unsol_event = alc260_replacer_672v_unsol_event,
4698                 .init_hook = alc260_replacer_672v_automute,
4699         },
4700 #ifdef CONFIG_SND_DEBUG
4701         [ALC260_TEST] = {
4702                 .mixers = { alc260_test_mixer,
4703                             alc260_capture_mixer },
4704                 .init_verbs = { alc260_test_init_verbs },
4705                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4706                 .dac_nids = alc260_test_dac_nids,
4707                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4708                 .adc_nids = alc260_test_adc_nids,
4709                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4710                 .channel_mode = alc260_modes,
4711                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4712                 .input_mux = alc260_test_capture_sources,
4713         },
4714 #endif
4715 };
4716
4717 static int patch_alc260(struct hda_codec *codec)
4718 {
4719         struct alc_spec *spec;
4720         int err, board_config;
4721
4722         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4723         if (spec == NULL)
4724                 return -ENOMEM;
4725
4726         codec->spec = spec;
4727
4728         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4729                                                   alc260_models,
4730                                                   alc260_cfg_tbl);
4731         if (board_config < 0) {
4732                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4733                            "trying auto-probe from BIOS...\n");
4734                 board_config = ALC260_AUTO;
4735         }
4736
4737         if (board_config == ALC260_AUTO) {
4738                 /* automatic parse from the BIOS config */
4739                 err = alc260_parse_auto_config(codec);
4740                 if (err < 0) {
4741                         alc_free(codec);
4742                         return err;
4743                 } else if (!err) {
4744                         printk(KERN_INFO
4745                                "hda_codec: Cannot set up configuration "
4746                                "from BIOS.  Using base mode...\n");
4747                         board_config = ALC260_BASIC;
4748                 }
4749         }
4750
4751         if (board_config != ALC260_AUTO)
4752                 setup_preset(spec, &alc260_presets[board_config]);
4753
4754         spec->stream_name_analog = "ALC260 Analog";
4755         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4756         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4757
4758         spec->stream_name_digital = "ALC260 Digital";
4759         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4760         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4761
4762         codec->patch_ops = alc_patch_ops;
4763         if (board_config == ALC260_AUTO)
4764                 spec->init_hook = alc260_auto_init;
4765 #ifdef CONFIG_SND_HDA_POWER_SAVE
4766         if (!spec->loopback.amplist)
4767                 spec->loopback.amplist = alc260_loopbacks;
4768 #endif
4769
4770         return 0;
4771 }
4772
4773
4774 /*
4775  * ALC882 support
4776  *
4777  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4778  * configuration.  Each pin widget can choose any input DACs and a mixer.
4779  * Each ADC is connected from a mixer of all inputs.  This makes possible
4780  * 6-channel independent captures.
4781  *
4782  * In addition, an independent DAC for the multi-playback (not used in this
4783  * driver yet).
4784  */
4785 #define ALC882_DIGOUT_NID       0x06
4786 #define ALC882_DIGIN_NID        0x0a
4787
4788 static struct hda_channel_mode alc882_ch_modes[1] = {
4789         { 8, NULL }
4790 };
4791
4792 static hda_nid_t alc882_dac_nids[4] = {
4793         /* front, rear, clfe, rear_surr */
4794         0x02, 0x03, 0x04, 0x05
4795 };
4796
4797 /* identical with ALC880 */
4798 #define alc882_adc_nids         alc880_adc_nids
4799 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4800
4801 /* input MUX */
4802 /* FIXME: should be a matrix-type input source selection */
4803
4804 static struct hda_input_mux alc882_capture_source = {
4805         .num_items = 4,
4806         .items = {
4807                 { "Mic", 0x0 },
4808                 { "Front Mic", 0x1 },
4809                 { "Line", 0x2 },
4810                 { "CD", 0x4 },
4811         },
4812 };
4813 #define alc882_mux_enum_info alc_mux_enum_info
4814 #define alc882_mux_enum_get alc_mux_enum_get
4815
4816 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4817                                struct snd_ctl_elem_value *ucontrol)
4818 {
4819         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4820         struct alc_spec *spec = codec->spec;
4821         const struct hda_input_mux *imux = spec->input_mux;
4822         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4823         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4824         hda_nid_t nid = capture_mixers[adc_idx];
4825         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4826         unsigned int i, idx;
4827
4828         idx = ucontrol->value.enumerated.item[0];
4829         if (idx >= imux->num_items)
4830                 idx = imux->num_items - 1;
4831         if (*cur_val == idx)
4832                 return 0;
4833         for (i = 0; i < imux->num_items; i++) {
4834                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4835                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4836                                          imux->items[i].index,
4837                                          HDA_AMP_MUTE, v);
4838         }
4839         *cur_val = idx;
4840         return 1;
4841 }
4842
4843 /*
4844  * 2ch mode
4845  */
4846 static struct hda_verb alc882_3ST_ch2_init[] = {
4847         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4848         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4849         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4850         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4851         { } /* end */
4852 };
4853
4854 /*
4855  * 6ch mode
4856  */
4857 static struct hda_verb alc882_3ST_ch6_init[] = {
4858         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4859         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4860         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4861         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4862         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4863         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4864         { } /* end */
4865 };
4866
4867 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4868         { 2, alc882_3ST_ch2_init },
4869         { 6, alc882_3ST_ch6_init },
4870 };
4871
4872 /*
4873  * 6ch mode
4874  */
4875 static struct hda_verb alc882_sixstack_ch6_init[] = {
4876         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4877         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4878         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4879         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4880         { } /* end */
4881 };
4882
4883 /*
4884  * 8ch mode
4885  */
4886 static struct hda_verb alc882_sixstack_ch8_init[] = {
4887         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4888         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4889         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4890         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4891         { } /* end */
4892 };
4893
4894 static struct hda_channel_mode alc882_sixstack_modes[2] = {
4895         { 6, alc882_sixstack_ch6_init },
4896         { 8, alc882_sixstack_ch8_init },
4897 };
4898
4899 /*
4900  * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
4901  */
4902
4903 /*
4904  * 2ch mode
4905  */
4906 static struct hda_verb alc885_mbp_ch2_init[] = {
4907         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4908         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4909         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4910         { } /* end */
4911 };
4912
4913 /*
4914  * 6ch mode
4915  */
4916 static struct hda_verb alc885_mbp_ch6_init[] = {
4917         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4918         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4919         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4920         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4921         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4922         { } /* end */
4923 };
4924
4925 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
4926         { 2, alc885_mbp_ch2_init },
4927         { 6, alc885_mbp_ch6_init },
4928 };
4929
4930
4931 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4932  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4933  */
4934 static struct snd_kcontrol_new alc882_base_mixer[] = {
4935         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4936         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4937         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4938         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4939         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4940         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4941         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4942         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4943         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4944         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4945         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4946         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4947         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4948         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4949         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4950         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4951         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4952         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4953         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4954         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4955         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4956         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4957         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4958         { } /* end */
4959 };
4960
4961 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
4962         HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
4963         HDA_BIND_MUTE   ("Master Switch", 0x0c, 0x02, HDA_INPUT),
4964         HDA_CODEC_MUTE  ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
4965         HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
4966         HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
4967         HDA_CODEC_MUTE  ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
4968         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
4969         HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
4970         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
4971         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
4972         { } /* end */
4973 };
4974 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4975         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4976         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4977         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4978         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4979         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4980         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4981         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4982         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4983         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4984         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4985         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4986         { } /* end */
4987 };
4988
4989 static struct snd_kcontrol_new alc882_targa_mixer[] = {
4990         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4991         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4992         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4993         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4994         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4995         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4996         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4997         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4998         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4999         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5000         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5001         { } /* end */
5002 };
5003
5004 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5005  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5006  */
5007 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5008         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5009         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5010         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5011         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5012         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5013         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5014         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5015         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5016         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5017         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5018         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5019         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5020         { } /* end */
5021 };
5022
5023 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5024         {
5025                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5026                 .name = "Channel Mode",
5027                 .info = alc_ch_mode_info,
5028                 .get = alc_ch_mode_get,
5029                 .put = alc_ch_mode_put,
5030         },
5031         { } /* end */
5032 };
5033
5034 static struct hda_verb alc882_init_verbs[] = {
5035         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5036         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5037         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5038         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5039         /* Rear mixer */
5040         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5041         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5042         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5043         /* CLFE mixer */
5044         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5045         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5046         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5047         /* Side mixer */
5048         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5049         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5050         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5051
5052         /* Front Pin: output 0 (0x0c) */
5053         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5054         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5055         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5056         /* Rear Pin: output 1 (0x0d) */
5057         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5058         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5059         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5060         /* CLFE Pin: output 2 (0x0e) */
5061         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5062         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5063         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5064         /* Side Pin: output 3 (0x0f) */
5065         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5066         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5067         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5068         /* Mic (rear) pin: input vref at 80% */
5069         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5070         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5071         /* Front Mic pin: input vref at 80% */
5072         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5073         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5074         /* Line In pin: input */
5075         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5076         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5077         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5078         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5079         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5080         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5081         /* CD pin widget for input */
5082         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5083
5084         /* FIXME: use matrix-type input source selection */
5085         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5086         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5087         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5088         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5089         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5090         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5091         /* Input mixer2 */
5092         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5093         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5094         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5095         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5096         /* Input mixer3 */
5097         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5098         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5099         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5100         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5101         /* ADC1: mute amp left and right */
5102         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5103         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5104         /* ADC2: mute amp left and right */
5105         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5106         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5107         /* ADC3: mute amp left and right */
5108         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5109         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5110
5111         { }
5112 };
5113
5114 static struct hda_verb alc882_eapd_verbs[] = {
5115         /* change to EAPD mode */
5116         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5117         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5118         { }
5119 };
5120
5121 /* Mac Pro test */
5122 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5123         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5124         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5125         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5126         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5127         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5128         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5129         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5130         { } /* end */
5131 };
5132
5133 static struct hda_verb alc882_macpro_init_verbs[] = {
5134         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5135         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5136         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5137         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5138         /* Front Pin: output 0 (0x0c) */
5139         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5140         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5141         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5142         /* Front Mic pin: input vref at 80% */
5143         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5144         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5145         /* Speaker:  output */
5146         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5147         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5148         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5149         /* Headphone output (output 0 - 0x0c) */
5150         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5151         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5152         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5153
5154         /* FIXME: use matrix-type input source selection */
5155         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5156         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5157         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5158         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5159         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5160         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5161         /* Input mixer2 */
5162         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5163         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5164         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5165         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5166         /* Input mixer3 */
5167         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5168         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5169         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5170         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5171         /* ADC1: mute amp left and right */
5172         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5173         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5174         /* ADC2: mute amp left and right */
5175         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5176         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5177         /* ADC3: mute amp left and right */
5178         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5179         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5180
5181         { }
5182 };
5183
5184 /* Macbook Pro rev3 */
5185 static struct hda_verb alc885_mbp3_init_verbs[] = {
5186         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5187         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5188         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5189         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5190         /* Rear mixer */
5191         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5192         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5193         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5194         /* Front Pin: output 0 (0x0c) */
5195         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5196         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5197         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5198         /* HP Pin: output 0 (0x0d) */
5199         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5200         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5201         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5202         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5203         /* Mic (rear) pin: input vref at 80% */
5204         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5205         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5206         /* Front Mic pin: input vref at 80% */
5207         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5208         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5209         /* Line In pin: use output 1 when in LineOut mode */
5210         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5211         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5212         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5213
5214         /* FIXME: use matrix-type input source selection */
5215         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5216         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5217         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5218         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5219         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5220         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5221         /* Input mixer2 */
5222         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5223         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5224         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5225         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5226         /* Input mixer3 */
5227         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5228         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5229         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5230         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5231         /* ADC1: mute amp left and right */
5232         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5233         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5234         /* ADC2: mute amp left and right */
5235         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5236         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5237         /* ADC3: mute amp left and right */
5238         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5239         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5240
5241         { }
5242 };
5243
5244 /* iMac 24 mixer. */
5245 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5246         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5247         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5248         { } /* end */
5249 };
5250
5251 /* iMac 24 init verbs. */
5252 static struct hda_verb alc885_imac24_init_verbs[] = {
5253         /* Internal speakers: output 0 (0x0c) */
5254         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5255         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5256         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5257         /* Internal speakers: output 0 (0x0c) */
5258         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5259         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5260         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5261         /* Headphone: output 0 (0x0c) */
5262         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5263         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5264         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5265         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5266         /* Front Mic: input vref at 80% */
5267         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5268         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5269         { }
5270 };
5271
5272 /* Toggle speaker-output according to the hp-jack state */
5273 static void alc885_imac24_automute(struct hda_codec *codec)
5274 {
5275         unsigned int present;
5276
5277         present = snd_hda_codec_read(codec, 0x14, 0,
5278                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5279         snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5280                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5281         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5282                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5283 }
5284
5285 /* Processes unsolicited events. */
5286 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5287                                       unsigned int res)
5288 {
5289         /* Headphone insertion or removal. */
5290         if ((res >> 26) == ALC880_HP_EVENT)
5291                 alc885_imac24_automute(codec);
5292 }
5293
5294 static void alc885_mbp3_automute(struct hda_codec *codec)
5295 {
5296         unsigned int present;
5297
5298         present = snd_hda_codec_read(codec, 0x15, 0,
5299                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5300         snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5301                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5302         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5303                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5304
5305 }
5306 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5307                                     unsigned int res)
5308 {
5309         /* Headphone insertion or removal. */
5310         if ((res >> 26) == ALC880_HP_EVENT)
5311                 alc885_mbp3_automute(codec);
5312 }
5313
5314
5315 static struct hda_verb alc882_targa_verbs[] = {
5316         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5317         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5318
5319         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5320         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5321         
5322         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5323         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5324         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5325
5326         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5327         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5328         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5329         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5330         { } /* end */
5331 };
5332
5333 /* toggle speaker-output according to the hp-jack state */
5334 static void alc882_targa_automute(struct hda_codec *codec)
5335 {
5336         unsigned int present;
5337  
5338         present = snd_hda_codec_read(codec, 0x14, 0,
5339                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5340         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5341                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5342         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5343                                   present ? 1 : 3);
5344 }
5345
5346 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5347 {
5348         /* Looks like the unsol event is incompatible with the standard
5349          * definition.  4bit tag is placed at 26 bit!
5350          */
5351         if (((res >> 26) == ALC880_HP_EVENT)) {
5352                 alc882_targa_automute(codec);
5353         }
5354 }
5355
5356 static struct hda_verb alc882_asus_a7j_verbs[] = {
5357         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5358         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5359
5360         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5361         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5362         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5363         
5364         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5365         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5366         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5367
5368         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5369         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5370         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5371         { } /* end */
5372 };
5373
5374 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5375 {
5376         unsigned int gpiostate, gpiomask, gpiodir;
5377
5378         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5379                                        AC_VERB_GET_GPIO_DATA, 0);
5380
5381         if (!muted)
5382                 gpiostate |= (1 << pin);
5383         else
5384                 gpiostate &= ~(1 << pin);
5385
5386         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5387                                       AC_VERB_GET_GPIO_MASK, 0);
5388         gpiomask |= (1 << pin);
5389
5390         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5391                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5392         gpiodir |= (1 << pin);
5393
5394
5395         snd_hda_codec_write(codec, codec->afg, 0,
5396                             AC_VERB_SET_GPIO_MASK, gpiomask);
5397         snd_hda_codec_write(codec, codec->afg, 0,
5398                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5399
5400         msleep(1);
5401
5402         snd_hda_codec_write(codec, codec->afg, 0,
5403                             AC_VERB_SET_GPIO_DATA, gpiostate);
5404 }
5405
5406 /* set up GPIO at initialization */
5407 static void alc885_macpro_init_hook(struct hda_codec *codec)
5408 {
5409         alc882_gpio_mute(codec, 0, 0);
5410         alc882_gpio_mute(codec, 1, 0);
5411 }
5412
5413 /* set up GPIO and update auto-muting at initialization */
5414 static void alc885_imac24_init_hook(struct hda_codec *codec)
5415 {
5416         alc885_macpro_init_hook(codec);
5417         alc885_imac24_automute(codec);
5418 }
5419
5420 /*
5421  * generic initialization of ADC, input mixers and output mixers
5422  */
5423 static struct hda_verb alc882_auto_init_verbs[] = {
5424         /*
5425          * Unmute ADC0-2 and set the default input to mic-in
5426          */
5427         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5428         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5429         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5430         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5431         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5432         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5433
5434         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5435          * mixer widget
5436          * Note: PASD motherboards uses the Line In 2 as the input for
5437          * front panel mic (mic 2)
5438          */
5439         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5440         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5441         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5442         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5443         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5444         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5445
5446         /*
5447          * Set up output mixers (0x0c - 0x0f)
5448          */
5449         /* set vol=0 to output mixers */
5450         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5451         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5452         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5453         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5454         /* set up input amps for analog loopback */
5455         /* Amp Indices: DAC = 0, mixer = 1 */
5456         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5457         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5458         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5459         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5460         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5461         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5462         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5463         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5464         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5465         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5466
5467         /* FIXME: use matrix-type input source selection */
5468         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5469         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5470         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5471         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5472         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5473         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5474         /* Input mixer2 */
5475         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5476         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5477         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5478         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5479         /* Input mixer3 */
5480         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5481         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5482         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5483         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5484
5485         { }
5486 };
5487
5488 /* capture mixer elements */
5489 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5490         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5491         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5492         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5493         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5494         {
5495                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5496                 /* The multiple "Capture Source" controls confuse alsamixer
5497                  * So call somewhat different..
5498                  * FIXME: the controls appear in the "playback" view!
5499                  */
5500                 /* .name = "Capture Source", */
5501                 .name = "Input Source",
5502                 .count = 2,
5503                 .info = alc882_mux_enum_info,
5504                 .get = alc882_mux_enum_get,
5505                 .put = alc882_mux_enum_put,
5506         },
5507         { } /* end */
5508 };
5509
5510 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5511         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5512         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5513         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5514         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5515         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5516         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5517         {
5518                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5519                 /* The multiple "Capture Source" controls confuse alsamixer
5520                  * So call somewhat different..
5521                  * FIXME: the controls appear in the "playback" view!
5522                  */
5523                 /* .name = "Capture Source", */
5524                 .name = "Input Source",
5525                 .count = 3,
5526                 .info = alc882_mux_enum_info,
5527                 .get = alc882_mux_enum_get,
5528                 .put = alc882_mux_enum_put,
5529         },
5530         { } /* end */
5531 };
5532
5533 #ifdef CONFIG_SND_HDA_POWER_SAVE
5534 #define alc882_loopbacks        alc880_loopbacks
5535 #endif
5536
5537 /* pcm configuration: identiacal with ALC880 */
5538 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5539 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5540 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5541 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5542
5543 /*
5544  * configuration and preset
5545  */
5546 static const char *alc882_models[ALC882_MODEL_LAST] = {
5547         [ALC882_3ST_DIG]        = "3stack-dig",
5548         [ALC882_6ST_DIG]        = "6stack-dig",
5549         [ALC882_ARIMA]          = "arima",
5550         [ALC882_W2JC]           = "w2jc",
5551         [ALC885_MACPRO]         = "macpro",
5552         [ALC885_MBP3]           = "mbp3",
5553         [ALC885_IMAC24]         = "imac24",
5554         [ALC882_AUTO]           = "auto",
5555 };
5556
5557 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5558         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5559         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5560         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5561         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5562         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5563         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5564         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5565         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5566         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5567         {}
5568 };
5569
5570 static struct alc_config_preset alc882_presets[] = {
5571         [ALC882_3ST_DIG] = {
5572                 .mixers = { alc882_base_mixer },
5573                 .init_verbs = { alc882_init_verbs },
5574                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5575                 .dac_nids = alc882_dac_nids,
5576                 .dig_out_nid = ALC882_DIGOUT_NID,
5577                 .dig_in_nid = ALC882_DIGIN_NID,
5578                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5579                 .channel_mode = alc882_ch_modes,
5580                 .need_dac_fix = 1,
5581                 .input_mux = &alc882_capture_source,
5582         },
5583         [ALC882_6ST_DIG] = {
5584                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5585                 .init_verbs = { alc882_init_verbs },
5586                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5587                 .dac_nids = alc882_dac_nids,
5588                 .dig_out_nid = ALC882_DIGOUT_NID,
5589                 .dig_in_nid = ALC882_DIGIN_NID,
5590                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5591                 .channel_mode = alc882_sixstack_modes,
5592                 .input_mux = &alc882_capture_source,
5593         },
5594         [ALC882_ARIMA] = {
5595                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5596                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5597                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5598                 .dac_nids = alc882_dac_nids,
5599                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5600                 .channel_mode = alc882_sixstack_modes,
5601                 .input_mux = &alc882_capture_source,
5602         },
5603         [ALC882_W2JC] = {
5604                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5605                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5606                                 alc880_gpio1_init_verbs },
5607                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5608                 .dac_nids = alc882_dac_nids,
5609                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5610                 .channel_mode = alc880_threestack_modes,
5611                 .need_dac_fix = 1,
5612                 .input_mux = &alc882_capture_source,
5613                 .dig_out_nid = ALC882_DIGOUT_NID,
5614         },
5615         [ALC885_MBP3] = {
5616                 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5617                 .init_verbs = { alc885_mbp3_init_verbs,
5618                                 alc880_gpio1_init_verbs },
5619                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5620                 .dac_nids = alc882_dac_nids,
5621                 .channel_mode = alc885_mbp_6ch_modes,
5622                 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5623                 .input_mux = &alc882_capture_source,
5624                 .dig_out_nid = ALC882_DIGOUT_NID,
5625                 .dig_in_nid = ALC882_DIGIN_NID,
5626                 .unsol_event = alc885_mbp3_unsol_event,
5627                 .init_hook = alc885_mbp3_automute,
5628         },
5629         [ALC885_MACPRO] = {
5630                 .mixers = { alc882_macpro_mixer },
5631                 .init_verbs = { alc882_macpro_init_verbs },
5632                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5633                 .dac_nids = alc882_dac_nids,
5634                 .dig_out_nid = ALC882_DIGOUT_NID,
5635                 .dig_in_nid = ALC882_DIGIN_NID,
5636                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5637                 .channel_mode = alc882_ch_modes,
5638                 .input_mux = &alc882_capture_source,
5639                 .init_hook = alc885_macpro_init_hook,
5640         },
5641         [ALC885_IMAC24] = {
5642                 .mixers = { alc885_imac24_mixer },
5643                 .init_verbs = { alc885_imac24_init_verbs },
5644                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5645                 .dac_nids = alc882_dac_nids,
5646                 .dig_out_nid = ALC882_DIGOUT_NID,
5647                 .dig_in_nid = ALC882_DIGIN_NID,
5648                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5649                 .channel_mode = alc882_ch_modes,
5650                 .input_mux = &alc882_capture_source,
5651                 .unsol_event = alc885_imac24_unsol_event,
5652                 .init_hook = alc885_imac24_init_hook,
5653         },
5654         [ALC882_TARGA] = {
5655                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5656                             alc882_capture_mixer },
5657                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5658                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5659                 .dac_nids = alc882_dac_nids,
5660                 .dig_out_nid = ALC882_DIGOUT_NID,
5661                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5662                 .adc_nids = alc882_adc_nids,
5663                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5664                 .channel_mode = alc882_3ST_6ch_modes,
5665                 .need_dac_fix = 1,
5666                 .input_mux = &alc882_capture_source,
5667                 .unsol_event = alc882_targa_unsol_event,
5668                 .init_hook = alc882_targa_automute,
5669         },
5670         [ALC882_ASUS_A7J] = {
5671                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5672                             alc882_capture_mixer },
5673                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5674                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5675                 .dac_nids = alc882_dac_nids,
5676                 .dig_out_nid = ALC882_DIGOUT_NID,
5677                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5678                 .adc_nids = alc882_adc_nids,
5679                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5680                 .channel_mode = alc882_3ST_6ch_modes,
5681                 .need_dac_fix = 1,
5682                 .input_mux = &alc882_capture_source,
5683         },      
5684 };
5685
5686
5687 /*
5688  * Pin config fixes
5689  */
5690 enum { 
5691         PINFIX_ABIT_AW9D_MAX
5692 };
5693
5694 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5695         { 0x15, 0x01080104 }, /* side */
5696         { 0x16, 0x01011012 }, /* rear */
5697         { 0x17, 0x01016011 }, /* clfe */
5698         { }
5699 };
5700
5701 static const struct alc_pincfg *alc882_pin_fixes[] = {
5702         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5703 };
5704
5705 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5706         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5707         {}
5708 };
5709
5710 /*
5711  * BIOS auto configuration
5712  */
5713 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5714                                               hda_nid_t nid, int pin_type,
5715                                               int dac_idx)
5716 {
5717         /* set as output */
5718         struct alc_spec *spec = codec->spec;
5719         int idx;
5720
5721         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5722                 idx = 4;
5723         else
5724                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5725
5726         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5727                             pin_type);
5728         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5729                             AMP_OUT_UNMUTE);
5730         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5731
5732 }
5733
5734 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5735 {
5736         struct alc_spec *spec = codec->spec;
5737         int i;
5738
5739         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5740         for (i = 0; i <= HDA_SIDE; i++) {
5741                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5742                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5743                 if (nid)
5744                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5745                                                           i);
5746         }
5747 }
5748
5749 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5750 {
5751         struct alc_spec *spec = codec->spec;
5752         hda_nid_t pin;
5753
5754         pin = spec->autocfg.hp_pins[0];
5755         if (pin) /* connect to front */
5756                 /* use dac 0 */
5757                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5758 }
5759
5760 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5761 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5762
5763 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5764 {
5765         struct alc_spec *spec = codec->spec;
5766         int i;
5767
5768         for (i = 0; i < AUTO_PIN_LAST; i++) {
5769                 hda_nid_t nid = spec->autocfg.input_pins[i];
5770                 if (alc882_is_input_pin(nid)) {
5771                         snd_hda_codec_write(codec, nid, 0,
5772                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5773                                             i <= AUTO_PIN_FRONT_MIC ?
5774                                             PIN_VREF80 : PIN_IN);
5775                         if (nid != ALC882_PIN_CD_NID)
5776                                 snd_hda_codec_write(codec, nid, 0,
5777                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5778                                                     AMP_OUT_MUTE);
5779                 }
5780         }
5781 }
5782
5783 /* almost identical with ALC880 parser... */
5784 static int alc882_parse_auto_config(struct hda_codec *codec)
5785 {
5786         struct alc_spec *spec = codec->spec;
5787         int err = alc880_parse_auto_config(codec);
5788
5789         if (err < 0)
5790                 return err;
5791         else if (err > 0)
5792                 /* hack - override the init verbs */
5793                 spec->init_verbs[0] = alc882_auto_init_verbs;
5794         return err;
5795 }
5796
5797 /* additional initialization for auto-configuration model */
5798 static void alc882_auto_init(struct hda_codec *codec)
5799 {
5800         alc882_auto_init_multi_out(codec);
5801         alc882_auto_init_hp_out(codec);
5802         alc882_auto_init_analog_input(codec);
5803 }
5804
5805 static int patch_alc882(struct hda_codec *codec)
5806 {
5807         struct alc_spec *spec;
5808         int err, board_config;
5809
5810         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5811         if (spec == NULL)
5812                 return -ENOMEM;
5813
5814         codec->spec = spec;
5815
5816         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5817                                                   alc882_models,
5818                                                   alc882_cfg_tbl);
5819
5820         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5821                 /* Pick up systems that don't supply PCI SSID */
5822                 switch (codec->subsystem_id) {
5823                 case 0x106b0c00: /* Mac Pro */
5824                         board_config = ALC885_MACPRO;
5825                         break;
5826                 case 0x106b1000: /* iMac 24 */
5827                         board_config = ALC885_IMAC24;
5828                         break;
5829                 case 0x106b2c00: /* Macbook Pro rev3 */
5830                         board_config = ALC885_MBP3;
5831                         break;
5832                 default:
5833                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5834                                          "trying auto-probe from BIOS...\n");
5835                         board_config = ALC882_AUTO;
5836                 }
5837         }
5838
5839         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5840
5841         if (board_config == ALC882_AUTO) {
5842                 /* automatic parse from the BIOS config */
5843                 err = alc882_parse_auto_config(codec);
5844                 if (err < 0) {
5845                         alc_free(codec);
5846                         return err;
5847                 } else if (!err) {
5848                         printk(KERN_INFO
5849                                "hda_codec: Cannot set up configuration "
5850                                "from BIOS.  Using base mode...\n");
5851                         board_config = ALC882_3ST_DIG;
5852                 }
5853         }
5854
5855         if (board_config != ALC882_AUTO)
5856                 setup_preset(spec, &alc882_presets[board_config]);
5857
5858         spec->stream_name_analog = "ALC882 Analog";
5859         spec->stream_analog_playback = &alc882_pcm_analog_playback;
5860         spec->stream_analog_capture = &alc882_pcm_analog_capture;
5861
5862         spec->stream_name_digital = "ALC882 Digital";
5863         spec->stream_digital_playback = &alc882_pcm_digital_playback;
5864         spec->stream_digital_capture = &alc882_pcm_digital_capture;
5865
5866         if (!spec->adc_nids && spec->input_mux) {
5867                 /* check whether NID 0x07 is valid */
5868                 unsigned int wcap = get_wcaps(codec, 0x07);
5869                 /* get type */
5870                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5871                 if (wcap != AC_WID_AUD_IN) {
5872                         spec->adc_nids = alc882_adc_nids_alt;
5873                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5874                         spec->mixers[spec->num_mixers] =
5875                                 alc882_capture_alt_mixer;
5876                         spec->num_mixers++;
5877                 } else {
5878                         spec->adc_nids = alc882_adc_nids;
5879                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5880                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5881                         spec->num_mixers++;
5882                 }
5883         }
5884
5885         codec->patch_ops = alc_patch_ops;
5886         if (board_config == ALC882_AUTO)
5887                 spec->init_hook = alc882_auto_init;
5888 #ifdef CONFIG_SND_HDA_POWER_SAVE
5889         if (!spec->loopback.amplist)
5890                 spec->loopback.amplist = alc882_loopbacks;
5891 #endif
5892
5893         return 0;
5894 }
5895
5896 /*
5897  * ALC883 support
5898  *
5899  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5900  * configuration.  Each pin widget can choose any input DACs and a mixer.
5901  * Each ADC is connected from a mixer of all inputs.  This makes possible
5902  * 6-channel independent captures.
5903  *
5904  * In addition, an independent DAC for the multi-playback (not used in this
5905  * driver yet).
5906  */
5907 #define ALC883_DIGOUT_NID       0x06
5908 #define ALC883_DIGIN_NID        0x0a
5909
5910 static hda_nid_t alc883_dac_nids[4] = {
5911         /* front, rear, clfe, rear_surr */
5912         0x02, 0x04, 0x03, 0x05
5913 };
5914
5915 static hda_nid_t alc883_adc_nids[2] = {
5916         /* ADC1-2 */
5917         0x08, 0x09,
5918 };
5919
5920 /* input MUX */
5921 /* FIXME: should be a matrix-type input source selection */
5922
5923 static struct hda_input_mux alc883_capture_source = {
5924         .num_items = 4,
5925         .items = {
5926                 { "Mic", 0x0 },
5927                 { "Front Mic", 0x1 },
5928                 { "Line", 0x2 },
5929                 { "CD", 0x4 },
5930         },
5931 };
5932
5933 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5934         .num_items = 2,
5935         .items = {
5936                 { "Mic", 0x1 },
5937                 { "Line", 0x2 },
5938         },
5939 };
5940
5941 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5942         .num_items = 4,
5943         .items = {
5944                 { "Mic", 0x0 },
5945                 { "iMic", 0x1 },
5946                 { "Line", 0x2 },
5947                 { "CD", 0x4 },
5948         },
5949 };
5950
5951 #define alc883_mux_enum_info alc_mux_enum_info
5952 #define alc883_mux_enum_get alc_mux_enum_get
5953
5954 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5955                                struct snd_ctl_elem_value *ucontrol)
5956 {
5957         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5958         struct alc_spec *spec = codec->spec;
5959         const struct hda_input_mux *imux = spec->input_mux;
5960         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5961         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5962         hda_nid_t nid = capture_mixers[adc_idx];
5963         unsigned int *cur_val = &spec->cur_mux[adc_idx];
5964         unsigned int i, idx;
5965
5966         idx = ucontrol->value.enumerated.item[0];
5967         if (idx >= imux->num_items)
5968                 idx = imux->num_items - 1;
5969         if (*cur_val == idx)
5970                 return 0;
5971         for (i = 0; i < imux->num_items; i++) {
5972                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5973                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5974                                          imux->items[i].index,
5975                                          HDA_AMP_MUTE, v);
5976         }
5977         *cur_val = idx;
5978         return 1;
5979 }
5980
5981 /*
5982  * 2ch mode
5983  */
5984 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5985         { 2, NULL }
5986 };
5987
5988 /*
5989  * 2ch mode
5990  */
5991 static struct hda_verb alc883_3ST_ch2_init[] = {
5992         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5993         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5994         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5995         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5996         { } /* end */
5997 };
5998
5999 /*
6000  * 6ch mode
6001  */
6002 static struct hda_verb alc883_3ST_ch6_init[] = {
6003         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6004         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6005         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6006         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6007         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6008         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6009         { } /* end */
6010 };
6011
6012 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
6013         { 2, alc883_3ST_ch2_init },
6014         { 6, alc883_3ST_ch6_init },
6015 };
6016
6017 /*
6018  * 6ch mode
6019  */
6020 static struct hda_verb alc883_sixstack_ch6_init[] = {
6021         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6022         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6023         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6024         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6025         { } /* end */
6026 };
6027
6028 /*
6029  * 8ch mode
6030  */
6031 static struct hda_verb alc883_sixstack_ch8_init[] = {
6032         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6033         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6034         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6035         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6036         { } /* end */
6037 };
6038
6039 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6040         { 6, alc883_sixstack_ch6_init },
6041         { 8, alc883_sixstack_ch8_init },
6042 };
6043
6044 static struct hda_verb alc883_medion_eapd_verbs[] = {
6045         /* eanable EAPD on medion laptop */
6046         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6047         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6048         { }
6049 };
6050
6051 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6052  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6053  */
6054
6055 static struct snd_kcontrol_new alc883_base_mixer[] = {
6056         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6057         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6058         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6059         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6060         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6061         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6062         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6063         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6064         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6065         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6066         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6067         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6068         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6069         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6070         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6071         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6072         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6073         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6074         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6075         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6076         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6077         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6078         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6079         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6080         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6081         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6082         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6083         {
6084                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6085                 /* .name = "Capture Source", */
6086                 .name = "Input Source",
6087                 .count = 2,
6088                 .info = alc883_mux_enum_info,
6089                 .get = alc883_mux_enum_get,
6090                 .put = alc883_mux_enum_put,
6091         },
6092         { } /* end */
6093 };
6094
6095 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6096         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6097         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6098         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6099         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6100         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6101         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6102         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6103         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6104         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6105         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6106         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6107         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6108         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6109         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6110         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6111         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6112         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6113         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6114         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6115         {
6116                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6117                 /* .name = "Capture Source", */
6118                 .name = "Input Source",
6119                 .count = 2,
6120                 .info = alc883_mux_enum_info,
6121                 .get = alc883_mux_enum_get,
6122                 .put = alc883_mux_enum_put,
6123         },
6124         { } /* end */
6125 };
6126
6127 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6128         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6129         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6130         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6131         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6132         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6133         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6134         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6135         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6136         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6137         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6138         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6139         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6140         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6141         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6142         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6143         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6144         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6145         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6146         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6147         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6148         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6149         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6150         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6151         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6152         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6153         {
6154                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6155                 /* .name = "Capture Source", */
6156                 .name = "Input Source",
6157                 .count = 2,
6158                 .info = alc883_mux_enum_info,
6159                 .get = alc883_mux_enum_get,
6160                 .put = alc883_mux_enum_put,
6161         },
6162         { } /* end */
6163 };
6164
6165 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6166         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6167         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6168         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6169         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6170         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6171         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6172         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6173         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6174         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6175         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6176         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6177         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6178         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6179         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6180         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6181         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6182         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6183         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6184         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6185         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6186         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6187         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6188         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6189
6190         {
6191                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6192                 /* .name = "Capture Source", */
6193                 .name = "Input Source",
6194                 .count = 1,
6195                 .info = alc883_mux_enum_info,
6196                 .get = alc883_mux_enum_get,
6197                 .put = alc883_mux_enum_put,
6198         },
6199         { } /* end */
6200 };
6201
6202 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6203         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6204         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6205         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6206         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6207         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6208         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6209         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6210         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6211         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6212         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6213         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6214         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6215         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6216         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6217         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6218         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6219         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6220         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6221         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6222         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6223         {
6224                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6225                 /* .name = "Capture Source", */
6226                 .name = "Input Source",
6227                 .count = 2,
6228                 .info = alc883_mux_enum_info,
6229                 .get = alc883_mux_enum_get,
6230                 .put = alc883_mux_enum_put,
6231         },
6232         { } /* end */
6233 };
6234
6235 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6236         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6237         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6238         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6239         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6240         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6241         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6242         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6243         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6244         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6245         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6246         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6247         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6248         {
6249                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6250                 /* .name = "Capture Source", */
6251                 .name = "Input Source",
6252                 .count = 2,
6253                 .info = alc883_mux_enum_info,
6254                 .get = alc883_mux_enum_get,
6255                 .put = alc883_mux_enum_put,
6256         },
6257         { } /* end */
6258 };
6259
6260 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6261         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6262         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6263         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6264         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6265         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6266         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6267         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6268         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6269         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6270         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6271         {
6272                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6273                 /* .name = "Capture Source", */
6274                 .name = "Input Source",
6275                 .count = 1,
6276                 .info = alc883_mux_enum_info,
6277                 .get = alc883_mux_enum_get,
6278                 .put = alc883_mux_enum_put,
6279         },
6280         { } /* end */
6281 };
6282
6283 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6284         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6285         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6286         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6287         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6288         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6289         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6290         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6291         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6292         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6293         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6294         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6295         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6296         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6297         {
6298                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6299                 /* .name = "Capture Source", */
6300                 .name = "Input Source",
6301                 .count = 2,
6302                 .info = alc883_mux_enum_info,
6303                 .get = alc883_mux_enum_get,
6304                 .put = alc883_mux_enum_put,
6305         },
6306         { } /* end */
6307 };
6308
6309 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6310         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6311         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6312         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6313         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6314         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6315         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6316         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, 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("Capture Volume", 0x08, 0x0, HDA_INPUT),
6320         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6321         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6322         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6323         {
6324                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6325                 /* .name = "Capture Source", */
6326                 .name = "Input Source",
6327                 .count = 2,
6328                 .info = alc883_mux_enum_info,
6329                 .get = alc883_mux_enum_get,
6330                 .put = alc883_mux_enum_put,
6331         },
6332         { } /* end */
6333 };      
6334
6335 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6336         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6337         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6338         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6339         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6340         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6341         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6342         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6343         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6344         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6345         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6346         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6347         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6348         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6349         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6350         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
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("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6358         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6359         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6360         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6361         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6362         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6363         {
6364                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6365                 /* .name = "Capture Source", */
6366                 .name = "Input Source",
6367                 .count = 2,
6368                 .info = alc883_mux_enum_info,
6369                 .get = alc883_mux_enum_get,
6370                 .put = alc883_mux_enum_put,
6371         },
6372         { } /* end */
6373 };
6374
6375 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6376         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6377         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6378         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6379         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6380         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6381         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6382         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6383         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6384         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6385         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6386         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6387         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6388         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6389         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6390         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6391         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6392         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6393         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6394         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6395         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6396         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6397         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6398         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6399         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6400         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6401         {
6402                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6403                 /* .name = "Capture Source", */
6404                 .name = "Input Source",
6405                 .count = 2,
6406                 .info = alc883_mux_enum_info,
6407                 .get = alc883_mux_enum_get,
6408                 .put = alc883_mux_enum_put,
6409         },
6410         { } /* end */
6411 };
6412
6413 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6414         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6415         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6416         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
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("Capture Volume", 0x08, 0x0, HDA_INPUT),
6423         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6424         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6425         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6426         {
6427                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6428                 /* .name = "Capture Source", */
6429                 .name = "Input Source",
6430                 .count = 2,
6431                 .info = alc883_mux_enum_info,
6432                 .get = alc883_mux_enum_get,
6433                 .put = alc883_mux_enum_put,
6434         },
6435         { } /* end */
6436 };
6437
6438 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6439         {
6440                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6441                 .name = "Channel Mode",
6442                 .info = alc_ch_mode_info,
6443                 .get = alc_ch_mode_get,
6444                 .put = alc_ch_mode_put,
6445         },
6446         { } /* end */
6447 };
6448
6449 static struct hda_verb alc883_init_verbs[] = {
6450         /* ADC1: mute amp left and right */
6451         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6452         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6453         /* ADC2: mute amp left and right */
6454         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6455         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6456         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6457         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6458         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6459         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6460         /* Rear mixer */
6461         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6462         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6463         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6464         /* CLFE mixer */
6465         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6466         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6467         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6468         /* Side mixer */
6469         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6470         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6471         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6472
6473         /* mute analog input loopbacks */
6474         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6475         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6476         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6477         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6478         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6479
6480         /* Front Pin: output 0 (0x0c) */
6481         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6482         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6483         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6484         /* Rear Pin: output 1 (0x0d) */
6485         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6486         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6487         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6488         /* CLFE Pin: output 2 (0x0e) */
6489         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6490         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6491         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6492         /* Side Pin: output 3 (0x0f) */
6493         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6494         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6495         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6496         /* Mic (rear) pin: input vref at 80% */
6497         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6498         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6499         /* Front Mic pin: input vref at 80% */
6500         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6501         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6502         /* Line In pin: input */
6503         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6504         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6505         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6506         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6507         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6509         /* CD pin widget for input */
6510         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6511
6512         /* FIXME: use matrix-type input source selection */
6513         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6514         /* Input mixer2 */
6515         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6516         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6517         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6518         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6519         /* Input mixer3 */
6520         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6521         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6522         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6523         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6524         { }
6525 };
6526
6527 static struct hda_verb alc883_tagra_verbs[] = {
6528         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6529         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6530
6531         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6532         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6533         
6534         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6535         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6536         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6537
6538         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6539         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6540         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6541         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6542
6543         { } /* end */
6544 };
6545
6546 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6547         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6548         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6549         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6550         { } /* end */
6551 };
6552
6553 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6554         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6555         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6556         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6557         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6558         { } /* end */
6559 };
6560
6561 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6562         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6563         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6564         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6565         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6566         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6567         { } /* end */
6568 };
6569
6570 static struct hda_verb alc888_6st_hp_verbs[] = {
6571         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6572         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6573         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6574         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6575         { }
6576 };
6577
6578 static struct hda_verb alc888_3st_hp_verbs[] = {
6579         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6580         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6581         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6582         { }
6583 };
6584
6585 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6586         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6587         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6588         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6589         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6590         { }
6591 };
6592
6593 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6594         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6595         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6596         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6597         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6598         { }
6599 };
6600
6601 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6602         { 2, alc888_3st_hp_2ch_init },
6603         { 6, alc888_3st_hp_6ch_init },
6604 };
6605
6606 /* toggle front-jack and RCA according to the hp-jack state */
6607 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6608 {
6609         unsigned int present;
6610  
6611         present = snd_hda_codec_read(codec, 0x1b, 0,
6612                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6613         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6614                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6615         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6616                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6617 }
6618
6619 /* toggle RCA according to the front-jack state */
6620 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6621 {
6622         unsigned int present;
6623  
6624         present = snd_hda_codec_read(codec, 0x14, 0,
6625                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6626         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6627                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6628 }
6629
6630 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6631                                              unsigned int res)
6632 {
6633         if ((res >> 26) == ALC880_HP_EVENT)
6634                 alc888_lenovo_ms7195_front_automute(codec);
6635         if ((res >> 26) == ALC880_FRONT_EVENT)
6636                 alc888_lenovo_ms7195_rca_automute(codec);
6637 }
6638
6639 static struct hda_verb alc883_medion_md2_verbs[] = {
6640         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6641         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6642
6643         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6644
6645         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6646         { } /* end */
6647 };
6648
6649 /* toggle speaker-output according to the hp-jack state */
6650 static void alc883_medion_md2_automute(struct hda_codec *codec)
6651 {
6652         unsigned int present;
6653  
6654         present = snd_hda_codec_read(codec, 0x14, 0,
6655                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6656         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6657                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6658 }
6659
6660 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6661                                           unsigned int res)
6662 {
6663         if ((res >> 26) == ALC880_HP_EVENT)
6664                 alc883_medion_md2_automute(codec);
6665 }
6666
6667 /* toggle speaker-output according to the hp-jack state */
6668 static void alc883_tagra_automute(struct hda_codec *codec)
6669 {
6670         unsigned int present;
6671         unsigned char bits;
6672
6673         present = snd_hda_codec_read(codec, 0x14, 0,
6674                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6675         bits = present ? HDA_AMP_MUTE : 0;
6676         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6677                                  HDA_AMP_MUTE, bits);
6678         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6679                                   present ? 1 : 3);
6680 }
6681
6682 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6683 {
6684         if ((res >> 26) == ALC880_HP_EVENT)
6685                 alc883_tagra_automute(codec);
6686 }
6687
6688 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6689 {
6690         unsigned int present;
6691         unsigned char bits;
6692
6693         present = snd_hda_codec_read(codec, 0x14, 0,
6694                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6695         bits = present ? HDA_AMP_MUTE : 0;
6696         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6697                                  HDA_AMP_MUTE, bits);
6698 }
6699
6700 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6701 {
6702         unsigned int present;
6703         unsigned char bits;
6704
6705         present = snd_hda_codec_read(codec, 0x1b, 0,
6706                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6707         bits = present ? HDA_AMP_MUTE : 0;
6708         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6709                                  HDA_AMP_MUTE, bits);
6710         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6711                                  HDA_AMP_MUTE, bits);
6712 }
6713
6714 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6715                                            unsigned int res)
6716 {
6717         if ((res >> 26) == ALC880_HP_EVENT)
6718                 alc883_lenovo_101e_all_automute(codec);
6719         if ((res >> 26) == ALC880_FRONT_EVENT)
6720                 alc883_lenovo_101e_ispeaker_automute(codec);
6721 }
6722
6723 /* toggle speaker-output according to the hp-jack state */
6724 static void alc883_acer_aspire_automute(struct hda_codec *codec)
6725 {
6726         unsigned int present;
6727  
6728         present = snd_hda_codec_read(codec, 0x14, 0,
6729                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6730         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6731                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6732         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
6733                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6734 }
6735
6736 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
6737                                            unsigned int res)
6738 {
6739         if ((res >> 26) == ALC880_HP_EVENT)
6740                 alc883_acer_aspire_automute(codec);
6741 }
6742
6743 static struct hda_verb alc883_acer_eapd_verbs[] = {
6744         /* HP Pin: output 0 (0x0c) */
6745         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6746         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6747         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6748         /* Front Pin: output 0 (0x0c) */
6749         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6750         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6751         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6752         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
6753         /* eanable EAPD on medion laptop */
6754         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6755         {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
6756         /* enable unsolicited event */
6757         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6758         { }
6759 };
6760
6761 /*
6762  * generic initialization of ADC, input mixers and output mixers
6763  */
6764 static struct hda_verb alc883_auto_init_verbs[] = {
6765         /*
6766          * Unmute ADC0-2 and set the default input to mic-in
6767          */
6768         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6769         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6770         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6771         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772
6773         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6774          * mixer widget
6775          * Note: PASD motherboards uses the Line In 2 as the input for
6776          * front panel mic (mic 2)
6777          */
6778         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6779         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6780         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6781         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6782         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6783         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6784
6785         /*
6786          * Set up output mixers (0x0c - 0x0f)
6787          */
6788         /* set vol=0 to output mixers */
6789         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6790         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6791         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6792         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6793         /* set up input amps for analog loopback */
6794         /* Amp Indices: DAC = 0, mixer = 1 */
6795         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6796         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6797         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6798         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6799         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6800         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6801         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6802         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6803         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6804         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6805
6806         /* FIXME: use matrix-type input source selection */
6807         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6808         /* Input mixer1 */
6809         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6810         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6811         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6812         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6813         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6814         /* Input mixer2 */
6815         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6816         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6817         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6818         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6819         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6820
6821         { }
6822 };
6823
6824 /* capture mixer elements */
6825 static struct snd_kcontrol_new alc883_capture_mixer[] = {
6826         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6827         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6828         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6829         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6830         {
6831                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6832                 /* The multiple "Capture Source" controls confuse alsamixer
6833                  * So call somewhat different..
6834                  * FIXME: the controls appear in the "playback" view!
6835                  */
6836                 /* .name = "Capture Source", */
6837                 .name = "Input Source",
6838                 .count = 2,
6839                 .info = alc882_mux_enum_info,
6840                 .get = alc882_mux_enum_get,
6841                 .put = alc882_mux_enum_put,
6842         },
6843         { } /* end */
6844 };
6845
6846 #ifdef CONFIG_SND_HDA_POWER_SAVE
6847 #define alc883_loopbacks        alc880_loopbacks
6848 #endif
6849
6850 /* pcm configuration: identiacal with ALC880 */
6851 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
6852 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
6853 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
6854 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
6855
6856 /*
6857  * configuration and preset
6858  */
6859 static const char *alc883_models[ALC883_MODEL_LAST] = {
6860         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
6861         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
6862         [ALC883_3ST_6ch]        = "3stack-6ch",
6863         [ALC883_6ST_DIG]        = "6stack-dig",
6864         [ALC883_TARGA_DIG]      = "targa-dig",
6865         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
6866         [ALC883_ACER]           = "acer",
6867         [ALC883_ACER_ASPIRE]    = "acer-aspire",
6868         [ALC883_MEDION]         = "medion",
6869         [ALC883_MEDION_MD2]     = "medion-md2",
6870         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
6871         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6872         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
6873         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6874         [ALC888_6ST_HP]         = "6stack-hp",
6875         [ALC888_3ST_HP]         = "3stack-hp",
6876         [ALC883_AUTO]           = "auto",
6877 };
6878
6879 static struct snd_pci_quirk alc883_cfg_tbl[] = {
6880         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6881         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6882         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6883         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6884         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6885         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6886         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6887         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6888         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6889         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6890         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6891         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6892         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6893         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6894         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6895         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6896         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6897         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6898         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6899         SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
6900         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6901         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6902         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6903         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6904         SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
6905         SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
6906         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6907         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6908         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6909         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6910         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6911         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6912         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6913         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6914         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6915         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6916         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6917         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6918         {}
6919 };
6920
6921 static struct alc_config_preset alc883_presets[] = {
6922         [ALC883_3ST_2ch_DIG] = {
6923                 .mixers = { alc883_3ST_2ch_mixer },
6924                 .init_verbs = { alc883_init_verbs },
6925                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6926                 .dac_nids = alc883_dac_nids,
6927                 .dig_out_nid = ALC883_DIGOUT_NID,
6928                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6929                 .adc_nids = alc883_adc_nids,
6930                 .dig_in_nid = ALC883_DIGIN_NID,
6931                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6932                 .channel_mode = alc883_3ST_2ch_modes,
6933                 .input_mux = &alc883_capture_source,
6934         },
6935         [ALC883_3ST_6ch_DIG] = {
6936                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6937                 .init_verbs = { alc883_init_verbs },
6938                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6939                 .dac_nids = alc883_dac_nids,
6940                 .dig_out_nid = ALC883_DIGOUT_NID,
6941                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6942                 .adc_nids = alc883_adc_nids,
6943                 .dig_in_nid = ALC883_DIGIN_NID,
6944                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6945                 .channel_mode = alc883_3ST_6ch_modes,
6946                 .need_dac_fix = 1,
6947                 .input_mux = &alc883_capture_source,
6948         },
6949         [ALC883_3ST_6ch] = {
6950                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6951                 .init_verbs = { alc883_init_verbs },
6952                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6953                 .dac_nids = alc883_dac_nids,
6954                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6955                 .adc_nids = alc883_adc_nids,
6956                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6957                 .channel_mode = alc883_3ST_6ch_modes,
6958                 .need_dac_fix = 1,
6959                 .input_mux = &alc883_capture_source,
6960         },
6961         [ALC883_6ST_DIG] = {
6962                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
6963                 .init_verbs = { alc883_init_verbs },
6964                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6965                 .dac_nids = alc883_dac_nids,
6966                 .dig_out_nid = ALC883_DIGOUT_NID,
6967                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6968                 .adc_nids = alc883_adc_nids,
6969                 .dig_in_nid = ALC883_DIGIN_NID,
6970                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6971                 .channel_mode = alc883_sixstack_modes,
6972                 .input_mux = &alc883_capture_source,
6973         },
6974         [ALC883_TARGA_DIG] = {
6975                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6976                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6977                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6978                 .dac_nids = alc883_dac_nids,
6979                 .dig_out_nid = ALC883_DIGOUT_NID,
6980                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6981                 .adc_nids = alc883_adc_nids,
6982                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6983                 .channel_mode = alc883_3ST_6ch_modes,
6984                 .need_dac_fix = 1,
6985                 .input_mux = &alc883_capture_source,
6986                 .unsol_event = alc883_tagra_unsol_event,
6987                 .init_hook = alc883_tagra_automute,
6988         },
6989         [ALC883_TARGA_2ch_DIG] = {
6990                 .mixers = { alc883_tagra_2ch_mixer},
6991                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6992                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6993                 .dac_nids = alc883_dac_nids,
6994                 .dig_out_nid = ALC883_DIGOUT_NID,
6995                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6996                 .adc_nids = alc883_adc_nids,
6997                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6998                 .channel_mode = alc883_3ST_2ch_modes,
6999                 .input_mux = &alc883_capture_source,
7000                 .unsol_event = alc883_tagra_unsol_event,
7001                 .init_hook = alc883_tagra_automute,
7002         },
7003         [ALC883_ACER] = {
7004                 .mixers = { alc883_base_mixer },
7005                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7006                  * and the headphone jack.  Turn this on and rely on the
7007                  * standard mute methods whenever the user wants to turn
7008                  * these outputs off.
7009                  */
7010                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7011                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7012                 .dac_nids = alc883_dac_nids,
7013                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7014                 .adc_nids = alc883_adc_nids,
7015                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7016                 .channel_mode = alc883_3ST_2ch_modes,
7017                 .input_mux = &alc883_capture_source,
7018         },
7019         [ALC883_ACER_ASPIRE] = {
7020                 .mixers = { alc883_acer_aspire_mixer },
7021                 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7022                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7023                 .dac_nids = alc883_dac_nids,
7024                 .dig_out_nid = ALC883_DIGOUT_NID,
7025                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7026                 .adc_nids = alc883_adc_nids,
7027                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7028                 .channel_mode = alc883_3ST_2ch_modes,
7029                 .input_mux = &alc883_capture_source,
7030                 .unsol_event = alc883_acer_aspire_unsol_event,
7031                 .init_hook = alc883_acer_aspire_automute,
7032         },
7033         [ALC883_MEDION] = {
7034                 .mixers = { alc883_fivestack_mixer,
7035                             alc883_chmode_mixer },
7036                 .init_verbs = { alc883_init_verbs,
7037                                 alc883_medion_eapd_verbs },
7038                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7039                 .dac_nids = alc883_dac_nids,
7040                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7041                 .adc_nids = alc883_adc_nids,
7042                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7043                 .channel_mode = alc883_sixstack_modes,
7044                 .input_mux = &alc883_capture_source,
7045         },
7046         [ALC883_MEDION_MD2] = {
7047                 .mixers = { alc883_medion_md2_mixer},
7048                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7049                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7050                 .dac_nids = alc883_dac_nids,
7051                 .dig_out_nid = ALC883_DIGOUT_NID,
7052                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7053                 .adc_nids = alc883_adc_nids,
7054                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7055                 .channel_mode = alc883_3ST_2ch_modes,
7056                 .input_mux = &alc883_capture_source,
7057                 .unsol_event = alc883_medion_md2_unsol_event,
7058                 .init_hook = alc883_medion_md2_automute,
7059         },      
7060         [ALC883_LAPTOP_EAPD] = {
7061                 .mixers = { alc883_base_mixer },
7062                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7063                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7064                 .dac_nids = alc883_dac_nids,
7065                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7066                 .adc_nids = alc883_adc_nids,
7067                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7068                 .channel_mode = alc883_3ST_2ch_modes,
7069                 .input_mux = &alc883_capture_source,
7070         },
7071         [ALC883_LENOVO_101E_2ch] = {
7072                 .mixers = { alc883_lenovo_101e_2ch_mixer},
7073                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7074                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7075                 .dac_nids = alc883_dac_nids,
7076                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7077                 .adc_nids = alc883_adc_nids,
7078                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7079                 .channel_mode = alc883_3ST_2ch_modes,
7080                 .input_mux = &alc883_lenovo_101e_capture_source,
7081                 .unsol_event = alc883_lenovo_101e_unsol_event,
7082                 .init_hook = alc883_lenovo_101e_all_automute,
7083         },
7084         [ALC883_LENOVO_NB0763] = {
7085                 .mixers = { alc883_lenovo_nb0763_mixer },
7086                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7087                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7088                 .dac_nids = alc883_dac_nids,
7089                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7090                 .adc_nids = alc883_adc_nids,
7091                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7092                 .channel_mode = alc883_3ST_2ch_modes,
7093                 .need_dac_fix = 1,
7094                 .input_mux = &alc883_lenovo_nb0763_capture_source,
7095                 .unsol_event = alc883_medion_md2_unsol_event,
7096                 .init_hook = alc883_medion_md2_automute,
7097         },
7098         [ALC888_LENOVO_MS7195_DIG] = {
7099                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7100                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7101                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7102                 .dac_nids = alc883_dac_nids,
7103                 .dig_out_nid = ALC883_DIGOUT_NID,
7104                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7105                 .adc_nids = alc883_adc_nids,
7106                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7107                 .channel_mode = alc883_3ST_6ch_modes,
7108                 .need_dac_fix = 1,
7109                 .input_mux = &alc883_capture_source,
7110                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7111                 .init_hook = alc888_lenovo_ms7195_front_automute,
7112         },      
7113         [ALC888_6ST_HP] = {
7114                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7115                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7116                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7117                 .dac_nids = alc883_dac_nids,
7118                 .dig_out_nid = ALC883_DIGOUT_NID,
7119                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7120                 .adc_nids = alc883_adc_nids,
7121                 .dig_in_nid = ALC883_DIGIN_NID,
7122                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7123                 .channel_mode = alc883_sixstack_modes,
7124                 .input_mux = &alc883_capture_source,
7125         },
7126         [ALC888_3ST_HP] = {
7127                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7128                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7129                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7130                 .dac_nids = alc883_dac_nids,
7131                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7132                 .adc_nids = alc883_adc_nids,
7133                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7134                 .channel_mode = alc888_3st_hp_modes,
7135                 .need_dac_fix = 1,
7136                 .input_mux = &alc883_capture_source,
7137         },
7138 };
7139
7140
7141 /*
7142  * BIOS auto configuration
7143  */
7144 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7145                                               hda_nid_t nid, int pin_type,
7146                                               int dac_idx)
7147 {
7148         /* set as output */
7149         struct alc_spec *spec = codec->spec;
7150         int idx;
7151
7152         if (spec->multiout.dac_nids[dac_idx] == 0x25)
7153                 idx = 4;
7154         else
7155                 idx = spec->multiout.dac_nids[dac_idx] - 2;
7156
7157         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7158                             pin_type);
7159         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7160                             AMP_OUT_UNMUTE);
7161         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7162
7163 }
7164
7165 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7166 {
7167         struct alc_spec *spec = codec->spec;
7168         int i;
7169
7170         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7171         for (i = 0; i <= HDA_SIDE; i++) {
7172                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7173                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7174                 if (nid)
7175                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7176                                                           i);
7177         }
7178 }
7179
7180 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7181 {
7182         struct alc_spec *spec = codec->spec;
7183         hda_nid_t pin;
7184
7185         pin = spec->autocfg.hp_pins[0];
7186         if (pin) /* connect to front */
7187                 /* use dac 0 */
7188                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7189 }
7190
7191 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
7192 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
7193
7194 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7195 {
7196         struct alc_spec *spec = codec->spec;
7197         int i;
7198
7199         for (i = 0; i < AUTO_PIN_LAST; i++) {
7200                 hda_nid_t nid = spec->autocfg.input_pins[i];
7201                 if (alc883_is_input_pin(nid)) {
7202                         snd_hda_codec_write(codec, nid, 0,
7203                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
7204                                             (i <= AUTO_PIN_FRONT_MIC ?
7205                                              PIN_VREF80 : PIN_IN));
7206                         if (nid != ALC883_PIN_CD_NID)
7207                                 snd_hda_codec_write(codec, nid, 0,
7208                                                     AC_VERB_SET_AMP_GAIN_MUTE,
7209                                                     AMP_OUT_MUTE);
7210                 }
7211         }
7212 }
7213
7214 /* almost identical with ALC880 parser... */
7215 static int alc883_parse_auto_config(struct hda_codec *codec)
7216 {
7217         struct alc_spec *spec = codec->spec;
7218         int err = alc880_parse_auto_config(codec);
7219
7220         if (err < 0)
7221                 return err;
7222         else if (err > 0)
7223                 /* hack - override the init verbs */
7224                 spec->init_verbs[0] = alc883_auto_init_verbs;
7225         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7226         spec->num_mixers++;
7227         return err;
7228 }
7229
7230 /* additional initialization for auto-configuration model */
7231 static void alc883_auto_init(struct hda_codec *codec)
7232 {
7233         alc883_auto_init_multi_out(codec);
7234         alc883_auto_init_hp_out(codec);
7235         alc883_auto_init_analog_input(codec);
7236 }
7237
7238 static int patch_alc883(struct hda_codec *codec)
7239 {
7240         struct alc_spec *spec;
7241         int err, board_config;
7242
7243         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7244         if (spec == NULL)
7245                 return -ENOMEM;
7246
7247         codec->spec = spec;
7248
7249         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7250                                                   alc883_models,
7251                                                   alc883_cfg_tbl);
7252         if (board_config < 0) {
7253                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7254                        "trying auto-probe from BIOS...\n");
7255                 board_config = ALC883_AUTO;
7256         }
7257
7258         if (board_config == ALC883_AUTO) {
7259                 /* automatic parse from the BIOS config */
7260                 err = alc883_parse_auto_config(codec);
7261                 if (err < 0) {
7262                         alc_free(codec);
7263                         return err;
7264                 } else if (!err) {
7265                         printk(KERN_INFO
7266                                "hda_codec: Cannot set up configuration "
7267                                "from BIOS.  Using base mode...\n");
7268                         board_config = ALC883_3ST_2ch_DIG;
7269                 }
7270         }
7271
7272         if (board_config != ALC883_AUTO)
7273                 setup_preset(spec, &alc883_presets[board_config]);
7274
7275         spec->stream_name_analog = "ALC883 Analog";
7276         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7277         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7278
7279         spec->stream_name_digital = "ALC883 Digital";
7280         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7281         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7282
7283         if (!spec->adc_nids && spec->input_mux) {
7284                 spec->adc_nids = alc883_adc_nids;
7285                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7286         }
7287
7288         codec->patch_ops = alc_patch_ops;
7289         if (board_config == ALC883_AUTO)
7290                 spec->init_hook = alc883_auto_init;
7291 #ifdef CONFIG_SND_HDA_POWER_SAVE
7292         if (!spec->loopback.amplist)
7293                 spec->loopback.amplist = alc883_loopbacks;
7294 #endif
7295
7296         return 0;
7297 }
7298
7299 /*
7300  * ALC262 support
7301  */
7302
7303 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7304 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7305
7306 #define alc262_dac_nids         alc260_dac_nids
7307 #define alc262_adc_nids         alc882_adc_nids
7308 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7309
7310 #define alc262_modes            alc260_modes
7311 #define alc262_capture_source   alc882_capture_source
7312
7313 static struct snd_kcontrol_new alc262_base_mixer[] = {
7314         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7315         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7316         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7317         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7318         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7319         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7320         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7321         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7322         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7323         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7324         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7325         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7326         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7327            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7328         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7329         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7330         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7331         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7332         { } /* end */
7333 };
7334
7335 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7336         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7337         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7338         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7339         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7340         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7341         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7342         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7343         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7344         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7345         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7346         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7347         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7348         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7349            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7350         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7351         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7352         { } /* end */
7353 };
7354
7355 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7356         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7357         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7358         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7359         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7360         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7361
7362         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7363         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7364         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7365         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7366         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7367         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7368         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7369         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7370         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7371         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7372         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7373         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7374         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7375         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7376         { } /* end */
7377 };
7378
7379 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7380         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7381         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7382         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7383         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7384         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7385         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7386         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7387         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7388         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7389         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7390         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7391         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7392         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7393         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7394         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7395         { } /* end */
7396 };
7397
7398 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7399         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7400         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7401         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7402         { } /* end */
7403 };
7404
7405 static struct hda_bind_ctls alc262_sony_bind_sw = {
7406         .ops = &snd_hda_bind_sw,
7407         .values = {
7408                 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7409                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7410                 0,
7411         },
7412 };
7413
7414 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7415         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7416         HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw),
7417         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7418         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7419         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7420         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7421         { } /* end */
7422 };
7423
7424 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7425         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7426         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7427         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7428         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7429         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7430         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7431         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7432         { } /* end */
7433 };
7434
7435 #define alc262_capture_mixer            alc882_capture_mixer
7436 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7437
7438 /*
7439  * generic initialization of ADC, input mixers and output mixers
7440  */
7441 static struct hda_verb alc262_init_verbs[] = {
7442         /*
7443          * Unmute ADC0-2 and set the default input to mic-in
7444          */
7445         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7446         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7447         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7448         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7449         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7450         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7451
7452         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7453          * mixer widget
7454          * Note: PASD motherboards uses the Line In 2 as the input for
7455          * front panel mic (mic 2)
7456          */
7457         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7458         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7459         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7460         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7461         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7462         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7463
7464         /*
7465          * Set up output mixers (0x0c - 0x0e)
7466          */
7467         /* set vol=0 to output mixers */
7468         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7469         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7470         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7471         /* set up input amps for analog loopback */
7472         /* Amp Indices: DAC = 0, mixer = 1 */
7473         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7474         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7475         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7476         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7477         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7478         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7479
7480         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7481         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7482         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7483         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7484         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7485         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7486
7487         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7488         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7489         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7490         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7491         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7492         
7493         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7494         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7495         
7496         /* FIXME: use matrix-type input source selection */
7497         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7498         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7499         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7500         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7501         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7502         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7503         /* Input mixer2 */
7504         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7505         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7506         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7507         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7508         /* Input mixer3 */
7509         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7510         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7511         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7512         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7513
7514         { }
7515 };
7516
7517 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7518         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7519         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7520         {}
7521 };
7522
7523 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7524         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7525         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7526         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7527
7528         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7529         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7530         {}
7531 };
7532
7533 static struct hda_verb alc262_sony_unsol_verbs[] = {
7534         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7535         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7536         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7537
7538         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7539         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7540 };
7541
7542 /* mute/unmute internal speaker according to the hp jack and mute state */
7543 static void alc262_hippo_automute(struct hda_codec *codec)
7544 {
7545         struct alc_spec *spec = codec->spec;
7546         unsigned int mute;
7547         unsigned int present;
7548
7549         /* need to execute and sync at first */
7550         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7551         present = snd_hda_codec_read(codec, 0x15, 0,
7552                                      AC_VERB_GET_PIN_SENSE, 0);
7553         spec->jack_present = (present & 0x80000000) != 0;
7554         if (spec->jack_present) {
7555                 /* mute internal speaker */
7556                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7557                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7558         } else {
7559                 /* unmute internal speaker if necessary */
7560                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7561                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7562                                          HDA_AMP_MUTE, mute);
7563         }
7564 }
7565
7566 /* unsolicited event for HP jack sensing */
7567 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7568                                        unsigned int res)
7569 {
7570         if ((res >> 26) != ALC880_HP_EVENT)
7571                 return;
7572         alc262_hippo_automute(codec);
7573 }
7574
7575 static void alc262_hippo1_automute(struct hda_codec *codec)
7576 {
7577         unsigned int mute;
7578         unsigned int present;
7579
7580         snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7581         present = snd_hda_codec_read(codec, 0x1b, 0,
7582                                      AC_VERB_GET_PIN_SENSE, 0);
7583         present = (present & 0x80000000) != 0;
7584         if (present) {
7585                 /* mute internal speaker */
7586                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7587                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7588         } else {
7589                 /* unmute internal speaker if necessary */
7590                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7591                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7592                                          HDA_AMP_MUTE, mute);
7593         }
7594 }
7595
7596 /* unsolicited event for HP jack sensing */
7597 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7598                                        unsigned int res)
7599 {
7600         if ((res >> 26) != ALC880_HP_EVENT)
7601                 return;
7602         alc262_hippo1_automute(codec);
7603 }
7604
7605 /*
7606  * fujitsu model
7607  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7608  */
7609
7610 #define ALC_HP_EVENT    0x37
7611
7612 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7613         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7614         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7615         {}
7616 };
7617
7618 static struct hda_input_mux alc262_fujitsu_capture_source = {
7619         .num_items = 2,
7620         .items = {
7621                 { "Mic", 0x0 },
7622                 { "CD", 0x4 },
7623         },
7624 };
7625
7626 static struct hda_input_mux alc262_HP_capture_source = {
7627         .num_items = 5,
7628         .items = {
7629                 { "Mic", 0x0 },
7630                 { "Front Mic", 0x3 },
7631                 { "Line", 0x2 },
7632                 { "CD", 0x4 },
7633                 { "AUX IN", 0x6 },
7634         },
7635 };
7636
7637 /* mute/unmute internal speaker according to the hp jack and mute state */
7638 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7639 {
7640         struct alc_spec *spec = codec->spec;
7641         unsigned int mute;
7642
7643         if (force || !spec->sense_updated) {
7644                 unsigned int present;
7645                 /* need to execute and sync at first */
7646                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7647                 present = snd_hda_codec_read(codec, 0x14, 0,
7648                                          AC_VERB_GET_PIN_SENSE, 0);
7649                 spec->jack_present = (present & 0x80000000) != 0;
7650                 spec->sense_updated = 1;
7651         }
7652         if (spec->jack_present) {
7653                 /* mute internal speaker */
7654                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7655                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7656         } else {
7657                 /* unmute internal speaker if necessary */
7658                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7659                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7660                                          HDA_AMP_MUTE, mute);
7661         }
7662 }
7663
7664 /* unsolicited event for HP jack sensing */
7665 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7666                                        unsigned int res)
7667 {
7668         if ((res >> 26) != ALC_HP_EVENT)
7669                 return;
7670         alc262_fujitsu_automute(codec, 1);
7671 }
7672
7673 /* bind volumes of both NID 0x0c and 0x0d */
7674 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
7675         .ops = &snd_hda_bind_vol,
7676         .values = {
7677                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7678                 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7679                 0
7680         },
7681 };
7682
7683 /* bind hp and internal speaker mute (with plug check) */
7684 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7685                                          struct snd_ctl_elem_value *ucontrol)
7686 {
7687         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7688         long *valp = ucontrol->value.integer.value;
7689         int change;
7690
7691         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7692                                           HDA_AMP_MUTE,
7693                                           valp[0] ? 0 : HDA_AMP_MUTE);
7694         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7695                                            HDA_AMP_MUTE,
7696                                            valp[1] ? 0 : HDA_AMP_MUTE);
7697         if (change)
7698                 alc262_fujitsu_automute(codec, 0);
7699         return change;
7700 }
7701
7702 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7703         HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
7704         {
7705                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7706                 .name = "Master Playback Switch",
7707                 .info = snd_hda_mixer_amp_switch_info,
7708                 .get = snd_hda_mixer_amp_switch_get,
7709                 .put = alc262_fujitsu_master_sw_put,
7710                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7711         },
7712         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7713         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7714         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7715         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7716         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7717         { } /* end */
7718 };
7719
7720 /* additional init verbs for Benq laptops */
7721 static struct hda_verb alc262_EAPD_verbs[] = {
7722         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7723         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7724         {}
7725 };
7726
7727 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7728         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7729         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7730
7731         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7732         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7733         {}
7734 };
7735
7736 /* add playback controls from the parsed DAC table */
7737 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7738                                              const struct auto_pin_cfg *cfg)
7739 {
7740         hda_nid_t nid;
7741         int err;
7742
7743         spec->multiout.num_dacs = 1;    /* only use one dac */
7744         spec->multiout.dac_nids = spec->private_dac_nids;
7745         spec->multiout.dac_nids[0] = 2;
7746
7747         nid = cfg->line_out_pins[0];
7748         if (nid) {
7749                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7750                                   "Front Playback Volume",
7751                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7752                 if (err < 0)
7753                         return err;
7754                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7755                                   "Front Playback Switch",
7756                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7757                 if (err < 0)
7758                         return err;
7759         }
7760
7761         nid = cfg->speaker_pins[0];
7762         if (nid) {
7763                 if (nid == 0x16) {
7764                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7765                                           "Speaker Playback Volume",
7766                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7767                                                               HDA_OUTPUT));
7768                         if (err < 0)
7769                                 return err;
7770                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7771                                           "Speaker Playback Switch",
7772                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7773                                                               HDA_OUTPUT));
7774                         if (err < 0)
7775                                 return err;
7776                 } else {
7777                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7778                                           "Speaker Playback Switch",
7779                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7780                                                               HDA_OUTPUT));
7781                         if (err < 0)
7782                                 return err;
7783                 }
7784         }
7785         nid = cfg->hp_pins[0];
7786         if (nid) {
7787                 /* spec->multiout.hp_nid = 2; */
7788                 if (nid == 0x16) {
7789                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7790                                           "Headphone Playback Volume",
7791                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7792                                                               HDA_OUTPUT));
7793                         if (err < 0)
7794                                 return err;
7795                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7796                                           "Headphone Playback Switch",
7797                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7798                                                               HDA_OUTPUT));
7799                         if (err < 0)
7800                                 return err;
7801                 } else {
7802                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7803                                           "Headphone Playback Switch",
7804                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7805                                                               HDA_OUTPUT));
7806                         if (err < 0)
7807                                 return err;
7808                 }
7809         }
7810         return 0;
7811 }
7812
7813 /* identical with ALC880 */
7814 #define alc262_auto_create_analog_input_ctls \
7815         alc880_auto_create_analog_input_ctls
7816
7817 /*
7818  * generic initialization of ADC, input mixers and output mixers
7819  */
7820 static struct hda_verb alc262_volume_init_verbs[] = {
7821         /*
7822          * Unmute ADC0-2 and set the default input to mic-in
7823          */
7824         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7825         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7826         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7827         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7828         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7829         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7830
7831         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7832          * mixer widget
7833          * Note: PASD motherboards uses the Line In 2 as the input for
7834          * front panel mic (mic 2)
7835          */
7836         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7837         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7838         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7839         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7840         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7841         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7842
7843         /*
7844          * Set up output mixers (0x0c - 0x0f)
7845          */
7846         /* set vol=0 to output mixers */
7847         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7848         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7849         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7850         
7851         /* set up input amps for analog loopback */
7852         /* Amp Indices: DAC = 0, mixer = 1 */
7853         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7854         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7855         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7856         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7857         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7858         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7859
7860         /* FIXME: use matrix-type input source selection */
7861         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7862         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7863         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7864         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7865         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7866         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7867         /* Input mixer2 */
7868         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7869         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7870         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7871         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7872         /* Input mixer3 */
7873         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7874         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7875         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7876         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7877
7878         { }
7879 };
7880
7881 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7882         /*
7883          * Unmute ADC0-2 and set the default input to mic-in
7884          */
7885         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7886         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7887         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7888         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7889         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7890         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7891
7892         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7893          * mixer widget
7894          * Note: PASD motherboards uses the Line In 2 as the input for
7895          * front panel mic (mic 2)
7896          */
7897         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7898         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7899         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7900         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7901         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7902         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7903         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7904         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7905         
7906         /*
7907          * Set up output mixers (0x0c - 0x0e)
7908          */
7909         /* set vol=0 to output mixers */
7910         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7911         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7912         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7913
7914         /* set up input amps for analog loopback */
7915         /* Amp Indices: DAC = 0, mixer = 1 */
7916         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7917         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7918         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7919         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7920         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7921         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7922
7923         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7924         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7925         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7926
7927         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7928         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7929
7930         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7931         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7932
7933         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7934         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7935         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7936         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7937         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7938
7939         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7940         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7941         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7942         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7943         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7944         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7945
7946
7947         /* FIXME: use matrix-type input source selection */
7948         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7949         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7950         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7951         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7952         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7953         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7954         /* Input mixer2 */
7955         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7956         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7957         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7958         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7959         /* Input mixer3 */
7960         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7961         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7962         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7963         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7964
7965         { }
7966 };
7967
7968 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7969         /*
7970          * Unmute ADC0-2 and set the default input to mic-in
7971          */
7972         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7973         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7974         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7975         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7976         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7977         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7978
7979         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7980          * mixer widget
7981          * Note: PASD motherboards uses the Line In 2 as the input for front
7982          * panel mic (mic 2)
7983          */
7984         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7985         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7986         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7987         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7988         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7989         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7990         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7991         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7992         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
7993         /*
7994          * Set up output mixers (0x0c - 0x0e)
7995          */
7996         /* set vol=0 to output mixers */
7997         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7998         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7999         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8000
8001         /* set up input amps for analog loopback */
8002         /* Amp Indices: DAC = 0, mixer = 1 */
8003         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8004         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8005         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8006         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8007         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8008         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8009
8010
8011         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
8012         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
8013         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
8014         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
8015         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
8016         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
8017         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
8018
8019         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8020         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8021
8022         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8023         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8024
8025         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8026         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8027         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8028         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8029         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8030         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8031
8032         /* FIXME: use matrix-type input source selection */
8033         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8034         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8035         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8036         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8037         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8038         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8039         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8040         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
8041         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8042         /* Input mixer2 */
8043         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8044         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8045         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8046         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8047         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8048         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8049         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8050         /* Input mixer3 */
8051         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8052         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8053         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8054         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8055         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8056         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8057         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8058
8059         { }
8060 };
8061
8062 #ifdef CONFIG_SND_HDA_POWER_SAVE
8063 #define alc262_loopbacks        alc880_loopbacks
8064 #endif
8065
8066 /* pcm configuration: identiacal with ALC880 */
8067 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
8068 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
8069 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
8070 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
8071
8072 /*
8073  * BIOS auto configuration
8074  */
8075 static int alc262_parse_auto_config(struct hda_codec *codec)
8076 {
8077         struct alc_spec *spec = codec->spec;
8078         int err;
8079         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8080
8081         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8082                                            alc262_ignore);
8083         if (err < 0)
8084                 return err;
8085         if (!spec->autocfg.line_outs)
8086                 return 0; /* can't find valid BIOS pin config */
8087         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8088         if (err < 0)
8089                 return err;
8090         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8091         if (err < 0)
8092                 return err;
8093
8094         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8095
8096         if (spec->autocfg.dig_out_pin)
8097                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8098         if (spec->autocfg.dig_in_pin)
8099                 spec->dig_in_nid = ALC262_DIGIN_NID;
8100
8101         if (spec->kctl_alloc)
8102                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8103
8104         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8105         spec->num_mux_defs = 1;
8106         spec->input_mux = &spec->private_imux;
8107
8108         return 1;
8109 }
8110
8111 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
8112 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
8113 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
8114
8115
8116 /* init callback for auto-configuration model -- overriding the default init */
8117 static void alc262_auto_init(struct hda_codec *codec)
8118 {
8119         alc262_auto_init_multi_out(codec);
8120         alc262_auto_init_hp_out(codec);
8121         alc262_auto_init_analog_input(codec);
8122 }
8123
8124 /*
8125  * configuration and preset
8126  */
8127 static const char *alc262_models[ALC262_MODEL_LAST] = {
8128         [ALC262_BASIC]          = "basic",
8129         [ALC262_HIPPO]          = "hippo",
8130         [ALC262_HIPPO_1]        = "hippo_1",
8131         [ALC262_FUJITSU]        = "fujitsu",
8132         [ALC262_HP_BPC]         = "hp-bpc",
8133         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8134         [ALC262_BENQ_ED8]       = "benq",
8135         [ALC262_BENQ_T31]       = "benq-t31",
8136         [ALC262_SONY_ASSAMD]    = "sony-assamd",
8137         [ALC262_AUTO]           = "auto",
8138 };
8139
8140 static struct snd_pci_quirk alc262_cfg_tbl[] = {
8141         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8142         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8143         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8144         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8145         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8146         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8147         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8148         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8149         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8150         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8151         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8152         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8153         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8154         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8155         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8156         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8157         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8158         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8159         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8160         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8161         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8162         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8163         SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8164         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8165         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8166         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8167         {}
8168 };
8169
8170 static struct alc_config_preset alc262_presets[] = {
8171         [ALC262_BASIC] = {
8172                 .mixers = { alc262_base_mixer },
8173                 .init_verbs = { alc262_init_verbs },
8174                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8175                 .dac_nids = alc262_dac_nids,
8176                 .hp_nid = 0x03,
8177                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8178                 .channel_mode = alc262_modes,
8179                 .input_mux = &alc262_capture_source,
8180         },
8181         [ALC262_HIPPO] = {
8182                 .mixers = { alc262_base_mixer },
8183                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8184                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8185                 .dac_nids = alc262_dac_nids,
8186                 .hp_nid = 0x03,
8187                 .dig_out_nid = ALC262_DIGOUT_NID,
8188                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8189                 .channel_mode = alc262_modes,
8190                 .input_mux = &alc262_capture_source,
8191                 .unsol_event = alc262_hippo_unsol_event,
8192                 .init_hook = alc262_hippo_automute,
8193         },
8194         [ALC262_HIPPO_1] = {
8195                 .mixers = { alc262_hippo1_mixer },
8196                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8197                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8198                 .dac_nids = alc262_dac_nids,
8199                 .hp_nid = 0x02,
8200                 .dig_out_nid = ALC262_DIGOUT_NID,
8201                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8202                 .channel_mode = alc262_modes,
8203                 .input_mux = &alc262_capture_source,
8204                 .unsol_event = alc262_hippo1_unsol_event,
8205                 .init_hook = alc262_hippo1_automute,
8206         },
8207         [ALC262_FUJITSU] = {
8208                 .mixers = { alc262_fujitsu_mixer },
8209                 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
8210                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8211                 .dac_nids = alc262_dac_nids,
8212                 .hp_nid = 0x03,
8213                 .dig_out_nid = ALC262_DIGOUT_NID,
8214                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8215                 .channel_mode = alc262_modes,
8216                 .input_mux = &alc262_fujitsu_capture_source,
8217                 .unsol_event = alc262_fujitsu_unsol_event,
8218         },
8219         [ALC262_HP_BPC] = {
8220                 .mixers = { alc262_HP_BPC_mixer },
8221                 .init_verbs = { alc262_HP_BPC_init_verbs },
8222                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8223                 .dac_nids = alc262_dac_nids,
8224                 .hp_nid = 0x03,
8225                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8226                 .channel_mode = alc262_modes,
8227                 .input_mux = &alc262_HP_capture_source,
8228         },
8229         [ALC262_HP_BPC_D7000_WF] = {
8230                 .mixers = { alc262_HP_BPC_WildWest_mixer },
8231                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8232                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8233                 .dac_nids = alc262_dac_nids,
8234                 .hp_nid = 0x03,
8235                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8236                 .channel_mode = alc262_modes,
8237                 .input_mux = &alc262_HP_capture_source,
8238         },
8239         [ALC262_HP_BPC_D7000_WL] = {
8240                 .mixers = { alc262_HP_BPC_WildWest_mixer,
8241                             alc262_HP_BPC_WildWest_option_mixer },
8242                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8243                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8244                 .dac_nids = alc262_dac_nids,
8245                 .hp_nid = 0x03,
8246                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8247                 .channel_mode = alc262_modes,
8248                 .input_mux = &alc262_HP_capture_source,
8249         },
8250         [ALC262_BENQ_ED8] = {
8251                 .mixers = { alc262_base_mixer },
8252                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8253                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8254                 .dac_nids = alc262_dac_nids,
8255                 .hp_nid = 0x03,
8256                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8257                 .channel_mode = alc262_modes,
8258                 .input_mux = &alc262_capture_source,
8259         },
8260         [ALC262_SONY_ASSAMD] = {
8261                 .mixers = { alc262_sony_mixer },
8262                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8263                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8264                 .dac_nids = alc262_dac_nids,
8265                 .hp_nid = 0x02,
8266                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8267                 .channel_mode = alc262_modes,
8268                 .input_mux = &alc262_capture_source,
8269                 .unsol_event = alc262_hippo_unsol_event,
8270                 .init_hook = alc262_hippo_automute,
8271         },
8272         [ALC262_BENQ_T31] = {
8273                 .mixers = { alc262_benq_t31_mixer },
8274                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8275                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8276                 .dac_nids = alc262_dac_nids,
8277                 .hp_nid = 0x03,
8278                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8279                 .channel_mode = alc262_modes,
8280                 .input_mux = &alc262_capture_source,
8281                 .unsol_event = alc262_hippo_unsol_event,
8282                 .init_hook = alc262_hippo_automute,
8283         },      
8284 };
8285
8286 static int patch_alc262(struct hda_codec *codec)
8287 {
8288         struct alc_spec *spec;
8289         int board_config;
8290         int err;
8291
8292         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8293         if (spec == NULL)
8294                 return -ENOMEM;
8295
8296         codec->spec = spec;
8297 #if 0
8298         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8299          * under-run
8300          */
8301         {
8302         int tmp;
8303         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8304         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8305         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8306         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8307         }
8308 #endif
8309
8310         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8311                                                   alc262_models,
8312                                                   alc262_cfg_tbl);
8313
8314         if (board_config < 0) {
8315                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8316                        "trying auto-probe from BIOS...\n");
8317                 board_config = ALC262_AUTO;
8318         }
8319
8320         if (board_config == ALC262_AUTO) {
8321                 /* automatic parse from the BIOS config */
8322                 err = alc262_parse_auto_config(codec);
8323                 if (err < 0) {
8324                         alc_free(codec);
8325                         return err;
8326                 } else if (!err) {
8327                         printk(KERN_INFO
8328                                "hda_codec: Cannot set up configuration "
8329                                "from BIOS.  Using base mode...\n");
8330                         board_config = ALC262_BASIC;
8331                 }
8332         }
8333
8334         if (board_config != ALC262_AUTO)
8335                 setup_preset(spec, &alc262_presets[board_config]);
8336
8337         spec->stream_name_analog = "ALC262 Analog";
8338         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8339         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8340                 
8341         spec->stream_name_digital = "ALC262 Digital";
8342         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8343         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8344
8345         if (!spec->adc_nids && spec->input_mux) {
8346                 /* check whether NID 0x07 is valid */
8347                 unsigned int wcap = get_wcaps(codec, 0x07);
8348
8349                 /* get type */
8350                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8351                 if (wcap != AC_WID_AUD_IN) {
8352                         spec->adc_nids = alc262_adc_nids_alt;
8353                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8354                         spec->mixers[spec->num_mixers] =
8355                                 alc262_capture_alt_mixer;
8356                         spec->num_mixers++;
8357                 } else {
8358                         spec->adc_nids = alc262_adc_nids;
8359                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8360                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8361                         spec->num_mixers++;
8362                 }
8363         }
8364
8365         codec->patch_ops = alc_patch_ops;
8366         if (board_config == ALC262_AUTO)
8367                 spec->init_hook = alc262_auto_init;
8368 #ifdef CONFIG_SND_HDA_POWER_SAVE
8369         if (!spec->loopback.amplist)
8370                 spec->loopback.amplist = alc262_loopbacks;
8371 #endif
8372                 
8373         return 0;
8374 }
8375
8376 /*
8377  *  ALC268 channel source setting (2 channel)
8378  */
8379 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8380 #define alc268_modes            alc260_modes
8381         
8382 static hda_nid_t alc268_dac_nids[2] = {
8383         /* front, hp */
8384         0x02, 0x03
8385 };
8386
8387 static hda_nid_t alc268_adc_nids[2] = {
8388         /* ADC0-1 */
8389         0x08, 0x07
8390 };
8391
8392 static hda_nid_t alc268_adc_nids_alt[1] = {
8393         /* ADC0 */
8394         0x08
8395 };
8396
8397 static struct snd_kcontrol_new alc268_base_mixer[] = {
8398         /* output mixer control */
8399         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8400         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8401         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8402         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8403         { }
8404 };
8405
8406 static struct hda_verb alc268_eapd_verbs[] = {
8407         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8408         {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8409         { }
8410 };
8411
8412 /* Toshiba specific */
8413 #define alc268_toshiba_automute alc262_hippo_automute
8414
8415 static struct hda_verb alc268_toshiba_verbs[] = {
8416         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8417         { } /* end */
8418 };
8419
8420 /* Acer specific */
8421 /* bind volumes of both NID 0x0c and 0x0d */
8422 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
8423         .ops = &snd_hda_bind_vol,
8424         .values = {
8425                 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
8426                 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
8427                 0
8428         },
8429 };
8430
8431 #define alc268_acer_master_sw_put       alc262_fujitsu_master_sw_put
8432 #define alc268_acer_automute    alc262_fujitsu_automute
8433
8434 static struct snd_kcontrol_new alc268_acer_mixer[] = {
8435         /* output mixer control */
8436         HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
8437         {
8438                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8439                 .name = "Master Playback Switch",
8440                 .info = snd_hda_mixer_amp_switch_info,
8441                 .get = snd_hda_mixer_amp_switch_get,
8442                 .put = alc268_acer_master_sw_put,
8443                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8444         },
8445         { }
8446 };
8447
8448 static struct hda_verb alc268_acer_verbs[] = {
8449         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8450         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8451
8452         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8453         { }
8454 };
8455
8456 /* unsolicited event for HP jack sensing */
8457 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
8458                                        unsigned int res)
8459 {
8460         if ((res >> 28) != ALC880_HP_EVENT)
8461                 return;
8462         alc268_toshiba_automute(codec);
8463 }
8464
8465 static void alc268_acer_unsol_event(struct hda_codec *codec,
8466                                        unsigned int res)
8467 {
8468         if ((res >> 28) != ALC880_HP_EVENT)
8469                 return;
8470         alc268_acer_automute(codec, 1);
8471 }
8472
8473 /*
8474  * generic initialization of ADC, input mixers and output mixers
8475  */
8476 static struct hda_verb alc268_base_init_verbs[] = {
8477         /* Unmute DAC0-1 and set vol = 0 */
8478         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8479         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8481         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8482         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8483         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8484
8485         /*
8486          * Set up output mixers (0x0c - 0x0e)
8487          */
8488         /* set vol=0 to output mixers */
8489         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8490         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8491         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8492         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8493
8494         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8495         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8496
8497         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8498         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8499         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8500         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8501         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8502         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8503         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8504         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8505
8506         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8507         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8508         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8509         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8510         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8511         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8512         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8513         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8514
8515         /* FIXME: use matrix-type input source selection */
8516         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8517         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8518         /* Input mixer2 */
8519         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8520         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8521         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8522         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8523
8524         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8525         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8526         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8527         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8528         { }
8529 };
8530
8531 /*
8532  * generic initialization of ADC, input mixers and output mixers
8533  */
8534 static struct hda_verb alc268_volume_init_verbs[] = {
8535         /* set output DAC */
8536         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8537         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8538         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8539         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8540
8541         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8542         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8543         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8544         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8545         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8546
8547         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8548         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8549         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8550         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8551         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8552
8553         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8554         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8555         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8556         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8557
8558         /* set PCBEEP vol = 0 */
8559         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8560
8561         { }
8562 };
8563
8564 #define alc268_mux_enum_info alc_mux_enum_info
8565 #define alc268_mux_enum_get alc_mux_enum_get
8566
8567 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8568                                struct snd_ctl_elem_value *ucontrol)
8569 {
8570         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8571         struct alc_spec *spec = codec->spec;
8572         const struct hda_input_mux *imux = spec->input_mux;
8573         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8574         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8575         hda_nid_t nid = capture_mixers[adc_idx];
8576         unsigned int *cur_val = &spec->cur_mux[adc_idx];
8577         unsigned int i, idx;
8578
8579         idx = ucontrol->value.enumerated.item[0];
8580         if (idx >= imux->num_items)
8581                 idx = imux->num_items - 1;
8582         if (*cur_val == idx)
8583                 return 0;
8584         for (i = 0; i < imux->num_items; i++) {
8585                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
8586                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
8587                                          imux->items[i].index,
8588                                          HDA_AMP_MUTE, v);
8589                 snd_hda_codec_write_cache(codec, nid, 0,
8590                                           AC_VERB_SET_CONNECT_SEL,
8591                                           idx );
8592         }
8593         *cur_val = idx;
8594         return 1;
8595 }
8596
8597 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8598         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8599         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8600         {
8601                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8602                 /* The multiple "Capture Source" controls confuse alsamixer
8603                  * So call somewhat different..
8604                  * FIXME: the controls appear in the "playback" view!
8605                  */
8606                 /* .name = "Capture Source", */
8607                 .name = "Input Source",
8608                 .count = 1,
8609                 .info = alc268_mux_enum_info,
8610                 .get = alc268_mux_enum_get,
8611                 .put = alc268_mux_enum_put,
8612         },
8613         { } /* end */
8614 };
8615
8616 static struct snd_kcontrol_new alc268_capture_mixer[] = {
8617         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8618         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8619         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8620         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8621         {
8622                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8623                 /* The multiple "Capture Source" controls confuse alsamixer
8624                  * So call somewhat different..
8625                  * FIXME: the controls appear in the "playback" view!
8626                  */
8627                 /* .name = "Capture Source", */
8628                 .name = "Input Source",
8629                 .count = 2,
8630                 .info = alc268_mux_enum_info,
8631                 .get = alc268_mux_enum_get,
8632                 .put = alc268_mux_enum_put,
8633         },
8634         { } /* end */
8635 };
8636
8637 static struct hda_input_mux alc268_capture_source = {
8638         .num_items = 4,
8639         .items = {
8640                 { "Mic", 0x0 },
8641                 { "Front Mic", 0x1 },
8642                 { "Line", 0x2 },
8643                 { "CD", 0x3 },
8644         },
8645 };
8646
8647 /* create input playback/capture controls for the given pin */
8648 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8649                                     const char *ctlname, int idx)
8650 {
8651         char name[32];
8652         int err;
8653
8654         sprintf(name, "%s Playback Volume", ctlname);
8655         if (nid == 0x14) {
8656                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8657                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8658                                                       HDA_OUTPUT));
8659                 if (err < 0)
8660                         return err;
8661         } else if (nid == 0x15) {
8662                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8663                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8664                                                       HDA_OUTPUT));
8665                 if (err < 0)
8666                         return err;
8667         } else
8668                 return -1;
8669         sprintf(name, "%s Playback Switch", ctlname);
8670         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8671                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8672         if (err < 0)
8673                 return err;
8674         return 0;
8675 }
8676
8677 /* add playback controls from the parsed DAC table */
8678 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8679                                              const struct auto_pin_cfg *cfg)
8680 {
8681         hda_nid_t nid;
8682         int err;
8683
8684         spec->multiout.num_dacs = 2;    /* only use one dac */
8685         spec->multiout.dac_nids = spec->private_dac_nids;
8686         spec->multiout.dac_nids[0] = 2;
8687         spec->multiout.dac_nids[1] = 3;
8688
8689         nid = cfg->line_out_pins[0];
8690         if (nid)
8691                 alc268_new_analog_output(spec, nid, "Front", 0);        
8692
8693         nid = cfg->speaker_pins[0];
8694         if (nid == 0x1d) {
8695                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8696                                   "Speaker Playback Volume",
8697                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8698                 if (err < 0)
8699                         return err;
8700         }
8701         nid = cfg->hp_pins[0];
8702         if (nid)
8703                 alc268_new_analog_output(spec, nid, "Headphone", 0);
8704
8705         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8706         if (nid == 0x16) {
8707                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8708                                   "Mono Playback Switch",
8709                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8710                 if (err < 0)
8711                         return err;
8712         }
8713         return 0;       
8714 }
8715
8716 /* create playback/capture controls for input pins */
8717 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8718                                                 const struct auto_pin_cfg *cfg)
8719 {
8720         struct hda_input_mux *imux = &spec->private_imux;
8721         int i, idx1;
8722
8723         for (i = 0; i < AUTO_PIN_LAST; i++) {
8724                 switch(cfg->input_pins[i]) {
8725                 case 0x18:
8726                         idx1 = 0;       /* Mic 1 */
8727                         break;
8728                 case 0x19:
8729                         idx1 = 1;       /* Mic 2 */
8730                         break;
8731                 case 0x1a:
8732                         idx1 = 2;       /* Line In */
8733                         break;
8734                 case 0x1c:      
8735                         idx1 = 3;       /* CD */
8736                         break;
8737                 default:
8738                         continue;
8739                 }
8740                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8741                 imux->items[imux->num_items].index = idx1;
8742                 imux->num_items++;      
8743         }
8744         return 0;
8745 }
8746
8747 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8748 {
8749         struct alc_spec *spec = codec->spec;
8750         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8751         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8752         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8753         unsigned int    dac_vol1, dac_vol2;
8754
8755         if (speaker_nid) {
8756                 snd_hda_codec_write(codec, speaker_nid, 0,
8757                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8758                 snd_hda_codec_write(codec, 0x0f, 0,
8759                                     AC_VERB_SET_AMP_GAIN_MUTE,
8760                                     AMP_IN_UNMUTE(1));
8761                 snd_hda_codec_write(codec, 0x10, 0,
8762                                     AC_VERB_SET_AMP_GAIN_MUTE,
8763                                     AMP_IN_UNMUTE(1));
8764         } else {
8765                 snd_hda_codec_write(codec, 0x0f, 0,
8766                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8767                 snd_hda_codec_write(codec, 0x10, 0,
8768                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8769         }
8770
8771         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
8772         if (line_nid == 0x14)   
8773                 dac_vol2 = AMP_OUT_ZERO;
8774         else if (line_nid == 0x15)
8775                 dac_vol1 = AMP_OUT_ZERO;
8776         if (hp_nid == 0x14)     
8777                 dac_vol2 = AMP_OUT_ZERO;
8778         else if (hp_nid == 0x15)
8779                 dac_vol1 = AMP_OUT_ZERO;
8780         if (line_nid != 0x16 || hp_nid != 0x16 ||
8781             spec->autocfg.line_out_pins[1] != 0x16 ||
8782             spec->autocfg.line_out_pins[2] != 0x16)
8783                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8784
8785         snd_hda_codec_write(codec, 0x02, 0,
8786                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8787         snd_hda_codec_write(codec, 0x03, 0,
8788                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8789 }
8790
8791 /* pcm configuration: identiacal with ALC880 */
8792 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
8793 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
8794 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
8795
8796 /*
8797  * BIOS auto configuration
8798  */
8799 static int alc268_parse_auto_config(struct hda_codec *codec)
8800 {
8801         struct alc_spec *spec = codec->spec;
8802         int err;
8803         static hda_nid_t alc268_ignore[] = { 0 };
8804
8805         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8806                                            alc268_ignore);
8807         if (err < 0)
8808                 return err;
8809         if (!spec->autocfg.line_outs)
8810                 return 0; /* can't find valid BIOS pin config */
8811
8812         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8813         if (err < 0)
8814                 return err;
8815         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8816         if (err < 0)
8817                 return err;
8818
8819         spec->multiout.max_channels = 2;
8820
8821         /* digital only support output */
8822         if (spec->autocfg.dig_out_pin)
8823                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8824
8825         if (spec->kctl_alloc)
8826                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8827
8828         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8829         spec->num_mux_defs = 1;
8830         spec->input_mux = &spec->private_imux;
8831
8832         return 1;
8833 }
8834
8835 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
8836 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
8837 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
8838
8839 /* init callback for auto-configuration model -- overriding the default init */
8840 static void alc268_auto_init(struct hda_codec *codec)
8841 {
8842         alc268_auto_init_multi_out(codec);
8843         alc268_auto_init_hp_out(codec);
8844         alc268_auto_init_mono_speaker_out(codec);
8845         alc268_auto_init_analog_input(codec);
8846 }
8847
8848 /*
8849  * configuration and preset
8850  */
8851 static const char *alc268_models[ALC268_MODEL_LAST] = {
8852         [ALC268_3ST]            = "3stack",
8853         [ALC268_TOSHIBA]        = "toshiba",
8854         [ALC268_ACER]           = "acer",
8855         [ALC268_AUTO]           = "auto",
8856 };
8857
8858 static struct snd_pci_quirk alc268_cfg_tbl[] = {
8859         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8860         SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8861         SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
8862         SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
8863         {}
8864 };
8865
8866 static struct alc_config_preset alc268_presets[] = {
8867         [ALC268_3ST] = {
8868                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8869                 .init_verbs = { alc268_base_init_verbs },
8870                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8871                 .dac_nids = alc268_dac_nids,
8872                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8873                 .adc_nids = alc268_adc_nids_alt,
8874                 .hp_nid = 0x03,
8875                 .dig_out_nid = ALC268_DIGOUT_NID,
8876                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8877                 .channel_mode = alc268_modes,
8878                 .input_mux = &alc268_capture_source,
8879         },
8880         [ALC268_TOSHIBA] = {
8881                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8882                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
8883                                 alc268_toshiba_verbs },
8884                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8885                 .dac_nids = alc268_dac_nids,
8886                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8887                 .adc_nids = alc268_adc_nids_alt,
8888                 .hp_nid = 0x03,
8889                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8890                 .channel_mode = alc268_modes,
8891                 .input_mux = &alc268_capture_source,
8892                 .input_mux = &alc268_capture_source,
8893                 .unsol_event = alc268_toshiba_unsol_event,
8894                 .init_hook = alc268_toshiba_automute,
8895         },
8896         [ALC268_ACER] = {
8897                 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
8898                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
8899                                 alc268_acer_verbs },
8900                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8901                 .dac_nids = alc268_dac_nids,
8902                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8903                 .adc_nids = alc268_adc_nids_alt,
8904                 .hp_nid = 0x02,
8905                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8906                 .channel_mode = alc268_modes,
8907                 .input_mux = &alc268_capture_source,
8908                 .unsol_event = alc268_acer_unsol_event,
8909         },
8910 };
8911
8912 static int patch_alc268(struct hda_codec *codec)
8913 {
8914         struct alc_spec *spec;
8915         int board_config;
8916         int err;
8917
8918         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8919         if (spec == NULL)
8920                 return -ENOMEM;
8921
8922         codec->spec = spec;
8923
8924         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8925                                                   alc268_models,
8926                                                   alc268_cfg_tbl);
8927
8928         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8929                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8930                        "trying auto-probe from BIOS...\n");
8931                 board_config = ALC268_AUTO;
8932         }
8933
8934         if (board_config == ALC268_AUTO) {
8935                 /* automatic parse from the BIOS config */
8936                 err = alc268_parse_auto_config(codec);
8937                 if (err < 0) {
8938                         alc_free(codec);
8939                         return err;
8940                 } else if (!err) {
8941                         printk(KERN_INFO
8942                                "hda_codec: Cannot set up configuration "
8943                                "from BIOS.  Using base mode...\n");
8944                         board_config = ALC268_3ST;
8945                 }
8946         }
8947
8948         if (board_config != ALC268_AUTO)
8949                 setup_preset(spec, &alc268_presets[board_config]);
8950
8951         spec->stream_name_analog = "ALC268 Analog";
8952         spec->stream_analog_playback = &alc268_pcm_analog_playback;
8953         spec->stream_analog_capture = &alc268_pcm_analog_capture;
8954
8955         spec->stream_name_digital = "ALC268 Digital";
8956         spec->stream_digital_playback = &alc268_pcm_digital_playback;
8957
8958         if (board_config == ALC268_AUTO) {
8959                 if (!spec->adc_nids && spec->input_mux) {
8960                         /* check whether NID 0x07 is valid */
8961                         unsigned int wcap = get_wcaps(codec, 0x07);
8962
8963                         /* get type */
8964                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8965                         if (wcap != AC_WID_AUD_IN) {
8966                                 spec->adc_nids = alc268_adc_nids_alt;
8967                                 spec->num_adc_nids =
8968                                         ARRAY_SIZE(alc268_adc_nids_alt);
8969                                 spec->mixers[spec->num_mixers] =
8970                                         alc268_capture_alt_mixer;
8971                                 spec->num_mixers++;
8972                         } else {
8973                                 spec->adc_nids = alc268_adc_nids;
8974                                 spec->num_adc_nids =
8975                                         ARRAY_SIZE(alc268_adc_nids);
8976                                 spec->mixers[spec->num_mixers] =
8977                                         alc268_capture_mixer;
8978                                 spec->num_mixers++;
8979                         }
8980                 }
8981         }
8982         codec->patch_ops = alc_patch_ops;
8983         if (board_config == ALC268_AUTO)
8984                 spec->init_hook = alc268_auto_init;
8985                 
8986         return 0;
8987 }
8988
8989 /*
8990  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8991  */
8992
8993 /*
8994  * set the path ways for 2 channel output
8995  * need to set the codec line out and mic 1 pin widgets to inputs
8996  */
8997 static struct hda_verb alc861_threestack_ch2_init[] = {
8998         /* set pin widget 1Ah (line in) for input */
8999         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9000         /* set pin widget 18h (mic1/2) for input, for mic also enable
9001          * the vref
9002          */
9003         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9004
9005         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9006 #if 0
9007         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9008         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9009 #endif
9010         { } /* end */
9011 };
9012 /*
9013  * 6ch mode
9014  * need to set the codec line out and mic 1 pin widgets to outputs
9015  */
9016 static struct hda_verb alc861_threestack_ch6_init[] = {
9017         /* set pin widget 1Ah (line in) for output (Back Surround)*/
9018         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9019         /* set pin widget 18h (mic1) for output (CLFE)*/
9020         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9021
9022         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9023         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9024
9025         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9026 #if 0
9027         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9028         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9029 #endif
9030         { } /* end */
9031 };
9032
9033 static struct hda_channel_mode alc861_threestack_modes[2] = {
9034         { 2, alc861_threestack_ch2_init },
9035         { 6, alc861_threestack_ch6_init },
9036 };
9037 /* Set mic1 as input and unmute the mixer */
9038 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
9039         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9040         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9041         { } /* end */
9042 };
9043 /* Set mic1 as output and mute mixer */
9044 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
9045         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9046         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9047         { } /* end */
9048 };
9049
9050 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
9051         { 2, alc861_uniwill_m31_ch2_init },
9052         { 4, alc861_uniwill_m31_ch4_init },
9053 };
9054
9055 /* Set mic1 and line-in as input and unmute the mixer */
9056 static struct hda_verb alc861_asus_ch2_init[] = {
9057         /* set pin widget 1Ah (line in) for input */
9058         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9059         /* set pin widget 18h (mic1/2) for input, for mic also enable
9060          * the vref
9061          */
9062         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9063
9064         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9065 #if 0
9066         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9067         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9068 #endif
9069         { } /* end */
9070 };
9071 /* Set mic1 nad line-in as output and mute mixer */
9072 static struct hda_verb alc861_asus_ch6_init[] = {
9073         /* set pin widget 1Ah (line in) for output (Back Surround)*/
9074         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9075         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9076         /* set pin widget 18h (mic1) for output (CLFE)*/
9077         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9078         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9079         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9080         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9081
9082         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9083 #if 0
9084         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9085         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9086 #endif
9087         { } /* end */
9088 };
9089
9090 static struct hda_channel_mode alc861_asus_modes[2] = {
9091         { 2, alc861_asus_ch2_init },
9092         { 6, alc861_asus_ch6_init },
9093 };
9094
9095 /* patch-ALC861 */
9096
9097 static struct snd_kcontrol_new alc861_base_mixer[] = {
9098         /* output mixer control */
9099         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9100         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9101         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9102         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9103         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9104
9105         /*Input mixer control */
9106         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9107            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9108         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9109         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9110         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9111         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9112         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9113         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9114         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9115         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9116
9117         /* Capture mixer control */
9118         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9119         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9120         {
9121                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9122                 .name = "Capture Source",
9123                 .count = 1,
9124                 .info = alc_mux_enum_info,
9125                 .get = alc_mux_enum_get,
9126                 .put = alc_mux_enum_put,
9127         },
9128         { } /* end */
9129 };
9130
9131 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
9132         /* output mixer control */
9133         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9134         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9135         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9136         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9137         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9138
9139         /* Input mixer control */
9140         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9141            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9142         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9143         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9144         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9145         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9146         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9147         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9148         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9149         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9150
9151         /* Capture mixer control */
9152         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9153         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9154         {
9155                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9156                 .name = "Capture Source",
9157                 .count = 1,
9158                 .info = alc_mux_enum_info,
9159                 .get = alc_mux_enum_get,
9160                 .put = alc_mux_enum_put,
9161         },
9162         {
9163                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9164                 .name = "Channel Mode",
9165                 .info = alc_ch_mode_info,
9166                 .get = alc_ch_mode_get,
9167                 .put = alc_ch_mode_put,
9168                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
9169         },
9170         { } /* end */
9171 };
9172
9173 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
9174         /* output mixer control */
9175         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9176         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9177         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9178         
9179         /*Capture mixer control */
9180         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9181         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9182         {
9183                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9184                 .name = "Capture Source",
9185                 .count = 1,
9186                 .info = alc_mux_enum_info,
9187                 .get = alc_mux_enum_get,
9188                 .put = alc_mux_enum_put,
9189         },
9190
9191         { } /* end */
9192 };
9193
9194 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
9195         /* output mixer control */
9196         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9197         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9198         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9199         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9200         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9201
9202         /* Input mixer control */
9203         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9204            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9205         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9206         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9207         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9208         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9209         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9210         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9211         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9212         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9213
9214         /* Capture mixer control */
9215         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9216         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9217         {
9218                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9219                 .name = "Capture Source",
9220                 .count = 1,
9221                 .info = alc_mux_enum_info,
9222                 .get = alc_mux_enum_get,
9223                 .put = alc_mux_enum_put,
9224         },
9225         {
9226                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9227                 .name = "Channel Mode",
9228                 .info = alc_ch_mode_info,
9229                 .get = alc_ch_mode_get,
9230                 .put = alc_ch_mode_put,
9231                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
9232         },
9233         { } /* end */
9234 };
9235
9236 static struct snd_kcontrol_new alc861_asus_mixer[] = {
9237         /* output mixer control */
9238         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9239         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9240         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9241         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9242         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9243
9244         /* Input mixer control */
9245         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9246         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9247         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9248         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9249         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9250         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9251         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9252         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9253         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9254         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
9255
9256         /* Capture mixer control */
9257         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9258         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9259         {
9260                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9261                 .name = "Capture Source",
9262                 .count = 1,
9263                 .info = alc_mux_enum_info,
9264                 .get = alc_mux_enum_get,
9265                 .put = alc_mux_enum_put,
9266         },
9267         {
9268                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9269                 .name = "Channel Mode",
9270                 .info = alc_ch_mode_info,
9271                 .get = alc_ch_mode_get,
9272                 .put = alc_ch_mode_put,
9273                 .private_value = ARRAY_SIZE(alc861_asus_modes),
9274         },
9275         { }
9276 };
9277
9278 /* additional mixer */
9279 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
9280         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9281         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9282         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
9283         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
9284         { }
9285 };
9286
9287 /*
9288  * generic initialization of ADC, input mixers and output mixers
9289  */
9290 static struct hda_verb alc861_base_init_verbs[] = {
9291         /*
9292          * Unmute ADC0 and set the default input to mic-in
9293          */
9294         /* port-A for surround (rear panel) */
9295         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9296         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
9297         /* port-B for mic-in (rear panel) with vref */
9298         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9299         /* port-C for line-in (rear panel) */
9300         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9301         /* port-D for Front */
9302         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9303         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9304         /* port-E for HP out (front panel) */
9305         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9306         /* route front PCM to HP */
9307         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9308         /* port-F for mic-in (front panel) with vref */
9309         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9310         /* port-G for CLFE (rear panel) */
9311         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9312         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9313         /* port-H for side (rear panel) */
9314         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9315         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
9316         /* CD-in */
9317         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9318         /* route front mic to ADC1*/
9319         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9320         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9321         
9322         /* Unmute DAC0~3 & spdif out*/
9323         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9324         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9325         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9326         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9327         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9328         
9329         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9330         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9331         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9332         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9333         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9334         
9335         /* Unmute Stereo Mixer 15 */
9336         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9337         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9338         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9339         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9340
9341         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9342         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9343         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9344         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9345         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9346         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9347         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9348         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9349         /* hp used DAC 3 (Front) */
9350         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9351         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9352
9353         { }
9354 };
9355
9356 static struct hda_verb alc861_threestack_init_verbs[] = {
9357         /*
9358          * Unmute ADC0 and set the default input to mic-in
9359          */
9360         /* port-A for surround (rear panel) */
9361         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9362         /* port-B for mic-in (rear panel) with vref */
9363         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9364         /* port-C for line-in (rear panel) */
9365         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9366         /* port-D for Front */
9367         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9368         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9369         /* port-E for HP out (front panel) */
9370         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9371         /* route front PCM to HP */
9372         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9373         /* port-F for mic-in (front panel) with vref */
9374         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9375         /* port-G for CLFE (rear panel) */
9376         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9377         /* port-H for side (rear panel) */
9378         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9379         /* CD-in */
9380         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9381         /* route front mic to ADC1*/
9382         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9383         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9384         /* Unmute DAC0~3 & spdif out*/
9385         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9386         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9387         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9388         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9389         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9390         
9391         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9392         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9393         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9394         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9395         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9396         
9397         /* Unmute Stereo Mixer 15 */
9398         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9399         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9400         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9401         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9402
9403         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9404         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9405         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9406         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9407         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9408         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9409         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9410         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9411         /* hp used DAC 3 (Front) */
9412         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9413         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9414         { }
9415 };
9416
9417 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9418         /*
9419          * Unmute ADC0 and set the default input to mic-in
9420          */
9421         /* port-A for surround (rear panel) */
9422         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9423         /* port-B for mic-in (rear panel) with vref */
9424         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9425         /* port-C for line-in (rear panel) */
9426         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9427         /* port-D for Front */
9428         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9429         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9430         /* port-E for HP out (front panel) */
9431         /* this has to be set to VREF80 */
9432         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9433         /* route front PCM to HP */
9434         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9435         /* port-F for mic-in (front panel) with vref */
9436         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9437         /* port-G for CLFE (rear panel) */
9438         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9439         /* port-H for side (rear panel) */
9440         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9441         /* CD-in */
9442         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9443         /* route front mic to ADC1*/
9444         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9445         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9446         /* Unmute DAC0~3 & spdif out*/
9447         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9448         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9449         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9450         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9451         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9452         
9453         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9454         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9455         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9456         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9457         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9458         
9459         /* Unmute Stereo Mixer 15 */
9460         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9461         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9462         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9463         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9464
9465         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9466         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9467         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9468         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9469         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9470         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9471         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9472         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9473         /* hp used DAC 3 (Front) */
9474         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9475         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9476         { }
9477 };
9478
9479 static struct hda_verb alc861_asus_init_verbs[] = {
9480         /*
9481          * Unmute ADC0 and set the default input to mic-in
9482          */
9483         /* port-A for surround (rear panel)
9484          * according to codec#0 this is the HP jack
9485          */
9486         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9487         /* route front PCM to HP */
9488         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9489         /* port-B for mic-in (rear panel) with vref */
9490         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9491         /* port-C for line-in (rear panel) */
9492         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9493         /* port-D for Front */
9494         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9495         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9496         /* port-E for HP out (front panel) */
9497         /* this has to be set to VREF80 */
9498         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9499         /* route front PCM to HP */
9500         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9501         /* port-F for mic-in (front panel) with vref */
9502         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9503         /* port-G for CLFE (rear panel) */
9504         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9505         /* port-H for side (rear panel) */
9506         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9507         /* CD-in */
9508         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9509         /* route front mic to ADC1*/
9510         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9511         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9512         /* Unmute DAC0~3 & spdif out*/
9513         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9514         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9515         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9516         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9517         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9518         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9519         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9520         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9521         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9522         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9523         
9524         /* Unmute Stereo Mixer 15 */
9525         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9526         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9527         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9528         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9529
9530         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9531         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9532         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9533         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9534         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9535         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9536         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9537         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9538         /* hp used DAC 3 (Front) */
9539         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9540         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9541         { }
9542 };
9543
9544 /* additional init verbs for ASUS laptops */
9545 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9546         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9547         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9548         { }
9549 };
9550
9551 /*
9552  * generic initialization of ADC, input mixers and output mixers
9553  */
9554 static struct hda_verb alc861_auto_init_verbs[] = {
9555         /*
9556          * Unmute ADC0 and set the default input to mic-in
9557          */
9558         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9559         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9560         
9561         /* Unmute DAC0~3 & spdif out*/
9562         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9563         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9564         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9565         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9566         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9567         
9568         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9569         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9570         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9571         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9572         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9573         
9574         /* Unmute Stereo Mixer 15 */
9575         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9576         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9577         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9578         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9579
9580         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9581         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9582         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9583         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9584         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9585         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9586         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9587         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9588
9589         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9590         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9591         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9592         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9593         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9594         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9595         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9596         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9597
9598         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
9599
9600         { }
9601 };
9602
9603 static struct hda_verb alc861_toshiba_init_verbs[] = {
9604         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9605
9606         { }
9607 };
9608
9609 /* toggle speaker-output according to the hp-jack state */
9610 static void alc861_toshiba_automute(struct hda_codec *codec)
9611 {
9612         unsigned int present;
9613
9614         present = snd_hda_codec_read(codec, 0x0f, 0,
9615                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9616         snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
9617                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9618         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
9619                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
9620 }
9621
9622 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9623                                        unsigned int res)
9624 {
9625         if ((res >> 26) == ALC880_HP_EVENT)
9626                 alc861_toshiba_automute(codec);
9627 }
9628
9629 /* pcm configuration: identiacal with ALC880 */
9630 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
9631 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
9632 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
9633 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
9634
9635
9636 #define ALC861_DIGOUT_NID       0x07
9637
9638 static struct hda_channel_mode alc861_8ch_modes[1] = {
9639         { 8, NULL }
9640 };
9641
9642 static hda_nid_t alc861_dac_nids[4] = {
9643         /* front, surround, clfe, side */
9644         0x03, 0x06, 0x05, 0x04
9645 };
9646
9647 static hda_nid_t alc660_dac_nids[3] = {
9648         /* front, clfe, surround */
9649         0x03, 0x05, 0x06
9650 };
9651
9652 static hda_nid_t alc861_adc_nids[1] = {
9653         /* ADC0-2 */
9654         0x08,
9655 };
9656
9657 static struct hda_input_mux alc861_capture_source = {
9658         .num_items = 5,
9659         .items = {
9660                 { "Mic", 0x0 },
9661                 { "Front Mic", 0x3 },
9662                 { "Line", 0x1 },
9663                 { "CD", 0x4 },
9664                 { "Mixer", 0x5 },
9665         },
9666 };
9667
9668 /* fill in the dac_nids table from the parsed pin configuration */
9669 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9670                                      const struct auto_pin_cfg *cfg)
9671 {
9672         int i;
9673         hda_nid_t nid;
9674
9675         spec->multiout.dac_nids = spec->private_dac_nids;
9676         for (i = 0; i < cfg->line_outs; i++) {
9677                 nid = cfg->line_out_pins[i];
9678                 if (nid) {
9679                         if (i >= ARRAY_SIZE(alc861_dac_nids))
9680                                 continue;
9681                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9682                 }
9683         }
9684         spec->multiout.num_dacs = cfg->line_outs;
9685         return 0;
9686 }
9687
9688 /* add playback controls from the parsed DAC table */
9689 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9690                                              const struct auto_pin_cfg *cfg)
9691 {
9692         char name[32];
9693         static const char *chname[4] = {
9694                 "Front", "Surround", NULL /*CLFE*/, "Side"
9695         };
9696         hda_nid_t nid;
9697         int i, idx, err;
9698
9699         for (i = 0; i < cfg->line_outs; i++) {
9700                 nid = spec->multiout.dac_nids[i];
9701                 if (!nid)
9702                         continue;
9703                 if (nid == 0x05) {
9704                         /* Center/LFE */
9705                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9706                                           "Center Playback Switch",
9707                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9708                                                               HDA_OUTPUT));
9709                         if (err < 0)
9710                                 return err;
9711                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9712                                           "LFE Playback Switch",
9713                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9714                                                               HDA_OUTPUT));
9715                         if (err < 0)
9716                                 return err;
9717                 } else {
9718                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9719                              idx++)
9720                                 if (nid == alc861_dac_nids[idx])
9721                                         break;
9722                         sprintf(name, "%s Playback Switch", chname[idx]);
9723                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9724                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9725                                                               HDA_OUTPUT));
9726                         if (err < 0)
9727                                 return err;
9728                 }
9729         }
9730         return 0;
9731 }
9732
9733 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9734 {
9735         int err;
9736         hda_nid_t nid;
9737
9738         if (!pin)
9739                 return 0;
9740
9741         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9742                 nid = 0x03;
9743                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9744                                   "Headphone Playback Switch",
9745                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9746                 if (err < 0)
9747                         return err;
9748                 spec->multiout.hp_nid = nid;
9749         }
9750         return 0;
9751 }
9752
9753 /* create playback/capture controls for input pins */
9754 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9755                                                 const struct auto_pin_cfg *cfg)
9756 {
9757         struct hda_input_mux *imux = &spec->private_imux;
9758         int i, err, idx, idx1;
9759
9760         for (i = 0; i < AUTO_PIN_LAST; i++) {
9761                 switch (cfg->input_pins[i]) {
9762                 case 0x0c:
9763                         idx1 = 1;
9764                         idx = 2;        /* Line In */
9765                         break;
9766                 case 0x0f:
9767                         idx1 = 2;
9768                         idx = 2;        /* Line In */
9769                         break;
9770                 case 0x0d:
9771                         idx1 = 0;
9772                         idx = 1;        /* Mic In */
9773                         break;
9774                 case 0x10:
9775                         idx1 = 3;
9776                         idx = 1;        /* Mic In */
9777                         break;
9778                 case 0x11:
9779                         idx1 = 4;
9780                         idx = 0;        /* CD */
9781                         break;
9782                 default:
9783                         continue;
9784                 }
9785
9786                 err = new_analog_input(spec, cfg->input_pins[i],
9787                                        auto_pin_cfg_labels[i], idx, 0x15);
9788                 if (err < 0)
9789                         return err;
9790
9791                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9792                 imux->items[imux->num_items].index = idx1;
9793                 imux->num_items++;
9794         }
9795         return 0;
9796 }
9797
9798 static struct snd_kcontrol_new alc861_capture_mixer[] = {
9799         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9800         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9801
9802         {
9803                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9804                 /* The multiple "Capture Source" controls confuse alsamixer
9805                  * So call somewhat different..
9806                  *FIXME: the controls appear in the "playback" view!
9807                  */
9808                 /* .name = "Capture Source", */
9809                 .name = "Input Source",
9810                 .count = 1,
9811                 .info = alc_mux_enum_info,
9812                 .get = alc_mux_enum_get,
9813                 .put = alc_mux_enum_put,
9814         },
9815         { } /* end */
9816 };
9817
9818 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9819                                               hda_nid_t nid,
9820                                               int pin_type, int dac_idx)
9821 {
9822         /* set as output */
9823
9824         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9825                             pin_type);
9826         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9827                             AMP_OUT_UNMUTE);
9828
9829 }
9830
9831 static void alc861_auto_init_multi_out(struct hda_codec *codec)
9832 {
9833         struct alc_spec *spec = codec->spec;
9834         int i;
9835
9836         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9837         for (i = 0; i < spec->autocfg.line_outs; i++) {
9838                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9839                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9840                 if (nid)
9841                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9842                                                           spec->multiout.dac_nids[i]);
9843         }
9844 }
9845
9846 static void alc861_auto_init_hp_out(struct hda_codec *codec)
9847 {
9848         struct alc_spec *spec = codec->spec;
9849         hda_nid_t pin;
9850
9851         pin = spec->autocfg.hp_pins[0];
9852         if (pin) /* connect to front */
9853                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9854                                                   spec->multiout.dac_nids[0]);
9855 }
9856
9857 static void alc861_auto_init_analog_input(struct hda_codec *codec)
9858 {
9859         struct alc_spec *spec = codec->spec;
9860         int i;
9861
9862         for (i = 0; i < AUTO_PIN_LAST; i++) {
9863                 hda_nid_t nid = spec->autocfg.input_pins[i];
9864                 if (nid >= 0x0c && nid <= 0x11) {
9865                         snd_hda_codec_write(codec, nid, 0,
9866                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
9867                                             i <= AUTO_PIN_FRONT_MIC ?
9868                                             PIN_VREF80 : PIN_IN);
9869                 }
9870         }
9871 }
9872
9873 /* parse the BIOS configuration and set up the alc_spec */
9874 /* return 1 if successful, 0 if the proper config is not found,
9875  * or a negative error code
9876  */
9877 static int alc861_parse_auto_config(struct hda_codec *codec)
9878 {
9879         struct alc_spec *spec = codec->spec;
9880         int err;
9881         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9882
9883         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9884                                            alc861_ignore);
9885         if (err < 0)
9886                 return err;
9887         if (!spec->autocfg.line_outs)
9888                 return 0; /* can't find valid BIOS pin config */
9889
9890         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9891         if (err < 0)
9892                 return err;
9893         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9894         if (err < 0)
9895                 return err;
9896         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9897         if (err < 0)
9898                 return err;
9899         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9900         if (err < 0)
9901                 return err;
9902
9903         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9904
9905         if (spec->autocfg.dig_out_pin)
9906                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9907
9908         if (spec->kctl_alloc)
9909                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9910
9911         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9912
9913         spec->num_mux_defs = 1;
9914         spec->input_mux = &spec->private_imux;
9915
9916         spec->adc_nids = alc861_adc_nids;
9917         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9918         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9919         spec->num_mixers++;
9920
9921         return 1;
9922 }
9923
9924 /* additional initialization for auto-configuration model */
9925 static void alc861_auto_init(struct hda_codec *codec)
9926 {
9927         alc861_auto_init_multi_out(codec);
9928         alc861_auto_init_hp_out(codec);
9929         alc861_auto_init_analog_input(codec);
9930 }
9931
9932 #ifdef CONFIG_SND_HDA_POWER_SAVE
9933 static struct hda_amp_list alc861_loopbacks[] = {
9934         { 0x15, HDA_INPUT, 0 },
9935         { 0x15, HDA_INPUT, 1 },
9936         { 0x15, HDA_INPUT, 2 },
9937         { 0x15, HDA_INPUT, 3 },
9938         { } /* end */
9939 };
9940 #endif
9941
9942
9943 /*
9944  * configuration and preset
9945  */
9946 static const char *alc861_models[ALC861_MODEL_LAST] = {
9947         [ALC861_3ST]            = "3stack",
9948         [ALC660_3ST]            = "3stack-660",
9949         [ALC861_3ST_DIG]        = "3stack-dig",
9950         [ALC861_6ST_DIG]        = "6stack-dig",
9951         [ALC861_UNIWILL_M31]    = "uniwill-m31",
9952         [ALC861_TOSHIBA]        = "toshiba",
9953         [ALC861_ASUS]           = "asus",
9954         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
9955         [ALC861_AUTO]           = "auto",
9956 };
9957
9958 static struct snd_pci_quirk alc861_cfg_tbl[] = {
9959         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9960         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9961         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9962         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9963         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9964         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9965         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9966         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9967         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9968          *        Any other models that need this preset?
9969          */
9970         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9971         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9972         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9973         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9974         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9975         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9976         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9977         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9978         {}
9979 };
9980
9981 static struct alc_config_preset alc861_presets[] = {
9982         [ALC861_3ST] = {
9983                 .mixers = { alc861_3ST_mixer },
9984                 .init_verbs = { alc861_threestack_init_verbs },
9985                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9986                 .dac_nids = alc861_dac_nids,
9987                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9988                 .channel_mode = alc861_threestack_modes,
9989                 .need_dac_fix = 1,
9990                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9991                 .adc_nids = alc861_adc_nids,
9992                 .input_mux = &alc861_capture_source,
9993         },
9994         [ALC861_3ST_DIG] = {
9995                 .mixers = { alc861_base_mixer },
9996                 .init_verbs = { alc861_threestack_init_verbs },
9997                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9998                 .dac_nids = alc861_dac_nids,
9999                 .dig_out_nid = ALC861_DIGOUT_NID,
10000                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10001                 .channel_mode = alc861_threestack_modes,
10002                 .need_dac_fix = 1,
10003                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10004                 .adc_nids = alc861_adc_nids,
10005                 .input_mux = &alc861_capture_source,
10006         },
10007         [ALC861_6ST_DIG] = {
10008                 .mixers = { alc861_base_mixer },
10009                 .init_verbs = { alc861_base_init_verbs },
10010                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10011                 .dac_nids = alc861_dac_nids,
10012                 .dig_out_nid = ALC861_DIGOUT_NID,
10013                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
10014                 .channel_mode = alc861_8ch_modes,
10015                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10016                 .adc_nids = alc861_adc_nids,
10017                 .input_mux = &alc861_capture_source,
10018         },
10019         [ALC660_3ST] = {
10020                 .mixers = { alc861_3ST_mixer },
10021                 .init_verbs = { alc861_threestack_init_verbs },
10022                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
10023                 .dac_nids = alc660_dac_nids,
10024                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10025                 .channel_mode = alc861_threestack_modes,
10026                 .need_dac_fix = 1,
10027                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10028                 .adc_nids = alc861_adc_nids,
10029                 .input_mux = &alc861_capture_source,
10030         },
10031         [ALC861_UNIWILL_M31] = {
10032                 .mixers = { alc861_uniwill_m31_mixer },
10033                 .init_verbs = { alc861_uniwill_m31_init_verbs },
10034                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10035                 .dac_nids = alc861_dac_nids,
10036                 .dig_out_nid = ALC861_DIGOUT_NID,
10037                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
10038                 .channel_mode = alc861_uniwill_m31_modes,
10039                 .need_dac_fix = 1,
10040                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10041                 .adc_nids = alc861_adc_nids,
10042                 .input_mux = &alc861_capture_source,
10043         },
10044         [ALC861_TOSHIBA] = {
10045                 .mixers = { alc861_toshiba_mixer },
10046                 .init_verbs = { alc861_base_init_verbs,
10047                                 alc861_toshiba_init_verbs },
10048                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10049                 .dac_nids = alc861_dac_nids,
10050                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10051                 .channel_mode = alc883_3ST_2ch_modes,
10052                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10053                 .adc_nids = alc861_adc_nids,
10054                 .input_mux = &alc861_capture_source,
10055                 .unsol_event = alc861_toshiba_unsol_event,
10056                 .init_hook = alc861_toshiba_automute,
10057         },
10058         [ALC861_ASUS] = {
10059                 .mixers = { alc861_asus_mixer },
10060                 .init_verbs = { alc861_asus_init_verbs },
10061                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10062                 .dac_nids = alc861_dac_nids,
10063                 .dig_out_nid = ALC861_DIGOUT_NID,
10064                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
10065                 .channel_mode = alc861_asus_modes,
10066                 .need_dac_fix = 1,
10067                 .hp_nid = 0x06,
10068                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10069                 .adc_nids = alc861_adc_nids,
10070                 .input_mux = &alc861_capture_source,
10071         },
10072         [ALC861_ASUS_LAPTOP] = {
10073                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
10074                 .init_verbs = { alc861_asus_init_verbs,
10075                                 alc861_asus_laptop_init_verbs },
10076                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10077                 .dac_nids = alc861_dac_nids,
10078                 .dig_out_nid = ALC861_DIGOUT_NID,
10079                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10080                 .channel_mode = alc883_3ST_2ch_modes,
10081                 .need_dac_fix = 1,
10082                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10083                 .adc_nids = alc861_adc_nids,
10084                 .input_mux = &alc861_capture_source,
10085         },
10086 };
10087
10088
10089 static int patch_alc861(struct hda_codec *codec)
10090 {
10091         struct alc_spec *spec;
10092         int board_config;
10093         int err;
10094
10095         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10096         if (spec == NULL)
10097                 return -ENOMEM;
10098
10099         codec->spec = spec;
10100
10101         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
10102                                                   alc861_models,
10103                                                   alc861_cfg_tbl);
10104
10105         if (board_config < 0) {
10106                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
10107                        "trying auto-probe from BIOS...\n");
10108                 board_config = ALC861_AUTO;
10109         }
10110
10111         if (board_config == ALC861_AUTO) {
10112                 /* automatic parse from the BIOS config */
10113                 err = alc861_parse_auto_config(codec);
10114                 if (err < 0) {
10115                         alc_free(codec);
10116                         return err;
10117                 } else if (!err) {
10118                         printk(KERN_INFO
10119                                "hda_codec: Cannot set up configuration "
10120                                "from BIOS.  Using base mode...\n");
10121                    board_config = ALC861_3ST_DIG;
10122                 }
10123         }
10124
10125         if (board_config != ALC861_AUTO)
10126                 setup_preset(spec, &alc861_presets[board_config]);
10127
10128         spec->stream_name_analog = "ALC861 Analog";
10129         spec->stream_analog_playback = &alc861_pcm_analog_playback;
10130         spec->stream_analog_capture = &alc861_pcm_analog_capture;
10131
10132         spec->stream_name_digital = "ALC861 Digital";
10133         spec->stream_digital_playback = &alc861_pcm_digital_playback;
10134         spec->stream_digital_capture = &alc861_pcm_digital_capture;
10135
10136         codec->patch_ops = alc_patch_ops;
10137         if (board_config == ALC861_AUTO)
10138                 spec->init_hook = alc861_auto_init;
10139 #ifdef CONFIG_SND_HDA_POWER_SAVE
10140         if (!spec->loopback.amplist)
10141                 spec->loopback.amplist = alc861_loopbacks;
10142 #endif
10143                 
10144         return 0;
10145 }
10146
10147 /*
10148  * ALC861-VD support
10149  *
10150  * Based on ALC882
10151  *
10152  * In addition, an independent DAC
10153  */
10154 #define ALC861VD_DIGOUT_NID     0x06
10155
10156 static hda_nid_t alc861vd_dac_nids[4] = {
10157         /* front, surr, clfe, side surr */
10158         0x02, 0x03, 0x04, 0x05
10159 };
10160
10161 /* dac_nids for ALC660vd are in a different order - according to
10162  * Realtek's driver.
10163  * This should probably tesult in a different mixer for 6stack models
10164  * of ALC660vd codecs, but for now there is only 3stack mixer
10165  * - and it is the same as in 861vd.
10166  * adc_nids in ALC660vd are (is) the same as in 861vd
10167  */
10168 static hda_nid_t alc660vd_dac_nids[3] = {
10169         /* front, rear, clfe, rear_surr */
10170         0x02, 0x04, 0x03
10171 };
10172
10173 static hda_nid_t alc861vd_adc_nids[1] = {
10174         /* ADC0 */
10175         0x09,
10176 };
10177
10178 /* input MUX */
10179 /* FIXME: should be a matrix-type input source selection */
10180 static struct hda_input_mux alc861vd_capture_source = {
10181         .num_items = 4,
10182         .items = {
10183                 { "Mic", 0x0 },
10184                 { "Front Mic", 0x1 },
10185                 { "Line", 0x2 },
10186                 { "CD", 0x4 },
10187         },
10188 };
10189
10190 static struct hda_input_mux alc861vd_dallas_capture_source = {
10191         .num_items = 3,
10192         .items = {
10193                 { "Front Mic", 0x0 },
10194                 { "ATAPI Mic", 0x1 },
10195                 { "Line In", 0x5 },
10196         },
10197 };
10198
10199 static struct hda_input_mux alc861vd_hp_capture_source = {
10200         .num_items = 2,
10201         .items = {
10202                 { "Front Mic", 0x0 },
10203                 { "ATAPI Mic", 0x1 },
10204         },
10205 };
10206
10207 #define alc861vd_mux_enum_info alc_mux_enum_info
10208 #define alc861vd_mux_enum_get alc_mux_enum_get
10209
10210 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
10211                                 struct snd_ctl_elem_value *ucontrol)
10212 {
10213         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10214         struct alc_spec *spec = codec->spec;
10215         const struct hda_input_mux *imux = spec->input_mux;
10216         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10217         static hda_nid_t capture_mixers[1] = { 0x22 };
10218         hda_nid_t nid = capture_mixers[adc_idx];
10219         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10220         unsigned int i, idx;
10221
10222         idx = ucontrol->value.enumerated.item[0];
10223         if (idx >= imux->num_items)
10224                 idx = imux->num_items - 1;
10225         if (*cur_val == idx)
10226                 return 0;
10227         for (i = 0; i < imux->num_items; i++) {
10228                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10229                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10230                                          imux->items[i].index,
10231                                          HDA_AMP_MUTE, v);
10232         }
10233         *cur_val = idx;
10234         return 1;
10235 }
10236
10237 /*
10238  * 2ch mode
10239  */
10240 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
10241         { 2, NULL }
10242 };
10243
10244 /*
10245  * 6ch mode
10246  */
10247 static struct hda_verb alc861vd_6stack_ch6_init[] = {
10248         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10249         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10250         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10251         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10252         { } /* end */
10253 };
10254
10255 /*
10256  * 8ch mode
10257  */
10258 static struct hda_verb alc861vd_6stack_ch8_init[] = {
10259         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10260         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10261         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10262         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10263         { } /* end */
10264 };
10265
10266 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
10267         { 6, alc861vd_6stack_ch6_init },
10268         { 8, alc861vd_6stack_ch8_init },
10269 };
10270
10271 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
10272         {
10273                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10274                 .name = "Channel Mode",
10275                 .info = alc_ch_mode_info,
10276                 .get = alc_ch_mode_get,
10277                 .put = alc_ch_mode_put,
10278         },
10279         { } /* end */
10280 };
10281
10282 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
10283         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10284         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10285
10286         {
10287                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10288                 /* The multiple "Capture Source" controls confuse alsamixer
10289                  * So call somewhat different..
10290                  *FIXME: the controls appear in the "playback" view!
10291                  */
10292                 /* .name = "Capture Source", */
10293                 .name = "Input Source",
10294                 .count = 1,
10295                 .info = alc861vd_mux_enum_info,
10296                 .get = alc861vd_mux_enum_get,
10297                 .put = alc861vd_mux_enum_put,
10298         },
10299         { } /* end */
10300 };
10301
10302 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10303  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10304  */
10305 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
10306         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10307         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10308
10309         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10310         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
10311
10312         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
10313                                 HDA_OUTPUT),
10314         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
10315                                 HDA_OUTPUT),
10316         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10317         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
10318
10319         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
10320         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
10321
10322         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10323
10324         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10325         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10326         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10327
10328         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10329         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10330         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10331
10332         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10333         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10334
10335         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10336         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10337
10338         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10339         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10340
10341         { } /* end */
10342 };
10343
10344 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
10345         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10346         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10347
10348         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10349
10350         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10351         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10352         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10353
10354         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10355         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10356         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10357
10358         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10359         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10360
10361         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10362         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10363
10364         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10365         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10366
10367         { } /* end */
10368 };
10369
10370 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10371         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10372         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10373         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10374
10375         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10376
10377         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10378         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10379         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10380
10381         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10382         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10383         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10384
10385         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10386         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10387
10388         { } /* end */
10389 };
10390
10391 /* Pin assignment: Front=0x14, HP = 0x15,
10392  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10393  */
10394 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10395         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10396         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10397         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10398         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10399         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10400         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10401         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10402         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10403         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10404         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10405         { } /* end */
10406 };
10407
10408 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
10409  *                 Front Mic=0x18, ATAPI Mic = 0x19,
10410  */
10411 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
10412         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10413         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10414         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10415         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10416         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10417         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10418         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10419         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10420         
10421         { } /* end */
10422 };
10423
10424 /*
10425  * generic initialization of ADC, input mixers and output mixers
10426  */
10427 static struct hda_verb alc861vd_volume_init_verbs[] = {
10428         /*
10429          * Unmute ADC0 and set the default input to mic-in
10430          */
10431         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10432         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10433
10434         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10435          * the analog-loopback mixer widget
10436          */
10437         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10438         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10439         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10440         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10441         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10442         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10443
10444         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10445         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10446         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10447         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10448         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10449
10450         /*
10451          * Set up output mixers (0x02 - 0x05)
10452          */
10453         /* set vol=0 to output mixers */
10454         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10455         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10456         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10457         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10458
10459         /* set up input amps for analog loopback */
10460         /* Amp Indices: DAC = 0, mixer = 1 */
10461         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10462         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10463         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10464         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10465         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10466         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10467         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10468         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10469
10470         { }
10471 };
10472
10473 /*
10474  * 3-stack pin configuration:
10475  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10476  */
10477 static struct hda_verb alc861vd_3stack_init_verbs[] = {
10478         /*
10479          * Set pin mode and muting
10480          */
10481         /* set front pin widgets 0x14 for output */
10482         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10483         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10484         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10485
10486         /* Mic (rear) pin: input vref at 80% */
10487         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10488         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10489         /* Front Mic pin: input vref at 80% */
10490         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10491         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10492         /* Line In pin: input */
10493         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10494         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10495         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10496         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10497         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10498         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10499         /* CD pin widget for input */
10500         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10501
10502         { }
10503 };
10504
10505 /*
10506  * 6-stack pin configuration:
10507  */
10508 static struct hda_verb alc861vd_6stack_init_verbs[] = {
10509         /*
10510          * Set pin mode and muting
10511          */
10512         /* set front pin widgets 0x14 for output */
10513         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10514         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10515         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10516
10517         /* Rear Pin: output 1 (0x0d) */
10518         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10519         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10520         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10521         /* CLFE Pin: output 2 (0x0e) */
10522         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10523         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10524         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10525         /* Side Pin: output 3 (0x0f) */
10526         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10527         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10528         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10529
10530         /* Mic (rear) pin: input vref at 80% */
10531         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10532         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10533         /* Front Mic pin: input vref at 80% */
10534         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10535         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10536         /* Line In pin: input */
10537         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10538         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10539         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10540         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10541         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10542         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10543         /* CD pin widget for input */
10544         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10545
10546         { }
10547 };
10548
10549 static struct hda_verb alc861vd_eapd_verbs[] = {
10550         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10551         { }
10552 };
10553
10554 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10555         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10556         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10557         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10558         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10559         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
10560         {}
10561 };
10562
10563 /* toggle speaker-output according to the hp-jack state */
10564 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10565 {
10566         unsigned int present;
10567         unsigned char bits;
10568
10569         present = snd_hda_codec_read(codec, 0x1b, 0,
10570                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10571         bits = present ? HDA_AMP_MUTE : 0;
10572         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10573                                  HDA_AMP_MUTE, bits);
10574 }
10575
10576 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10577 {
10578         unsigned int present;
10579         unsigned char bits;
10580
10581         present = snd_hda_codec_read(codec, 0x18, 0,
10582                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10583         bits = present ? HDA_AMP_MUTE : 0;
10584         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
10585                                  HDA_AMP_MUTE, bits);
10586 }
10587
10588 static void alc861vd_lenovo_automute(struct hda_codec *codec)
10589 {
10590         alc861vd_lenovo_hp_automute(codec);
10591         alc861vd_lenovo_mic_automute(codec);
10592 }
10593
10594 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10595                                         unsigned int res)
10596 {
10597         switch (res >> 26) {
10598         case ALC880_HP_EVENT:
10599                 alc861vd_lenovo_hp_automute(codec);
10600                 break;
10601         case ALC880_MIC_EVENT:
10602                 alc861vd_lenovo_mic_automute(codec);
10603                 break;
10604         }
10605 }
10606
10607 static struct hda_verb alc861vd_dallas_verbs[] = {
10608         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10609         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10610         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10611         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10612
10613         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10614         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10615         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10616         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10617         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10618         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10619         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10620         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10621         
10622         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10623         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10624         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10625         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10626         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10627         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10628         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10629         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10630
10631         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10632         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10633         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10634         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10635         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10636         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10637         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10638         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10639
10640         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10641         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10642         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10643         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10644
10645         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10646         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
10647         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10648
10649         { } /* end */
10650 };
10651
10652 /* toggle speaker-output according to the hp-jack state */
10653 static void alc861vd_dallas_automute(struct hda_codec *codec)
10654 {
10655         unsigned int present;
10656
10657         present = snd_hda_codec_read(codec, 0x15, 0,
10658                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10659         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10660                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10661 }
10662
10663 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10664 {
10665         if ((res >> 26) == ALC880_HP_EVENT)
10666                 alc861vd_dallas_automute(codec);
10667 }
10668
10669 #ifdef CONFIG_SND_HDA_POWER_SAVE
10670 #define alc861vd_loopbacks      alc880_loopbacks
10671 #endif
10672
10673 /* pcm configuration: identiacal with ALC880 */
10674 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
10675 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
10676 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
10677 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
10678
10679 /*
10680  * configuration and preset
10681  */
10682 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10683         [ALC660VD_3ST]          = "3stack-660",
10684         [ALC660VD_3ST_DIG]      = "3stack-660-digout",
10685         [ALC861VD_3ST]          = "3stack",
10686         [ALC861VD_3ST_DIG]      = "3stack-digout",
10687         [ALC861VD_6ST_DIG]      = "6stack-digout",
10688         [ALC861VD_LENOVO]       = "lenovo",
10689         [ALC861VD_DALLAS]       = "dallas",
10690         [ALC861VD_HP]           = "hp",
10691         [ALC861VD_AUTO]         = "auto",
10692 };
10693
10694 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10695         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10696         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10697         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10698         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10699         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10700
10701         /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
10702         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10703         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10704         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10705         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10706         SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
10707         SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
10708         SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
10709         SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
10710         {}
10711 };
10712
10713 static struct alc_config_preset alc861vd_presets[] = {
10714         [ALC660VD_3ST] = {
10715                 .mixers = { alc861vd_3st_mixer },
10716                 .init_verbs = { alc861vd_volume_init_verbs,
10717                                  alc861vd_3stack_init_verbs },
10718                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10719                 .dac_nids = alc660vd_dac_nids,
10720                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10721                 .adc_nids = alc861vd_adc_nids,
10722                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10723                 .channel_mode = alc861vd_3stack_2ch_modes,
10724                 .input_mux = &alc861vd_capture_source,
10725         },
10726         [ALC660VD_3ST_DIG] = {
10727                 .mixers = { alc861vd_3st_mixer },
10728                 .init_verbs = { alc861vd_volume_init_verbs,
10729                                  alc861vd_3stack_init_verbs },
10730                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10731                 .dac_nids = alc660vd_dac_nids,
10732                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10733                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10734                 .adc_nids = alc861vd_adc_nids,
10735                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10736                 .channel_mode = alc861vd_3stack_2ch_modes,
10737                 .input_mux = &alc861vd_capture_source,
10738         },
10739         [ALC861VD_3ST] = {
10740                 .mixers = { alc861vd_3st_mixer },
10741                 .init_verbs = { alc861vd_volume_init_verbs,
10742                                  alc861vd_3stack_init_verbs },
10743                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10744                 .dac_nids = alc861vd_dac_nids,
10745                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10746                 .channel_mode = alc861vd_3stack_2ch_modes,
10747                 .input_mux = &alc861vd_capture_source,
10748         },
10749         [ALC861VD_3ST_DIG] = {
10750                 .mixers = { alc861vd_3st_mixer },
10751                 .init_verbs = { alc861vd_volume_init_verbs,
10752                                  alc861vd_3stack_init_verbs },
10753                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10754                 .dac_nids = alc861vd_dac_nids,
10755                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10756                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10757                 .channel_mode = alc861vd_3stack_2ch_modes,
10758                 .input_mux = &alc861vd_capture_source,
10759         },
10760         [ALC861VD_6ST_DIG] = {
10761                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10762                 .init_verbs = { alc861vd_volume_init_verbs,
10763                                 alc861vd_6stack_init_verbs },
10764                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10765                 .dac_nids = alc861vd_dac_nids,
10766                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10767                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10768                 .channel_mode = alc861vd_6stack_modes,
10769                 .input_mux = &alc861vd_capture_source,
10770         },
10771         [ALC861VD_LENOVO] = {
10772                 .mixers = { alc861vd_lenovo_mixer },
10773                 .init_verbs = { alc861vd_volume_init_verbs,
10774                                 alc861vd_3stack_init_verbs,
10775                                 alc861vd_eapd_verbs,
10776                                 alc861vd_lenovo_unsol_verbs },
10777                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10778                 .dac_nids = alc660vd_dac_nids,
10779                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10780                 .adc_nids = alc861vd_adc_nids,
10781                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10782                 .channel_mode = alc861vd_3stack_2ch_modes,
10783                 .input_mux = &alc861vd_capture_source,
10784                 .unsol_event = alc861vd_lenovo_unsol_event,
10785                 .init_hook = alc861vd_lenovo_automute,
10786         },
10787         [ALC861VD_DALLAS] = {
10788                 .mixers = { alc861vd_dallas_mixer },
10789                 .init_verbs = { alc861vd_dallas_verbs },
10790                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10791                 .dac_nids = alc861vd_dac_nids,
10792                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10793                 .adc_nids = alc861vd_adc_nids,
10794                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10795                 .channel_mode = alc861vd_3stack_2ch_modes,
10796                 .input_mux = &alc861vd_dallas_capture_source,
10797                 .unsol_event = alc861vd_dallas_unsol_event,
10798                 .init_hook = alc861vd_dallas_automute,
10799         },
10800         [ALC861VD_HP] = {
10801                 .mixers = { alc861vd_hp_mixer },
10802                 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
10803                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10804                 .dac_nids = alc861vd_dac_nids,
10805                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10806                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10807                 .adc_nids = alc861vd_adc_nids,
10808                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10809                 .channel_mode = alc861vd_3stack_2ch_modes,
10810                 .input_mux = &alc861vd_hp_capture_source,
10811                 .unsol_event = alc861vd_dallas_unsol_event,
10812                 .init_hook = alc861vd_dallas_automute,
10813         },              
10814 };
10815
10816 /*
10817  * BIOS auto configuration
10818  */
10819 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10820                                 hda_nid_t nid, int pin_type, int dac_idx)
10821 {
10822         /* set as output */
10823         snd_hda_codec_write(codec, nid, 0,
10824                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10825         snd_hda_codec_write(codec, nid, 0,
10826                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10827 }
10828
10829 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10830 {
10831         struct alc_spec *spec = codec->spec;
10832         int i;
10833
10834         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10835         for (i = 0; i <= HDA_SIDE; i++) {
10836                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10837                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10838                 if (nid)
10839                         alc861vd_auto_set_output_and_unmute(codec, nid,
10840                                                             pin_type, i);
10841         }
10842 }
10843
10844
10845 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10846 {
10847         struct alc_spec *spec = codec->spec;
10848         hda_nid_t pin;
10849
10850         pin = spec->autocfg.hp_pins[0];
10851         if (pin) /* connect to front and  use dac 0 */
10852                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10853 }
10854
10855 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
10856 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
10857
10858 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10859 {
10860         struct alc_spec *spec = codec->spec;
10861         int i;
10862
10863         for (i = 0; i < AUTO_PIN_LAST; i++) {
10864                 hda_nid_t nid = spec->autocfg.input_pins[i];
10865                 if (alc861vd_is_input_pin(nid)) {
10866                         snd_hda_codec_write(codec, nid, 0,
10867                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
10868                                         i <= AUTO_PIN_FRONT_MIC ?
10869                                                         PIN_VREF80 : PIN_IN);
10870                         if (nid != ALC861VD_PIN_CD_NID)
10871                                 snd_hda_codec_write(codec, nid, 0,
10872                                                 AC_VERB_SET_AMP_GAIN_MUTE,
10873                                                 AMP_OUT_MUTE);
10874                 }
10875         }
10876 }
10877
10878 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
10879 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
10880
10881 /* add playback controls from the parsed DAC table */
10882 /* Based on ALC880 version. But ALC861VD has separate,
10883  * different NIDs for mute/unmute switch and volume control */
10884 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10885                                              const struct auto_pin_cfg *cfg)
10886 {
10887         char name[32];
10888         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10889         hda_nid_t nid_v, nid_s;
10890         int i, err;
10891
10892         for (i = 0; i < cfg->line_outs; i++) {
10893                 if (!spec->multiout.dac_nids[i])
10894                         continue;
10895                 nid_v = alc861vd_idx_to_mixer_vol(
10896                                 alc880_dac_to_idx(
10897                                         spec->multiout.dac_nids[i]));
10898                 nid_s = alc861vd_idx_to_mixer_switch(
10899                                 alc880_dac_to_idx(
10900                                         spec->multiout.dac_nids[i]));
10901
10902                 if (i == 2) {
10903                         /* Center/LFE */
10904                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10905                                           "Center Playback Volume",
10906                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10907                                                               HDA_OUTPUT));
10908                         if (err < 0)
10909                                 return err;
10910                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10911                                           "LFE Playback Volume",
10912                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10913                                                               HDA_OUTPUT));
10914                         if (err < 0)
10915                                 return err;
10916                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10917                                           "Center Playback Switch",
10918                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10919                                                               HDA_INPUT));
10920                         if (err < 0)
10921                                 return err;
10922                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10923                                           "LFE Playback Switch",
10924                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10925                                                               HDA_INPUT));
10926                         if (err < 0)
10927                                 return err;
10928                 } else {
10929                         sprintf(name, "%s Playback Volume", chname[i]);
10930                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10931                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10932                                                               HDA_OUTPUT));
10933                         if (err < 0)
10934                                 return err;
10935                         sprintf(name, "%s Playback Switch", chname[i]);
10936                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10937                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10938                                                               HDA_INPUT));
10939                         if (err < 0)
10940                                 return err;
10941                 }
10942         }
10943         return 0;
10944 }
10945
10946 /* add playback controls for speaker and HP outputs */
10947 /* Based on ALC880 version. But ALC861VD has separate,
10948  * different NIDs for mute/unmute switch and volume control */
10949 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10950                                         hda_nid_t pin, const char *pfx)
10951 {
10952         hda_nid_t nid_v, nid_s;
10953         int err;
10954         char name[32];
10955
10956         if (!pin)
10957                 return 0;
10958
10959         if (alc880_is_fixed_pin(pin)) {
10960                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10961                 /* specify the DAC as the extra output */
10962                 if (!spec->multiout.hp_nid)
10963                         spec->multiout.hp_nid = nid_v;
10964                 else
10965                         spec->multiout.extra_out_nid[0] = nid_v;
10966                 /* control HP volume/switch on the output mixer amp */
10967                 nid_v = alc861vd_idx_to_mixer_vol(
10968                                 alc880_fixed_pin_idx(pin));
10969                 nid_s = alc861vd_idx_to_mixer_switch(
10970                                 alc880_fixed_pin_idx(pin));
10971
10972                 sprintf(name, "%s Playback Volume", pfx);
10973                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10974                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10975                 if (err < 0)
10976                         return err;
10977                 sprintf(name, "%s Playback Switch", pfx);
10978                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10979                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10980                 if (err < 0)
10981                         return err;
10982         } else if (alc880_is_multi_pin(pin)) {
10983                 /* set manual connection */
10984                 /* we have only a switch on HP-out PIN */
10985                 sprintf(name, "%s Playback Switch", pfx);
10986                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10987                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10988                 if (err < 0)
10989                         return err;
10990         }
10991         return 0;
10992 }
10993
10994 /* parse the BIOS configuration and set up the alc_spec
10995  * return 1 if successful, 0 if the proper config is not found,
10996  * or a negative error code
10997  * Based on ALC880 version - had to change it to override
10998  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10999 static int alc861vd_parse_auto_config(struct hda_codec *codec)
11000 {
11001         struct alc_spec *spec = codec->spec;
11002         int err;
11003         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
11004
11005         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11006                                            alc861vd_ignore);
11007         if (err < 0)
11008                 return err;
11009         if (!spec->autocfg.line_outs)
11010                 return 0; /* can't find valid BIOS pin config */
11011
11012         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11013         if (err < 0)
11014                 return err;
11015         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
11016         if (err < 0)
11017                 return err;
11018         err = alc861vd_auto_create_extra_out(spec,
11019                                              spec->autocfg.speaker_pins[0],
11020                                              "Speaker");
11021         if (err < 0)
11022                 return err;
11023         err = alc861vd_auto_create_extra_out(spec,
11024                                              spec->autocfg.hp_pins[0],
11025                                              "Headphone");
11026         if (err < 0)
11027                 return err;
11028         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
11029         if (err < 0)
11030                 return err;
11031
11032         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11033
11034         if (spec->autocfg.dig_out_pin)
11035                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
11036
11037         if (spec->kctl_alloc)
11038                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11039
11040         spec->init_verbs[spec->num_init_verbs++]
11041                 = alc861vd_volume_init_verbs;
11042
11043         spec->num_mux_defs = 1;
11044         spec->input_mux = &spec->private_imux;
11045
11046         return 1;
11047 }
11048
11049 /* additional initialization for auto-configuration model */
11050 static void alc861vd_auto_init(struct hda_codec *codec)
11051 {
11052         alc861vd_auto_init_multi_out(codec);
11053         alc861vd_auto_init_hp_out(codec);
11054         alc861vd_auto_init_analog_input(codec);
11055 }
11056
11057 static int patch_alc861vd(struct hda_codec *codec)
11058 {
11059         struct alc_spec *spec;
11060         int err, board_config;
11061
11062         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11063         if (spec == NULL)
11064                 return -ENOMEM;
11065
11066         codec->spec = spec;
11067
11068         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
11069                                                   alc861vd_models,
11070                                                   alc861vd_cfg_tbl);
11071
11072         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
11073                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
11074                         "ALC861VD, trying auto-probe from BIOS...\n");
11075                 board_config = ALC861VD_AUTO;
11076         }
11077
11078         if (board_config == ALC861VD_AUTO) {
11079                 /* automatic parse from the BIOS config */
11080                 err = alc861vd_parse_auto_config(codec);
11081                 if (err < 0) {
11082                         alc_free(codec);
11083                         return err;
11084                 } else if (!err) {
11085                         printk(KERN_INFO
11086                                "hda_codec: Cannot set up configuration "
11087                                "from BIOS.  Using base mode...\n");
11088                         board_config = ALC861VD_3ST;
11089                 }
11090         }
11091
11092         if (board_config != ALC861VD_AUTO)
11093                 setup_preset(spec, &alc861vd_presets[board_config]);
11094
11095         spec->stream_name_analog = "ALC861VD Analog";
11096         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
11097         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
11098
11099         spec->stream_name_digital = "ALC861VD Digital";
11100         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
11101         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
11102
11103         spec->adc_nids = alc861vd_adc_nids;
11104         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
11105
11106         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
11107         spec->num_mixers++;
11108
11109         codec->patch_ops = alc_patch_ops;
11110
11111         if (board_config == ALC861VD_AUTO)
11112                 spec->init_hook = alc861vd_auto_init;
11113 #ifdef CONFIG_SND_HDA_POWER_SAVE
11114         if (!spec->loopback.amplist)
11115                 spec->loopback.amplist = alc861vd_loopbacks;
11116 #endif
11117
11118         return 0;
11119 }
11120
11121 /*
11122  * ALC662 support
11123  *
11124  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
11125  * configuration.  Each pin widget can choose any input DACs and a mixer.
11126  * Each ADC is connected from a mixer of all inputs.  This makes possible
11127  * 6-channel independent captures.
11128  *
11129  * In addition, an independent DAC for the multi-playback (not used in this
11130  * driver yet).
11131  */
11132 #define ALC662_DIGOUT_NID       0x06
11133 #define ALC662_DIGIN_NID        0x0a
11134
11135 static hda_nid_t alc662_dac_nids[4] = {
11136         /* front, rear, clfe, rear_surr */
11137         0x02, 0x03, 0x04
11138 };
11139
11140 static hda_nid_t alc662_adc_nids[1] = {
11141         /* ADC1-2 */
11142         0x09,
11143 };
11144 /* input MUX */
11145 /* FIXME: should be a matrix-type input source selection */
11146
11147 static struct hda_input_mux alc662_capture_source = {
11148         .num_items = 4,
11149         .items = {
11150                 { "Mic", 0x0 },
11151                 { "Front Mic", 0x1 },
11152                 { "Line", 0x2 },
11153                 { "CD", 0x4 },
11154         },
11155 };
11156
11157 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
11158         .num_items = 2,
11159         .items = {
11160                 { "Mic", 0x1 },
11161                 { "Line", 0x2 },
11162         },
11163 };
11164 #define alc662_mux_enum_info alc_mux_enum_info
11165 #define alc662_mux_enum_get alc_mux_enum_get
11166
11167 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
11168                                struct snd_ctl_elem_value *ucontrol)
11169 {
11170         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11171         struct alc_spec *spec = codec->spec;
11172         const struct hda_input_mux *imux = spec->input_mux;
11173         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11174         static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
11175         hda_nid_t nid = capture_mixers[adc_idx];
11176         unsigned int *cur_val = &spec->cur_mux[adc_idx];
11177         unsigned int i, idx;
11178
11179         idx = ucontrol->value.enumerated.item[0];
11180         if (idx >= imux->num_items)
11181                 idx = imux->num_items - 1;
11182         if (*cur_val == idx)
11183                 return 0;
11184         for (i = 0; i < imux->num_items; i++) {
11185                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11186                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11187                                          imux->items[i].index,
11188                                          HDA_AMP_MUTE, v);
11189         }
11190         *cur_val = idx;
11191         return 1;
11192 }
11193 /*
11194  * 2ch mode
11195  */
11196 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
11197         { 2, NULL }
11198 };
11199
11200 /*
11201  * 2ch mode
11202  */
11203 static struct hda_verb alc662_3ST_ch2_init[] = {
11204         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
11205         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11206         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
11207         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11208         { } /* end */
11209 };
11210
11211 /*
11212  * 6ch mode
11213  */
11214 static struct hda_verb alc662_3ST_ch6_init[] = {
11215         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11216         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11217         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
11218         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11219         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11220         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
11221         { } /* end */
11222 };
11223
11224 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
11225         { 2, alc662_3ST_ch2_init },
11226         { 6, alc662_3ST_ch6_init },
11227 };
11228
11229 /*
11230  * 2ch mode
11231  */
11232 static struct hda_verb alc662_sixstack_ch6_init[] = {
11233         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11234         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11235         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11236         { } /* end */
11237 };
11238
11239 /*
11240  * 6ch mode
11241  */
11242 static struct hda_verb alc662_sixstack_ch8_init[] = {
11243         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11244         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11245         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11246         { } /* end */
11247 };
11248
11249 static struct hda_channel_mode alc662_5stack_modes[2] = {
11250         { 2, alc662_sixstack_ch6_init },
11251         { 6, alc662_sixstack_ch8_init },
11252 };
11253
11254 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11255  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11256  */
11257
11258 static struct snd_kcontrol_new alc662_base_mixer[] = {
11259         /* output mixer control */
11260         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11261         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
11262         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11263         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11264         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11265         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11266         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11267         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11268         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11269
11270         /*Input mixer control */
11271         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
11272         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
11273         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
11274         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
11275         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
11276         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
11277         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
11278         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
11279
11280         /* Capture mixer control */
11281         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11282         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11283         {
11284                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11285                 .name = "Capture Source",
11286                 .count = 1,
11287                 .info = alc_mux_enum_info,
11288                 .get = alc_mux_enum_get,
11289                 .put = alc_mux_enum_put,
11290         },
11291         { } /* end */
11292 };
11293
11294 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
11295         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11296         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11297         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11298         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11299         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11300         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11301         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11302         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11303         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11304         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11305         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11306         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11307         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11308         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11309         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11310         {
11311                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11312                 /* .name = "Capture Source", */
11313                 .name = "Input Source",
11314                 .count = 1,
11315                 .info = alc662_mux_enum_info,
11316                 .get = alc662_mux_enum_get,
11317                 .put = alc662_mux_enum_put,
11318         },
11319         { } /* end */
11320 };
11321
11322 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
11323         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11324         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11325         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11326         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
11327         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11328         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11329         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11330         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11331         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11332         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11333         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11334         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11335         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11336         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11337         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11338         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11339         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11340         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11341         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11342         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11343         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11344         {
11345                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11346                 /* .name = "Capture Source", */
11347                 .name = "Input Source",
11348                 .count = 1,
11349                 .info = alc662_mux_enum_info,
11350                 .get = alc662_mux_enum_get,
11351                 .put = alc662_mux_enum_put,
11352         },
11353         { } /* end */
11354 };
11355
11356 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
11357         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11358         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11359         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11360         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
11361         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11362         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11363         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11364         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11365         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11366         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11367         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11368         {
11369                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11370                 /* .name = "Capture Source", */
11371                 .name = "Input Source",
11372                 .count = 1,
11373                 .info = alc662_mux_enum_info,
11374                 .get = alc662_mux_enum_get,
11375                 .put = alc662_mux_enum_put,
11376         },
11377         { } /* end */
11378 };
11379
11380 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11381         {
11382                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11383                 .name = "Channel Mode",
11384                 .info = alc_ch_mode_info,
11385                 .get = alc_ch_mode_get,
11386                 .put = alc_ch_mode_put,
11387         },
11388         { } /* end */
11389 };
11390
11391 static struct hda_verb alc662_init_verbs[] = {
11392         /* ADC: mute amp left and right */
11393         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11394         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11395         /* Front mixer: unmute input/output amp left and right (volume = 0) */
11396
11397         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11398         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11399         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11400         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11401         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11402
11403         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11404         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11405         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11406         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11407         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11408         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11409
11410         /* Front Pin: output 0 (0x0c) */
11411         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11412         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11413
11414         /* Rear Pin: output 1 (0x0d) */
11415         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11416         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11417
11418         /* CLFE Pin: output 2 (0x0e) */
11419         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11420         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11421
11422         /* Mic (rear) pin: input vref at 80% */
11423         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11424         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11425         /* Front Mic pin: input vref at 80% */
11426         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11427         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11428         /* Line In pin: input */
11429         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11430         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11431         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11432         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11433         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11434         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11435         /* CD pin widget for input */
11436         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11437
11438         /* FIXME: use matrix-type input source selection */
11439         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11440         /* Input mixer */
11441         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11442         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11443         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11444         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11445         { }
11446 };
11447
11448 static struct hda_verb alc662_sue_init_verbs[] = {
11449         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11450         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11451         {}
11452 };
11453
11454 /*
11455  * generic initialization of ADC, input mixers and output mixers
11456  */
11457 static struct hda_verb alc662_auto_init_verbs[] = {
11458         /*
11459          * Unmute ADC and set the default input to mic-in
11460          */
11461         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11462         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11463
11464         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11465          * mixer widget
11466          * Note: PASD motherboards uses the Line In 2 as the input for front
11467          * panel mic (mic 2)
11468          */
11469         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11470         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11471         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11472         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11473         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11474         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11475
11476         /*
11477          * Set up output mixers (0x0c - 0x0f)
11478          */
11479         /* set vol=0 to output mixers */
11480         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11481         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11482         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11483
11484         /* set up input amps for analog loopback */
11485         /* Amp Indices: DAC = 0, mixer = 1 */
11486         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11487         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11488         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11489         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11490         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11491         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11492
11493
11494         /* FIXME: use matrix-type input source selection */
11495         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11496         /* Input mixer */
11497         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11498         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11499         { }
11500 };
11501
11502 /* capture mixer elements */
11503 static struct snd_kcontrol_new alc662_capture_mixer[] = {
11504         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11505         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11506         {
11507                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11508                 /* The multiple "Capture Source" controls confuse alsamixer
11509                  * So call somewhat different..
11510                  * FIXME: the controls appear in the "playback" view!
11511                  */
11512                 /* .name = "Capture Source", */
11513                 .name = "Input Source",
11514                 .count = 1,
11515                 .info = alc882_mux_enum_info,
11516                 .get = alc882_mux_enum_get,
11517                 .put = alc882_mux_enum_put,
11518         },
11519         { } /* end */
11520 };
11521
11522 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11523 {
11524         unsigned int present;
11525         unsigned char bits;
11526
11527         present = snd_hda_codec_read(codec, 0x14, 0,
11528                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11529         bits = present ? HDA_AMP_MUTE : 0;
11530         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11531                                  HDA_AMP_MUTE, bits);
11532 }
11533
11534 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11535 {
11536         unsigned int present;
11537         unsigned char bits;
11538
11539         present = snd_hda_codec_read(codec, 0x1b, 0,
11540                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11541         bits = present ? HDA_AMP_MUTE : 0;
11542         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11543                                  HDA_AMP_MUTE, bits);
11544         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11545                                  HDA_AMP_MUTE, bits);
11546 }
11547
11548 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11549                                            unsigned int res)
11550 {
11551         if ((res >> 26) == ALC880_HP_EVENT)
11552                 alc662_lenovo_101e_all_automute(codec);
11553         if ((res >> 26) == ALC880_FRONT_EVENT)
11554                 alc662_lenovo_101e_ispeaker_automute(codec);
11555 }
11556
11557 #ifdef CONFIG_SND_HDA_POWER_SAVE
11558 #define alc662_loopbacks        alc880_loopbacks
11559 #endif
11560
11561
11562 /* pcm configuration: identiacal with ALC880 */
11563 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
11564 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
11565 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
11566 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
11567
11568 /*
11569  * configuration and preset
11570  */
11571 static const char *alc662_models[ALC662_MODEL_LAST] = {
11572         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
11573         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
11574         [ALC662_3ST_6ch]        = "3stack-6ch",
11575         [ALC662_5ST_DIG]        = "6stack-dig",
11576         [ALC662_LENOVO_101E]    = "lenovo-101e",
11577         [ALC662_AUTO]           = "auto",
11578 };
11579
11580 static struct snd_pci_quirk alc662_cfg_tbl[] = {
11581         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11582         {}
11583 };
11584
11585 static struct alc_config_preset alc662_presets[] = {
11586         [ALC662_3ST_2ch_DIG] = {
11587                 .mixers = { alc662_3ST_2ch_mixer },
11588                 .init_verbs = { alc662_init_verbs },
11589                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11590                 .dac_nids = alc662_dac_nids,
11591                 .dig_out_nid = ALC662_DIGOUT_NID,
11592                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11593                 .adc_nids = alc662_adc_nids,
11594                 .dig_in_nid = ALC662_DIGIN_NID,
11595                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11596                 .channel_mode = alc662_3ST_2ch_modes,
11597                 .input_mux = &alc662_capture_source,
11598         },
11599         [ALC662_3ST_6ch_DIG] = {
11600                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11601                 .init_verbs = { alc662_init_verbs },
11602                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11603                 .dac_nids = alc662_dac_nids,
11604                 .dig_out_nid = ALC662_DIGOUT_NID,
11605                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11606                 .adc_nids = alc662_adc_nids,
11607                 .dig_in_nid = ALC662_DIGIN_NID,
11608                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11609                 .channel_mode = alc662_3ST_6ch_modes,
11610                 .need_dac_fix = 1,
11611                 .input_mux = &alc662_capture_source,
11612         },
11613         [ALC662_3ST_6ch] = {
11614                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11615                 .init_verbs = { alc662_init_verbs },
11616                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11617                 .dac_nids = alc662_dac_nids,
11618                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11619                 .adc_nids = alc662_adc_nids,
11620                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11621                 .channel_mode = alc662_3ST_6ch_modes,
11622                 .need_dac_fix = 1,
11623                 .input_mux = &alc662_capture_source,
11624         },
11625         [ALC662_5ST_DIG] = {
11626                 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
11627                 .init_verbs = { alc662_init_verbs },
11628                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11629                 .dac_nids = alc662_dac_nids,
11630                 .dig_out_nid = ALC662_DIGOUT_NID,
11631                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11632                 .adc_nids = alc662_adc_nids,
11633                 .dig_in_nid = ALC662_DIGIN_NID,
11634                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11635                 .channel_mode = alc662_5stack_modes,
11636                 .input_mux = &alc662_capture_source,
11637         },
11638         [ALC662_LENOVO_101E] = {
11639                 .mixers = { alc662_lenovo_101e_mixer },
11640                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11641                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11642                 .dac_nids = alc662_dac_nids,
11643                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11644                 .adc_nids = alc662_adc_nids,
11645                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11646                 .channel_mode = alc662_3ST_2ch_modes,
11647                 .input_mux = &alc662_lenovo_101e_capture_source,
11648                 .unsol_event = alc662_lenovo_101e_unsol_event,
11649                 .init_hook = alc662_lenovo_101e_all_automute,
11650         },
11651
11652 };
11653
11654
11655 /*
11656  * BIOS auto configuration
11657  */
11658
11659 /* add playback controls from the parsed DAC table */
11660 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11661                                              const struct auto_pin_cfg *cfg)
11662 {
11663         char name[32];
11664         static const char *chname[4] = {
11665                 "Front", "Surround", NULL /*CLFE*/, "Side"
11666         };
11667         hda_nid_t nid;
11668         int i, err;
11669
11670         for (i = 0; i < cfg->line_outs; i++) {
11671                 if (!spec->multiout.dac_nids[i])
11672                         continue;
11673                 nid = alc880_idx_to_mixer(i);
11674                 if (i == 2) {
11675                         /* Center/LFE */
11676                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11677                                           "Center Playback Volume",
11678                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11679                                                               HDA_OUTPUT));
11680                         if (err < 0)
11681                                 return err;
11682                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11683                                           "LFE Playback Volume",
11684                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11685                                                               HDA_OUTPUT));
11686                         if (err < 0)
11687                                 return err;
11688                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11689                                           "Center Playback Switch",
11690                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11691                                                               HDA_INPUT));
11692                         if (err < 0)
11693                                 return err;
11694                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11695                                           "LFE Playback Switch",
11696                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11697                                                               HDA_INPUT));
11698                         if (err < 0)
11699                                 return err;
11700                 } else {
11701                         sprintf(name, "%s Playback Volume", chname[i]);
11702                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11703                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11704                                                               HDA_OUTPUT));
11705                         if (err < 0)
11706                                 return err;
11707                         sprintf(name, "%s Playback Switch", chname[i]);
11708                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11709                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11710                                                               HDA_INPUT));
11711                         if (err < 0)
11712                                 return err;
11713                 }
11714         }
11715         return 0;
11716 }
11717
11718 /* add playback controls for speaker and HP outputs */
11719 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11720                                         const char *pfx)
11721 {
11722         hda_nid_t nid;
11723         int err;
11724         char name[32];
11725
11726         if (!pin)
11727                 return 0;
11728
11729         if (alc880_is_fixed_pin(pin)) {
11730                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11731                 /* printk("DAC nid=%x\n",nid); */
11732                 /* specify the DAC as the extra output */
11733                 if (!spec->multiout.hp_nid)
11734                         spec->multiout.hp_nid = nid;
11735                 else
11736                         spec->multiout.extra_out_nid[0] = nid;
11737                 /* control HP volume/switch on the output mixer amp */
11738                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11739                 sprintf(name, "%s Playback Volume", pfx);
11740                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11741                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11742                 if (err < 0)
11743                         return err;
11744                 sprintf(name, "%s Playback Switch", pfx);
11745                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11746                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11747                 if (err < 0)
11748                         return err;
11749         } else if (alc880_is_multi_pin(pin)) {
11750                 /* set manual connection */
11751                 /* we have only a switch on HP-out PIN */
11752                 sprintf(name, "%s Playback Switch", pfx);
11753                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11754                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11755                 if (err < 0)
11756                         return err;
11757         }
11758         return 0;
11759 }
11760
11761 /* create playback/capture controls for input pins */
11762 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11763                                                 const struct auto_pin_cfg *cfg)
11764 {
11765         struct hda_input_mux *imux = &spec->private_imux;
11766         int i, err, idx;
11767
11768         for (i = 0; i < AUTO_PIN_LAST; i++) {
11769                 if (alc880_is_input_pin(cfg->input_pins[i])) {
11770                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
11771                         err = new_analog_input(spec, cfg->input_pins[i],
11772                                                auto_pin_cfg_labels[i],
11773                                                idx, 0x0b);
11774                         if (err < 0)
11775                                 return err;
11776                         imux->items[imux->num_items].label =
11777                                 auto_pin_cfg_labels[i];
11778                         imux->items[imux->num_items].index =
11779                                 alc880_input_pin_idx(cfg->input_pins[i]);
11780                         imux->num_items++;
11781                 }
11782         }
11783         return 0;
11784 }
11785
11786 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11787                                               hda_nid_t nid, int pin_type,
11788                                               int dac_idx)
11789 {
11790         /* set as output */
11791         snd_hda_codec_write(codec, nid, 0,
11792                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11793         snd_hda_codec_write(codec, nid, 0,
11794                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11795         /* need the manual connection? */
11796         if (alc880_is_multi_pin(nid)) {
11797                 struct alc_spec *spec = codec->spec;
11798                 int idx = alc880_multi_pin_idx(nid);
11799                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11800                                     AC_VERB_SET_CONNECT_SEL,
11801                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11802         }
11803 }
11804
11805 static void alc662_auto_init_multi_out(struct hda_codec *codec)
11806 {
11807         struct alc_spec *spec = codec->spec;
11808         int i;
11809
11810         for (i = 0; i <= HDA_SIDE; i++) {
11811                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11812                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11813                 if (nid)
11814                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11815                                                           i);
11816         }
11817 }
11818
11819 static void alc662_auto_init_hp_out(struct hda_codec *codec)
11820 {
11821         struct alc_spec *spec = codec->spec;
11822         hda_nid_t pin;
11823
11824         pin = spec->autocfg.hp_pins[0];
11825         if (pin) /* connect to front */
11826                 /* use dac 0 */
11827                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11828 }
11829
11830 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
11831 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
11832
11833 static void alc662_auto_init_analog_input(struct hda_codec *codec)
11834 {
11835         struct alc_spec *spec = codec->spec;
11836         int i;
11837
11838         for (i = 0; i < AUTO_PIN_LAST; i++) {
11839                 hda_nid_t nid = spec->autocfg.input_pins[i];
11840                 if (alc662_is_input_pin(nid)) {
11841                         snd_hda_codec_write(codec, nid, 0,
11842                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
11843                                             (i <= AUTO_PIN_FRONT_MIC ?
11844                                              PIN_VREF80 : PIN_IN));
11845                         if (nid != ALC662_PIN_CD_NID)
11846                                 snd_hda_codec_write(codec, nid, 0,
11847                                                     AC_VERB_SET_AMP_GAIN_MUTE,
11848                                                     AMP_OUT_MUTE);
11849                 }
11850         }
11851 }
11852
11853 static int alc662_parse_auto_config(struct hda_codec *codec)
11854 {
11855         struct alc_spec *spec = codec->spec;
11856         int err;
11857         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11858
11859         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11860                                            alc662_ignore);
11861         if (err < 0)
11862                 return err;
11863         if (!spec->autocfg.line_outs)
11864                 return 0; /* can't find valid BIOS pin config */
11865
11866         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11867         if (err < 0)
11868                 return err;
11869         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11870         if (err < 0)
11871                 return err;
11872         err = alc662_auto_create_extra_out(spec,
11873                                            spec->autocfg.speaker_pins[0],
11874                                            "Speaker");
11875         if (err < 0)
11876                 return err;
11877         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11878                                            "Headphone");
11879         if (err < 0)
11880                 return err;
11881         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11882         if (err < 0)
11883                 return err;
11884
11885         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11886
11887         if (spec->autocfg.dig_out_pin)
11888                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11889
11890         if (spec->kctl_alloc)
11891                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11892
11893         spec->num_mux_defs = 1;
11894         spec->input_mux = &spec->private_imux;
11895         
11896         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11897         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11898         spec->num_mixers++;
11899         return 1;
11900 }
11901
11902 /* additional initialization for auto-configuration model */
11903 static void alc662_auto_init(struct hda_codec *codec)
11904 {
11905         alc662_auto_init_multi_out(codec);
11906         alc662_auto_init_hp_out(codec);
11907         alc662_auto_init_analog_input(codec);
11908 }
11909
11910 static int patch_alc662(struct hda_codec *codec)
11911 {
11912         struct alc_spec *spec;
11913         int err, board_config;
11914
11915         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11916         if (!spec)
11917                 return -ENOMEM;
11918
11919         codec->spec = spec;
11920
11921         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11922                                                   alc662_models,
11923                                                   alc662_cfg_tbl);
11924         if (board_config < 0) {
11925                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11926                        "trying auto-probe from BIOS...\n");
11927                 board_config = ALC662_AUTO;
11928         }
11929
11930         if (board_config == ALC662_AUTO) {
11931                 /* automatic parse from the BIOS config */
11932                 err = alc662_parse_auto_config(codec);
11933                 if (err < 0) {
11934                         alc_free(codec);
11935                         return err;
11936                 } else if (!err) {
11937                         printk(KERN_INFO
11938                                "hda_codec: Cannot set up configuration "
11939                                "from BIOS.  Using base mode...\n");
11940                         board_config = ALC662_3ST_2ch_DIG;
11941                 }
11942         }
11943
11944         if (board_config != ALC662_AUTO)
11945                 setup_preset(spec, &alc662_presets[board_config]);
11946
11947         spec->stream_name_analog = "ALC662 Analog";
11948         spec->stream_analog_playback = &alc662_pcm_analog_playback;
11949         spec->stream_analog_capture = &alc662_pcm_analog_capture;
11950
11951         spec->stream_name_digital = "ALC662 Digital";
11952         spec->stream_digital_playback = &alc662_pcm_digital_playback;
11953         spec->stream_digital_capture = &alc662_pcm_digital_capture;
11954
11955         if (!spec->adc_nids && spec->input_mux) {
11956                 spec->adc_nids = alc662_adc_nids;
11957                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11958         }
11959
11960         codec->patch_ops = alc_patch_ops;
11961         if (board_config == ALC662_AUTO)
11962                 spec->init_hook = alc662_auto_init;
11963 #ifdef CONFIG_SND_HDA_POWER_SAVE
11964         if (!spec->loopback.amplist)
11965                 spec->loopback.amplist = alc662_loopbacks;
11966 #endif
11967
11968         return 0;
11969 }
11970
11971 /*
11972  * patch entries
11973  */
11974 struct hda_codec_preset snd_hda_preset_realtek[] = {
11975         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11976         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11977         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11978         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11979           .patch = patch_alc861 },
11980         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11981         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11982         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11983         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11984           .patch = patch_alc883 },
11985         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11986           .patch = patch_alc662 },
11987         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11988         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11989         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11990         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11991         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11992         {} /* terminator */
11993 };