[ALSA] hda-codec - Remove conflicting capture mixers for ALC861VD
[linux-2.6] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_BENQ_ED8,
96         ALC262_SONY_ASSAMD,
97         ALC262_BENQ_T31,
98         ALC262_AUTO,
99         ALC262_MODEL_LAST /* last tag */
100 };
101
102 /* ALC268 models */
103 enum {
104         ALC268_3ST,
105         ALC268_AUTO,
106         ALC268_MODEL_LAST /* last tag */
107 };
108
109 /* ALC861 models */
110 enum {
111         ALC861_3ST,
112         ALC660_3ST,
113         ALC861_3ST_DIG,
114         ALC861_6ST_DIG,
115         ALC861_UNIWILL_M31,
116         ALC861_TOSHIBA,
117         ALC861_ASUS,
118         ALC861_ASUS_LAPTOP,
119         ALC861_AUTO,
120         ALC861_MODEL_LAST,
121 };
122
123 /* ALC861-VD models */
124 enum {
125         ALC660VD_3ST,
126         ALC660VD_3ST_DIG,
127         ALC861VD_3ST,
128         ALC861VD_3ST_DIG,
129         ALC861VD_6ST_DIG,
130         ALC861VD_LENOVO,
131         ALC861VD_DALLAS,
132         ALC861VD_AUTO,
133         ALC861VD_MODEL_LAST,
134 };
135
136 /* ALC662 models */
137 enum {
138         ALC662_3ST_2ch_DIG,
139         ALC662_3ST_6ch_DIG,
140         ALC662_3ST_6ch,
141         ALC662_5ST_DIG,
142         ALC662_LENOVO_101E,
143         ALC662_AUTO,
144         ALC662_MODEL_LAST,
145 };
146
147 /* ALC882 models */
148 enum {
149         ALC882_3ST_DIG,
150         ALC882_6ST_DIG,
151         ALC882_ARIMA,
152         ALC882_W2JC,
153         ALC882_TARGA,
154         ALC882_ASUS_A7J,
155         ALC885_MACPRO,
156         ALC885_IMAC24,
157         ALC882_AUTO,
158         ALC882_MODEL_LAST,
159 };
160
161 /* ALC883 models */
162 enum {
163         ALC883_3ST_2ch_DIG,
164         ALC883_3ST_6ch_DIG,
165         ALC883_3ST_6ch,
166         ALC883_6ST_DIG,
167         ALC883_TARGA_DIG,
168         ALC883_TARGA_2ch_DIG,
169         ALC883_ACER,
170         ALC883_ACER_ASPIRE,
171         ALC883_MEDION,
172         ALC883_MEDION_MD2,      
173         ALC883_LAPTOP_EAPD,
174         ALC883_LENOVO_101E_2ch,
175         ALC883_LENOVO_NB0763,
176         ALC888_LENOVO_MS7195_DIG,               
177         ALC888_6ST_HP,
178         ALC888_3ST_HP,
179         ALC883_AUTO,
180         ALC883_MODEL_LAST,
181 };
182
183 /* for GPIO Poll */
184 #define GPIO_MASK       0x03
185
186 struct alc_spec {
187         /* codec parameterization */
188         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
189         unsigned int num_mixers;
190
191         const struct hda_verb *init_verbs[5];   /* initialization verbs
192                                                  * don't forget NULL
193                                                  * termination!
194                                                  */
195         unsigned int num_init_verbs;
196
197         char *stream_name_analog;       /* analog PCM stream */
198         struct hda_pcm_stream *stream_analog_playback;
199         struct hda_pcm_stream *stream_analog_capture;
200
201         char *stream_name_digital;      /* digital PCM stream */
202         struct hda_pcm_stream *stream_digital_playback;
203         struct hda_pcm_stream *stream_digital_capture;
204
205         /* playback */
206         struct hda_multi_out multiout;  /* playback set-up
207                                          * max_channels, dacs must be set
208                                          * dig_out_nid and hp_nid are optional
209                                          */
210
211         /* capture */
212         unsigned int num_adc_nids;
213         hda_nid_t *adc_nids;
214         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
215
216         /* capture source */
217         unsigned int num_mux_defs;
218         const struct hda_input_mux *input_mux;
219         unsigned int cur_mux[3];
220
221         /* channel model */
222         const struct hda_channel_mode *channel_mode;
223         int num_channel_mode;
224         int need_dac_fix;
225
226         /* PCM information */
227         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
228
229         /* dynamic controls, init_verbs and input_mux */
230         struct auto_pin_cfg autocfg;
231         unsigned int num_kctl_alloc, num_kctl_used;
232         struct snd_kcontrol_new *kctl_alloc;
233         struct hda_input_mux private_imux;
234         hda_nid_t private_dac_nids[5];
235
236         /* hooks */
237         void (*init_hook)(struct hda_codec *codec);
238         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
239
240         /* for pin sensing */
241         unsigned int sense_updated: 1;
242         unsigned int jack_present: 1;
243
244 #ifdef CONFIG_SND_HDA_POWER_SAVE
245         struct hda_loopback_check loopback;
246 #endif
247 };
248
249 /*
250  * configuration template - to be copied to the spec instance
251  */
252 struct alc_config_preset {
253         struct snd_kcontrol_new *mixers[5]; /* should be identical size
254                                              * with spec
255                                              */
256         const struct hda_verb *init_verbs[5];
257         unsigned int num_dacs;
258         hda_nid_t *dac_nids;
259         hda_nid_t dig_out_nid;          /* optional */
260         hda_nid_t hp_nid;               /* optional */
261         unsigned int num_adc_nids;
262         hda_nid_t *adc_nids;
263         hda_nid_t dig_in_nid;
264         unsigned int num_channel_mode;
265         const struct hda_channel_mode *channel_mode;
266         int need_dac_fix;
267         unsigned int num_mux_defs;
268         const struct hda_input_mux *input_mux;
269         void (*unsol_event)(struct hda_codec *, unsigned int);
270         void (*init_hook)(struct hda_codec *);
271 #ifdef CONFIG_SND_HDA_POWER_SAVE
272         struct hda_amp_list *loopbacks;
273 #endif
274 };
275
276
277 /*
278  * input MUX handling
279  */
280 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
281                              struct snd_ctl_elem_info *uinfo)
282 {
283         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
284         struct alc_spec *spec = codec->spec;
285         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
286         if (mux_idx >= spec->num_mux_defs)
287                 mux_idx = 0;
288         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
289 }
290
291 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
292                             struct snd_ctl_elem_value *ucontrol)
293 {
294         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
295         struct alc_spec *spec = codec->spec;
296         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
297
298         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
299         return 0;
300 }
301
302 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
303                             struct snd_ctl_elem_value *ucontrol)
304 {
305         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
306         struct alc_spec *spec = codec->spec;
307         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
308         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
309         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
310                                      spec->adc_nids[adc_idx],
311                                      &spec->cur_mux[adc_idx]);
312 }
313
314
315 /*
316  * channel mode setting
317  */
318 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
319                             struct snd_ctl_elem_info *uinfo)
320 {
321         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
322         struct alc_spec *spec = codec->spec;
323         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
324                                     spec->num_channel_mode);
325 }
326
327 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
328                            struct snd_ctl_elem_value *ucontrol)
329 {
330         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
331         struct alc_spec *spec = codec->spec;
332         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
333                                    spec->num_channel_mode,
334                                    spec->multiout.max_channels);
335 }
336
337 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
338                            struct snd_ctl_elem_value *ucontrol)
339 {
340         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
341         struct alc_spec *spec = codec->spec;
342         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
343                                       spec->num_channel_mode,
344                                       &spec->multiout.max_channels);
345         if (err >= 0 && spec->need_dac_fix)
346                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
347         return err;
348 }
349
350 /*
351  * Control the mode of pin widget settings via the mixer.  "pc" is used
352  * instead of "%" to avoid consequences of accidently treating the % as 
353  * being part of a format specifier.  Maximum allowed length of a value is
354  * 63 characters plus NULL terminator.
355  *
356  * Note: some retasking pin complexes seem to ignore requests for input
357  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
358  * are requested.  Therefore order this list so that this behaviour will not
359  * cause problems when mixer clients move through the enum sequentially.
360  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
361  * March 2006.
362  */
363 static char *alc_pin_mode_names[] = {
364         "Mic 50pc bias", "Mic 80pc bias",
365         "Line in", "Line out", "Headphone out",
366 };
367 static unsigned char alc_pin_mode_values[] = {
368         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
369 };
370 /* The control can present all 5 options, or it can limit the options based
371  * in the pin being assumed to be exclusively an input or an output pin.  In
372  * addition, "input" pins may or may not process the mic bias option
373  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
374  * accept requests for bias as of chip versions up to March 2006) and/or
375  * wiring in the computer.
376  */
377 #define ALC_PIN_DIR_IN              0x00
378 #define ALC_PIN_DIR_OUT             0x01
379 #define ALC_PIN_DIR_INOUT           0x02
380 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
381 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
382
383 /* Info about the pin modes supported by the different pin direction modes. 
384  * For each direction the minimum and maximum values are given.
385  */
386 static signed char alc_pin_mode_dir_info[5][2] = {
387         { 0, 2 },    /* ALC_PIN_DIR_IN */
388         { 3, 4 },    /* ALC_PIN_DIR_OUT */
389         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
390         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
391         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
392 };
393 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
394 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
395 #define alc_pin_mode_n_items(_dir) \
396         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
397
398 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
399                              struct snd_ctl_elem_info *uinfo)
400 {
401         unsigned int item_num = uinfo->value.enumerated.item;
402         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
403
404         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
405         uinfo->count = 1;
406         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
407
408         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
409                 item_num = alc_pin_mode_min(dir);
410         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
411         return 0;
412 }
413
414 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
415                             struct snd_ctl_elem_value *ucontrol)
416 {
417         unsigned int i;
418         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
419         hda_nid_t nid = kcontrol->private_value & 0xffff;
420         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
421         long *valp = ucontrol->value.integer.value;
422         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
423                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
424                                                  0x00);
425
426         /* Find enumerated value for current pinctl setting */
427         i = alc_pin_mode_min(dir);
428         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
429                 i++;
430         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
431         return 0;
432 }
433
434 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
435                             struct snd_ctl_elem_value *ucontrol)
436 {
437         signed int change;
438         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
439         hda_nid_t nid = kcontrol->private_value & 0xffff;
440         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
441         long val = *ucontrol->value.integer.value;
442         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
443                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
444                                                  0x00);
445
446         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
447                 val = alc_pin_mode_min(dir);
448
449         change = pinctl != alc_pin_mode_values[val];
450         if (change) {
451                 /* Set pin mode to that requested */
452                 snd_hda_codec_write_cache(codec, nid, 0,
453                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
454                                           alc_pin_mode_values[val]);
455
456                 /* Also enable the retasking pin's input/output as required 
457                  * for the requested pin mode.  Enum values of 2 or less are
458                  * input modes.
459                  *
460                  * Dynamically switching the input/output buffers probably
461                  * reduces noise slightly (particularly on input) so we'll
462                  * do it.  However, having both input and output buffers
463                  * enabled simultaneously doesn't seem to be problematic if
464                  * this turns out to be necessary in the future.
465                  */
466                 if (val <= 2) {
467                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
468                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
469                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
470                                                  HDA_AMP_MUTE, 0);
471                 } else {
472                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
473                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
474                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
475                                                  HDA_AMP_MUTE, 0);
476                 }
477         }
478         return change;
479 }
480
481 #define ALC_PIN_MODE(xname, nid, dir) \
482         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
483           .info = alc_pin_mode_info, \
484           .get = alc_pin_mode_get, \
485           .put = alc_pin_mode_put, \
486           .private_value = nid | (dir<<16) }
487
488 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
489  * together using a mask with more than one bit set.  This control is
490  * currently used only by the ALC260 test model.  At this stage they are not
491  * needed for any "production" models.
492  */
493 #ifdef CONFIG_SND_DEBUG
494 #define alc_gpio_data_info      snd_ctl_boolean_mono_info
495
496 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
497                              struct snd_ctl_elem_value *ucontrol)
498 {
499         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500         hda_nid_t nid = kcontrol->private_value & 0xffff;
501         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
502         long *valp = ucontrol->value.integer.value;
503         unsigned int val = snd_hda_codec_read(codec, nid, 0,
504                                               AC_VERB_GET_GPIO_DATA, 0x00);
505
506         *valp = (val & mask) != 0;
507         return 0;
508 }
509 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
510                              struct snd_ctl_elem_value *ucontrol)
511 {
512         signed int change;
513         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
514         hda_nid_t nid = kcontrol->private_value & 0xffff;
515         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
516         long val = *ucontrol->value.integer.value;
517         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
518                                                     AC_VERB_GET_GPIO_DATA,
519                                                     0x00);
520
521         /* Set/unset the masked GPIO bit(s) as needed */
522         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
523         if (val == 0)
524                 gpio_data &= ~mask;
525         else
526                 gpio_data |= mask;
527         snd_hda_codec_write_cache(codec, nid, 0,
528                                   AC_VERB_SET_GPIO_DATA, gpio_data);
529
530         return change;
531 }
532 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
533         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
534           .info = alc_gpio_data_info, \
535           .get = alc_gpio_data_get, \
536           .put = alc_gpio_data_put, \
537           .private_value = nid | (mask<<16) }
538 #endif   /* CONFIG_SND_DEBUG */
539
540 /* A switch control to allow the enabling of the digital IO pins on the
541  * ALC260.  This is incredibly simplistic; the intention of this control is
542  * to provide something in the test model allowing digital outputs to be
543  * identified if present.  If models are found which can utilise these
544  * outputs a more complete mixer control can be devised for those models if
545  * necessary.
546  */
547 #ifdef CONFIG_SND_DEBUG
548 #define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
549
550 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
551                               struct snd_ctl_elem_value *ucontrol)
552 {
553         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
554         hda_nid_t nid = kcontrol->private_value & 0xffff;
555         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
556         long *valp = ucontrol->value.integer.value;
557         unsigned int val = snd_hda_codec_read(codec, nid, 0,
558                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
559
560         *valp = (val & mask) != 0;
561         return 0;
562 }
563 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
564                               struct snd_ctl_elem_value *ucontrol)
565 {
566         signed int change;
567         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
568         hda_nid_t nid = kcontrol->private_value & 0xffff;
569         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
570         long val = *ucontrol->value.integer.value;
571         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
572                                                     AC_VERB_GET_DIGI_CONVERT,
573                                                     0x00);
574
575         /* Set/unset the masked control bit(s) as needed */
576         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
577         if (val==0)
578                 ctrl_data &= ~mask;
579         else
580                 ctrl_data |= mask;
581         snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
582                                   ctrl_data);
583
584         return change;
585 }
586 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
587         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
588           .info = alc_spdif_ctrl_info, \
589           .get = alc_spdif_ctrl_get, \
590           .put = alc_spdif_ctrl_put, \
591           .private_value = nid | (mask<<16) }
592 #endif   /* CONFIG_SND_DEBUG */
593
594 /*
595  * set up from the preset table
596  */
597 static void setup_preset(struct alc_spec *spec,
598                          const struct alc_config_preset *preset)
599 {
600         int i;
601
602         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
603                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
604         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
605              i++)
606                 spec->init_verbs[spec->num_init_verbs++] =
607                         preset->init_verbs[i];
608         
609         spec->channel_mode = preset->channel_mode;
610         spec->num_channel_mode = preset->num_channel_mode;
611         spec->need_dac_fix = preset->need_dac_fix;
612
613         spec->multiout.max_channels = spec->channel_mode[0].channels;
614
615         spec->multiout.num_dacs = preset->num_dacs;
616         spec->multiout.dac_nids = preset->dac_nids;
617         spec->multiout.dig_out_nid = preset->dig_out_nid;
618         spec->multiout.hp_nid = preset->hp_nid;
619         
620         spec->num_mux_defs = preset->num_mux_defs;
621         if (!spec->num_mux_defs)
622                 spec->num_mux_defs = 1;
623         spec->input_mux = preset->input_mux;
624
625         spec->num_adc_nids = preset->num_adc_nids;
626         spec->adc_nids = preset->adc_nids;
627         spec->dig_in_nid = preset->dig_in_nid;
628
629         spec->unsol_event = preset->unsol_event;
630         spec->init_hook = preset->init_hook;
631 #ifdef CONFIG_SND_HDA_POWER_SAVE
632         spec->loopback.amplist = preset->loopbacks;
633 #endif
634 }
635
636 /* Enable GPIO mask and set output */
637 static struct hda_verb alc_gpio1_init_verbs[] = {
638         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
639         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
640         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
641         { }
642 };
643
644 static struct hda_verb alc_gpio2_init_verbs[] = {
645         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
646         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
647         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
648         { }
649 };
650
651 static struct hda_verb alc_gpio3_init_verbs[] = {
652         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
653         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
654         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
655         { }
656 };
657
658 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
659  *      31 ~ 16 :       Manufacture ID
660  *      15 ~ 8  :       SKU ID
661  *      7  ~ 0  :       Assembly ID
662  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
663  */
664 static void alc_subsystem_id(struct hda_codec *codec,
665                              unsigned int porta, unsigned int porte,
666                              unsigned int portd)
667 {
668         unsigned int ass, tmp;
669
670         ass = codec->subsystem_id;
671         if (!(ass & 1))
672                 return;
673
674         /* Override */
675         tmp = (ass & 0x38) >> 3;        /* external Amp control */
676         switch (tmp) {
677         case 1:
678                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
679                 break;
680         case 3:
681                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
682                 break;
683         case 7:
684                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
685                 break;
686         case 5:
687                 switch (codec->vendor_id) {
688                 case 0x10ec0862:
689                 case 0x10ec0660:
690                 case 0x10ec0662:        
691                 case 0x10ec0267:
692                 case 0x10ec0268:
693                         snd_hda_codec_write(codec, 0x14, 0,
694                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
695                         snd_hda_codec_write(codec, 0x15, 0,
696                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
697                         return;
698                 }
699         case 6:
700                 if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
701                         hda_nid_t port = 0;
702                         tmp = (ass & 0x1800) >> 11;
703                         switch (tmp) {
704                         case 0: port = porta; break;
705                         case 1: port = porte; break;
706                         case 2: port = portd; break;
707                         }
708                         if (port)
709                                 snd_hda_codec_write(codec, port, 0,
710                                                     AC_VERB_SET_EAPD_BTLENABLE,
711                                                     2);
712                 }
713                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
714                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
715                                     (tmp == 5 ? 0x3040 : 0x3050));
716                 break;
717         }
718 }
719
720 /*
721  * Fix-up pin default configurations
722  */
723
724 struct alc_pincfg {
725         hda_nid_t nid;
726         u32 val;
727 };
728
729 static void alc_fix_pincfg(struct hda_codec *codec,
730                            const struct snd_pci_quirk *quirk,
731                            const struct alc_pincfg **pinfix)
732 {
733         const struct alc_pincfg *cfg;
734
735         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
736         if (!quirk)
737                 return;
738
739         cfg = pinfix[quirk->value];
740         for (; cfg->nid; cfg++) {
741                 int i;
742                 u32 val = cfg->val;
743                 for (i = 0; i < 4; i++) {
744                         snd_hda_codec_write(codec, cfg->nid, 0,
745                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
746                                     val & 0xff);
747                         val >>= 8;
748                 }
749         }
750 }
751
752 /*
753  * ALC880 3-stack model
754  *
755  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
756  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
757  *                 F-Mic = 0x1b, HP = 0x19
758  */
759
760 static hda_nid_t alc880_dac_nids[4] = {
761         /* front, rear, clfe, rear_surr */
762         0x02, 0x05, 0x04, 0x03
763 };
764
765 static hda_nid_t alc880_adc_nids[3] = {
766         /* ADC0-2 */
767         0x07, 0x08, 0x09,
768 };
769
770 /* The datasheet says the node 0x07 is connected from inputs,
771  * but it shows zero connection in the real implementation on some devices.
772  * Note: this is a 915GAV bug, fixed on 915GLV
773  */
774 static hda_nid_t alc880_adc_nids_alt[2] = {
775         /* ADC1-2 */
776         0x08, 0x09,
777 };
778
779 #define ALC880_DIGOUT_NID       0x06
780 #define ALC880_DIGIN_NID        0x0a
781
782 static struct hda_input_mux alc880_capture_source = {
783         .num_items = 4,
784         .items = {
785                 { "Mic", 0x0 },
786                 { "Front Mic", 0x3 },
787                 { "Line", 0x2 },
788                 { "CD", 0x4 },
789         },
790 };
791
792 /* channel source setting (2/6 channel selection for 3-stack) */
793 /* 2ch mode */
794 static struct hda_verb alc880_threestack_ch2_init[] = {
795         /* set line-in to input, mute it */
796         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
797         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
798         /* set mic-in to input vref 80%, mute it */
799         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
800         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
801         { } /* end */
802 };
803
804 /* 6ch mode */
805 static struct hda_verb alc880_threestack_ch6_init[] = {
806         /* set line-in to output, unmute it */
807         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
808         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
809         /* set mic-in to output, unmute it */
810         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
811         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
812         { } /* end */
813 };
814
815 static struct hda_channel_mode alc880_threestack_modes[2] = {
816         { 2, alc880_threestack_ch2_init },
817         { 6, alc880_threestack_ch6_init },
818 };
819
820 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
821         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
822         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
823         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
824         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
825         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
826         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
827         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
828         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
829         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
830         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
831         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
832         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
833         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
834         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
835         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
836         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
837         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
838         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
839         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
840         {
841                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
842                 .name = "Channel Mode",
843                 .info = alc_ch_mode_info,
844                 .get = alc_ch_mode_get,
845                 .put = alc_ch_mode_put,
846         },
847         { } /* end */
848 };
849
850 /* capture mixer elements */
851 static struct snd_kcontrol_new alc880_capture_mixer[] = {
852         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
853         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
854         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
855         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
856         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
857         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
858         {
859                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
860                 /* The multiple "Capture Source" controls confuse alsamixer
861                  * So call somewhat different..
862                  * FIXME: the controls appear in the "playback" view!
863                  */
864                 /* .name = "Capture Source", */
865                 .name = "Input Source",
866                 .count = 3,
867                 .info = alc_mux_enum_info,
868                 .get = alc_mux_enum_get,
869                 .put = alc_mux_enum_put,
870         },
871         { } /* end */
872 };
873
874 /* capture mixer elements (in case NID 0x07 not available) */
875 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
876         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
877         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
878         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
879         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
880         {
881                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
882                 /* The multiple "Capture Source" controls confuse alsamixer
883                  * So call somewhat different..
884                  * FIXME: the controls appear in the "playback" view!
885                  */
886                 /* .name = "Capture Source", */
887                 .name = "Input Source",
888                 .count = 2,
889                 .info = alc_mux_enum_info,
890                 .get = alc_mux_enum_get,
891                 .put = alc_mux_enum_put,
892         },
893         { } /* end */
894 };
895
896
897
898 /*
899  * ALC880 5-stack model
900  *
901  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
902  *      Side = 0x02 (0xd)
903  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
904  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
905  */
906
907 /* additional mixers to alc880_three_stack_mixer */
908 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
909         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
910         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
911         { } /* end */
912 };
913
914 /* channel source setting (6/8 channel selection for 5-stack) */
915 /* 6ch mode */
916 static struct hda_verb alc880_fivestack_ch6_init[] = {
917         /* set line-in to input, mute it */
918         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
919         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
920         { } /* end */
921 };
922
923 /* 8ch mode */
924 static struct hda_verb alc880_fivestack_ch8_init[] = {
925         /* set line-in to output, unmute it */
926         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
927         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
928         { } /* end */
929 };
930
931 static struct hda_channel_mode alc880_fivestack_modes[2] = {
932         { 6, alc880_fivestack_ch6_init },
933         { 8, alc880_fivestack_ch8_init },
934 };
935
936
937 /*
938  * ALC880 6-stack model
939  *
940  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
941  *      Side = 0x05 (0x0f)
942  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
943  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
944  */
945
946 static hda_nid_t alc880_6st_dac_nids[4] = {
947         /* front, rear, clfe, rear_surr */
948         0x02, 0x03, 0x04, 0x05
949 };
950
951 static struct hda_input_mux alc880_6stack_capture_source = {
952         .num_items = 4,
953         .items = {
954                 { "Mic", 0x0 },
955                 { "Front Mic", 0x1 },
956                 { "Line", 0x2 },
957                 { "CD", 0x4 },
958         },
959 };
960
961 /* fixed 8-channels */
962 static struct hda_channel_mode alc880_sixstack_modes[1] = {
963         { 8, NULL },
964 };
965
966 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
967         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
968         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
969         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
970         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
971         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
972         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
973         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
974         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
975         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
976         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
977         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
978         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
979         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
980         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
981         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
982         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
983         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
984         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
985         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
986         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
987         {
988                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
989                 .name = "Channel Mode",
990                 .info = alc_ch_mode_info,
991                 .get = alc_ch_mode_get,
992                 .put = alc_ch_mode_put,
993         },
994         { } /* end */
995 };
996
997
998 /*
999  * ALC880 W810 model
1000  *
1001  * W810 has rear IO for:
1002  * Front (DAC 02)
1003  * Surround (DAC 03)
1004  * Center/LFE (DAC 04)
1005  * Digital out (06)
1006  *
1007  * The system also has a pair of internal speakers, and a headphone jack.
1008  * These are both connected to Line2 on the codec, hence to DAC 02.
1009  * 
1010  * There is a variable resistor to control the speaker or headphone
1011  * volume. This is a hardware-only device without a software API.
1012  *
1013  * Plugging headphones in will disable the internal speakers. This is
1014  * implemented in hardware, not via the driver using jack sense. In
1015  * a similar fashion, plugging into the rear socket marked "front" will
1016  * disable both the speakers and headphones.
1017  *
1018  * For input, there's a microphone jack, and an "audio in" jack.
1019  * These may not do anything useful with this driver yet, because I
1020  * haven't setup any initialization verbs for these yet...
1021  */
1022
1023 static hda_nid_t alc880_w810_dac_nids[3] = {
1024         /* front, rear/surround, clfe */
1025         0x02, 0x03, 0x04
1026 };
1027
1028 /* fixed 6 channels */
1029 static struct hda_channel_mode alc880_w810_modes[1] = {
1030         { 6, NULL }
1031 };
1032
1033 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1034 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1035         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1036         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1037         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1038         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1039         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1040         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1041         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1042         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1043         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1044         { } /* end */
1045 };
1046
1047
1048 /*
1049  * Z710V model
1050  *
1051  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1052  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1053  *                 Line = 0x1a
1054  */
1055
1056 static hda_nid_t alc880_z71v_dac_nids[1] = {
1057         0x02
1058 };
1059 #define ALC880_Z71V_HP_DAC      0x03
1060
1061 /* fixed 2 channels */
1062 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1063         { 2, NULL }
1064 };
1065
1066 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1067         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1068         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1069         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1070         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1071         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1072         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1073         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1074         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1075         { } /* end */
1076 };
1077
1078
1079 /* FIXME! */
1080 /*
1081  * ALC880 F1734 model
1082  *
1083  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1084  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1085  */
1086
1087 static hda_nid_t alc880_f1734_dac_nids[1] = {
1088         0x03
1089 };
1090 #define ALC880_F1734_HP_DAC     0x02
1091
1092 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1093         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1094         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1095         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1096         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1097         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1098         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1099         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1100         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1101         { } /* end */
1102 };
1103
1104
1105 /* FIXME! */
1106 /*
1107  * ALC880 ASUS model
1108  *
1109  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1110  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1111  *  Mic = 0x18, Line = 0x1a
1112  */
1113
1114 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1115 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1116
1117 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1118         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1119         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1120         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1121         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1122         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1123         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1124         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1125         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1126         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1127         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1128         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1129         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1130         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1131         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1132         {
1133                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1134                 .name = "Channel Mode",
1135                 .info = alc_ch_mode_info,
1136                 .get = alc_ch_mode_get,
1137                 .put = alc_ch_mode_put,
1138         },
1139         { } /* end */
1140 };
1141
1142 /* FIXME! */
1143 /*
1144  * ALC880 ASUS W1V model
1145  *
1146  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1147  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1148  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1149  */
1150
1151 /* additional mixers to alc880_asus_mixer */
1152 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1153         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1154         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1155         { } /* end */
1156 };
1157
1158 /* additional mixers to alc880_asus_mixer */
1159 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1160         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1161         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1162         { } /* end */
1163 };
1164
1165 /* TCL S700 */
1166 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1167         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1168         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1169         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1170         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1171         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1172         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1173         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1174         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1175         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1176         {
1177                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1178                 /* The multiple "Capture Source" controls confuse alsamixer
1179                  * So call somewhat different..
1180                  * FIXME: the controls appear in the "playback" view!
1181                  */
1182                 /* .name = "Capture Source", */
1183                 .name = "Input Source",
1184                 .count = 1,
1185                 .info = alc_mux_enum_info,
1186                 .get = alc_mux_enum_get,
1187                 .put = alc_mux_enum_put,
1188         },
1189         { } /* end */
1190 };
1191
1192 /* Uniwill */
1193 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1194         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1195         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1196         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1197         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1198         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1199         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1200         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1201         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1202         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1203         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1204         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1205         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1206         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1207         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1208         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1209         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1210         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1211         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1212         {
1213                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1214                 .name = "Channel Mode",
1215                 .info = alc_ch_mode_info,
1216                 .get = alc_ch_mode_get,
1217                 .put = alc_ch_mode_put,
1218         },
1219         { } /* end */
1220 };
1221
1222 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1223         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1224         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1225         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1226         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1227         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1228         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1229         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1230         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1231         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1232         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1233         { } /* end */
1234 };
1235
1236 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1237         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1238         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1239         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1240         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1241         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1242         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1243         { } /* end */
1244 };
1245
1246 /*
1247  * build control elements
1248  */
1249 static int alc_build_controls(struct hda_codec *codec)
1250 {
1251         struct alc_spec *spec = codec->spec;
1252         int err;
1253         int i;
1254
1255         for (i = 0; i < spec->num_mixers; i++) {
1256                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1257                 if (err < 0)
1258                         return err;
1259         }
1260
1261         if (spec->multiout.dig_out_nid) {
1262                 err = snd_hda_create_spdif_out_ctls(codec,
1263                                                     spec->multiout.dig_out_nid);
1264                 if (err < 0)
1265                         return err;
1266         }
1267         if (spec->dig_in_nid) {
1268                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1269                 if (err < 0)
1270                         return err;
1271         }
1272         return 0;
1273 }
1274
1275
1276 /*
1277  * initialize the codec volumes, etc
1278  */
1279
1280 /*
1281  * generic initialization of ADC, input mixers and output mixers
1282  */
1283 static struct hda_verb alc880_volume_init_verbs[] = {
1284         /*
1285          * Unmute ADC0-2 and set the default input to mic-in
1286          */
1287         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1288         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1289         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1290         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1291         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1292         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1293
1294         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1295          * mixer widget
1296          * Note: PASD motherboards uses the Line In 2 as the input for front
1297          * panel mic (mic 2)
1298          */
1299         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1300         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1301         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1302         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1303         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1304         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1305         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1306         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1307
1308         /*
1309          * Set up output mixers (0x0c - 0x0f)
1310          */
1311         /* set vol=0 to output mixers */
1312         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1313         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1314         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1315         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1316         /* set up input amps for analog loopback */
1317         /* Amp Indices: DAC = 0, mixer = 1 */
1318         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1319         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1320         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1321         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1322         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1323         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1324         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1325         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1326
1327         { }
1328 };
1329
1330 /*
1331  * 3-stack pin configuration:
1332  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1333  */
1334 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1335         /*
1336          * preset connection lists of input pins
1337          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1338          */
1339         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1340         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1341         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1342
1343         /*
1344          * Set pin mode and muting
1345          */
1346         /* set front pin widgets 0x14 for output */
1347         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1348         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1349         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1350         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1351         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1352         /* Mic2 (as headphone out) for HP output */
1353         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1354         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1355         /* Line In pin widget for input */
1356         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1357         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1358         /* Line2 (as front mic) pin widget for input and vref at 80% */
1359         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1360         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1361         /* CD pin widget for input */
1362         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1363
1364         { }
1365 };
1366
1367 /*
1368  * 5-stack pin configuration:
1369  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1370  * line-in/side = 0x1a, f-mic = 0x1b
1371  */
1372 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1373         /*
1374          * preset connection lists of input pins
1375          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1376          */
1377         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1378         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1379
1380         /*
1381          * Set pin mode and muting
1382          */
1383         /* set pin widgets 0x14-0x17 for output */
1384         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1385         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1386         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1387         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1388         /* unmute pins for output (no gain on this amp) */
1389         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1390         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1391         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1392         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1393
1394         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1395         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1396         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1397         /* Mic2 (as headphone out) for HP output */
1398         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1399         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1400         /* Line In pin widget for input */
1401         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1402         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1403         /* Line2 (as front mic) pin widget for input and vref at 80% */
1404         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1405         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1406         /* CD pin widget for input */
1407         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1408
1409         { }
1410 };
1411
1412 /*
1413  * W810 pin configuration:
1414  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1415  */
1416 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1417         /* hphone/speaker input selector: front DAC */
1418         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1419
1420         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1421         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1422         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1423         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1424         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1425         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1426
1427         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1428         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1429
1430         { }
1431 };
1432
1433 /*
1434  * Z71V pin configuration:
1435  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1436  */
1437 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1438         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1439         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1440         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1441         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1442
1443         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1444         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1445         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1446         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1447
1448         { }
1449 };
1450
1451 /*
1452  * 6-stack pin configuration:
1453  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1454  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1455  */
1456 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1457         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1458
1459         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1460         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1461         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1462         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1464         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1466         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467
1468         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1469         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1470         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1471         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1472         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1473         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1474         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1475         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1476         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1477         
1478         { }
1479 };
1480
1481 /*
1482  * Uniwill pin configuration:
1483  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1484  * line = 0x1a
1485  */
1486 static struct hda_verb alc880_uniwill_init_verbs[] = {
1487         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1488
1489         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1490         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1491         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1492         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1493         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1494         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1496         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1497         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1498         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1499         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1500         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1501         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1502         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1503
1504         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1505         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1506         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1507         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1508         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1509         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1510         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1511         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1512         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1513
1514         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1515         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1516
1517         { }
1518 };
1519
1520 /*
1521 * Uniwill P53
1522 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1523  */
1524 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1525         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1526
1527         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1528         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1529         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1530         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1531         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1532         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1533         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1534         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1535         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1536         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1537         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1538         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1539
1540         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1541         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1542         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1543         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1544         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1545         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1546
1547         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1548         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1549
1550         { }
1551 };
1552
1553 static struct hda_verb alc880_beep_init_verbs[] = {
1554         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1555         { }
1556 };
1557
1558 /* toggle speaker-output according to the hp-jack state */
1559 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1560 {
1561         unsigned int present;
1562         unsigned char bits;
1563
1564         present = snd_hda_codec_read(codec, 0x14, 0,
1565                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1566         bits = present ? HDA_AMP_MUTE : 0;
1567         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1568                                  HDA_AMP_MUTE, bits);
1569         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1570                                  HDA_AMP_MUTE, bits);
1571 }
1572
1573 /* auto-toggle front mic */
1574 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1575 {
1576         unsigned int present;
1577         unsigned char bits;
1578
1579         present = snd_hda_codec_read(codec, 0x18, 0,
1580                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1581         bits = present ? HDA_AMP_MUTE : 0;
1582         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1583 }
1584
1585 static void alc880_uniwill_automute(struct hda_codec *codec)
1586 {
1587         alc880_uniwill_hp_automute(codec);
1588         alc880_uniwill_mic_automute(codec);
1589 }
1590
1591 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1592                                        unsigned int res)
1593 {
1594         /* Looks like the unsol event is incompatible with the standard
1595          * definition.  4bit tag is placed at 28 bit!
1596          */
1597         switch (res >> 28) {
1598         case ALC880_HP_EVENT:
1599                 alc880_uniwill_hp_automute(codec);
1600                 break;
1601         case ALC880_MIC_EVENT:
1602                 alc880_uniwill_mic_automute(codec);
1603                 break;
1604         }
1605 }
1606
1607 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1608 {
1609         unsigned int present;
1610         unsigned char bits;
1611
1612         present = snd_hda_codec_read(codec, 0x14, 0,
1613                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1614         bits = present ? HDA_AMP_MUTE : 0;
1615         snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1616 }
1617
1618 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1619 {
1620         unsigned int present;
1621         
1622         present = snd_hda_codec_read(codec, 0x21, 0,
1623                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1624         present &= HDA_AMP_VOLMASK;
1625         snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1626                                  HDA_AMP_VOLMASK, present);
1627         snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1628                                  HDA_AMP_VOLMASK, present);
1629 }
1630
1631 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1632                                            unsigned int res)
1633 {
1634         /* Looks like the unsol event is incompatible with the standard
1635          * definition.  4bit tag is placed at 28 bit!
1636          */
1637         if ((res >> 28) == ALC880_HP_EVENT)
1638                 alc880_uniwill_p53_hp_automute(codec);
1639         if ((res >> 28) == ALC880_DCVOL_EVENT)
1640                 alc880_uniwill_p53_dcvol_automute(codec);
1641 }
1642
1643 /* FIXME! */
1644 /*
1645  * F1734 pin configuration:
1646  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1647  */
1648 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1649         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1650         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1651         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1652         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1653
1654         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1655         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1656         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1657         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1658
1659         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1660         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1661         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1662         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1663         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1664         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1665         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1666         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1667         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1668
1669         { }
1670 };
1671
1672 /* FIXME! */
1673 /*
1674  * ASUS pin configuration:
1675  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1676  */
1677 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1678         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1679         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1680         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1681         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1682
1683         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1684         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1685         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1686         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1687         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1688         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1689         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1690         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691
1692         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1693         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1694         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1695         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1696         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1697         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1698         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1699         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1700         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1701         
1702         { }
1703 };
1704
1705 /* Enable GPIO mask and set output */
1706 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1707 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1708
1709 /* Clevo m520g init */
1710 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1711         /* headphone output */
1712         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1713         /* line-out */
1714         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1715         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1716         /* Line-in */
1717         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1718         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1719         /* CD */
1720         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1721         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1722         /* Mic1 (rear panel) */
1723         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1724         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1725         /* Mic2 (front panel) */
1726         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1727         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1728         /* headphone */
1729         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1730         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1731         /* change to EAPD mode */
1732         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1733         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1734
1735         { }
1736 };
1737
1738 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1739         /* change to EAPD mode */
1740         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1741         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1742
1743         /* Headphone output */
1744         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1745         /* Front output*/
1746         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1747         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1748
1749         /* Line In pin widget for input */
1750         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1751         /* CD pin widget for input */
1752         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1753         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1754         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1755
1756         /* change to EAPD mode */
1757         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1758         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1759
1760         { }
1761 };
1762
1763 /*
1764  * LG m1 express dual
1765  *
1766  * Pin assignment:
1767  *   Rear Line-In/Out (blue): 0x14
1768  *   Build-in Mic-In: 0x15
1769  *   Speaker-out: 0x17
1770  *   HP-Out (green): 0x1b
1771  *   Mic-In/Out (red): 0x19
1772  *   SPDIF-Out: 0x1e
1773  */
1774
1775 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1776 static hda_nid_t alc880_lg_dac_nids[3] = {
1777         0x05, 0x02, 0x03
1778 };
1779
1780 /* seems analog CD is not working */
1781 static struct hda_input_mux alc880_lg_capture_source = {
1782         .num_items = 3,
1783         .items = {
1784                 { "Mic", 0x1 },
1785                 { "Line", 0x5 },
1786                 { "Internal Mic", 0x6 },
1787         },
1788 };
1789
1790 /* 2,4,6 channel modes */
1791 static struct hda_verb alc880_lg_ch2_init[] = {
1792         /* set line-in and mic-in to input */
1793         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1794         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1795         { }
1796 };
1797
1798 static struct hda_verb alc880_lg_ch4_init[] = {
1799         /* set line-in to out and mic-in to input */
1800         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1801         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1802         { }
1803 };
1804
1805 static struct hda_verb alc880_lg_ch6_init[] = {
1806         /* set line-in and mic-in to output */
1807         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1808         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1809         { }
1810 };
1811
1812 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1813         { 2, alc880_lg_ch2_init },
1814         { 4, alc880_lg_ch4_init },
1815         { 6, alc880_lg_ch6_init },
1816 };
1817
1818 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1819         /* FIXME: it's not really "master" but front channels */
1820         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1821         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1822         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1823         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1824         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1825         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1826         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1827         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1828         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1829         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1830         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1831         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1832         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1833         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1834         {
1835                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1836                 .name = "Channel Mode",
1837                 .info = alc_ch_mode_info,
1838                 .get = alc_ch_mode_get,
1839                 .put = alc_ch_mode_put,
1840         },
1841         { } /* end */
1842 };
1843
1844 static struct hda_verb alc880_lg_init_verbs[] = {
1845         /* set capture source to mic-in */
1846         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1847         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1848         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1849         /* mute all amp mixer inputs */
1850         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1851         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1852         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1853         /* line-in to input */
1854         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1855         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1856         /* built-in mic */
1857         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1858         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859         /* speaker-out */
1860         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1861         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1862         /* mic-in to input */
1863         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1864         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1865         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866         /* HP-out */
1867         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1868         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1869         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870         /* jack sense */
1871         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1872         { }
1873 };
1874
1875 /* toggle speaker-output according to the hp-jack state */
1876 static void alc880_lg_automute(struct hda_codec *codec)
1877 {
1878         unsigned int present;
1879         unsigned char bits;
1880
1881         present = snd_hda_codec_read(codec, 0x1b, 0,
1882                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1883         bits = present ? HDA_AMP_MUTE : 0;
1884         snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
1885                                  HDA_AMP_MUTE, bits);
1886 }
1887
1888 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1889 {
1890         /* Looks like the unsol event is incompatible with the standard
1891          * definition.  4bit tag is placed at 28 bit!
1892          */
1893         if ((res >> 28) == 0x01)
1894                 alc880_lg_automute(codec);
1895 }
1896
1897 /*
1898  * LG LW20
1899  *
1900  * Pin assignment:
1901  *   Speaker-out: 0x14
1902  *   Mic-In: 0x18
1903  *   Built-in Mic-In: 0x19
1904  *   Line-In: 0x1b
1905  *   HP-Out: 0x1a
1906  *   SPDIF-Out: 0x1e
1907  */
1908
1909 static struct hda_input_mux alc880_lg_lw_capture_source = {
1910         .num_items = 3,
1911         .items = {
1912                 { "Mic", 0x0 },
1913                 { "Internal Mic", 0x1 },
1914                 { "Line In", 0x2 },
1915         },
1916 };
1917
1918 #define alc880_lg_lw_modes alc880_threestack_modes
1919
1920 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1921         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1922         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1923         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1924         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1925         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1926         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1927         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1928         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1929         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1930         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1931         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1932         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1933         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1934         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1935         {
1936                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1937                 .name = "Channel Mode",
1938                 .info = alc_ch_mode_info,
1939                 .get = alc_ch_mode_get,
1940                 .put = alc_ch_mode_put,
1941         },
1942         { } /* end */
1943 };
1944
1945 static struct hda_verb alc880_lg_lw_init_verbs[] = {
1946         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1947         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1948         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1949
1950         /* set capture source to mic-in */
1951         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1952         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1953         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1954         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1955         /* speaker-out */
1956         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1957         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1958         /* HP-out */
1959         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1960         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1961         /* mic-in to input */
1962         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1963         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1964         /* built-in mic */
1965         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1966         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1967         /* jack sense */
1968         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1969         { }
1970 };
1971
1972 /* toggle speaker-output according to the hp-jack state */
1973 static void alc880_lg_lw_automute(struct hda_codec *codec)
1974 {
1975         unsigned int present;
1976         unsigned char bits;
1977
1978         present = snd_hda_codec_read(codec, 0x1b, 0,
1979                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1980         bits = present ? HDA_AMP_MUTE : 0;
1981         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1982                                  HDA_AMP_MUTE, bits);
1983 }
1984
1985 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1986 {
1987         /* Looks like the unsol event is incompatible with the standard
1988          * definition.  4bit tag is placed at 28 bit!
1989          */
1990         if ((res >> 28) == 0x01)
1991                 alc880_lg_lw_automute(codec);
1992 }
1993
1994 #ifdef CONFIG_SND_HDA_POWER_SAVE
1995 static struct hda_amp_list alc880_loopbacks[] = {
1996         { 0x0b, HDA_INPUT, 0 },
1997         { 0x0b, HDA_INPUT, 1 },
1998         { 0x0b, HDA_INPUT, 2 },
1999         { 0x0b, HDA_INPUT, 3 },
2000         { 0x0b, HDA_INPUT, 4 },
2001         { } /* end */
2002 };
2003
2004 static struct hda_amp_list alc880_lg_loopbacks[] = {
2005         { 0x0b, HDA_INPUT, 1 },
2006         { 0x0b, HDA_INPUT, 6 },
2007         { 0x0b, HDA_INPUT, 7 },
2008         { } /* end */
2009 };
2010 #endif
2011
2012 /*
2013  * Common callbacks
2014  */
2015
2016 static int alc_init(struct hda_codec *codec)
2017 {
2018         struct alc_spec *spec = codec->spec;
2019         unsigned int i;
2020
2021         for (i = 0; i < spec->num_init_verbs; i++)
2022                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2023
2024         if (spec->init_hook)
2025                 spec->init_hook(codec);
2026
2027         return 0;
2028 }
2029
2030 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2031 {
2032         struct alc_spec *spec = codec->spec;
2033
2034         if (spec->unsol_event)
2035                 spec->unsol_event(codec, res);
2036 }
2037
2038 #ifdef CONFIG_SND_HDA_POWER_SAVE
2039 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2040 {
2041         struct alc_spec *spec = codec->spec;
2042         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2043 }
2044 #endif
2045
2046 /*
2047  * Analog playback callbacks
2048  */
2049 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2050                                     struct hda_codec *codec,
2051                                     struct snd_pcm_substream *substream)
2052 {
2053         struct alc_spec *spec = codec->spec;
2054         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2055 }
2056
2057 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2058                                        struct hda_codec *codec,
2059                                        unsigned int stream_tag,
2060                                        unsigned int format,
2061                                        struct snd_pcm_substream *substream)
2062 {
2063         struct alc_spec *spec = codec->spec;
2064         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2065                                                 stream_tag, format, substream);
2066 }
2067
2068 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2069                                        struct hda_codec *codec,
2070                                        struct snd_pcm_substream *substream)
2071 {
2072         struct alc_spec *spec = codec->spec;
2073         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2074 }
2075
2076 /*
2077  * Digital out
2078  */
2079 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2080                                         struct hda_codec *codec,
2081                                         struct snd_pcm_substream *substream)
2082 {
2083         struct alc_spec *spec = codec->spec;
2084         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2085 }
2086
2087 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2088                                            struct hda_codec *codec,
2089                                            unsigned int stream_tag,
2090                                            unsigned int format,
2091                                            struct snd_pcm_substream *substream)
2092 {
2093         struct alc_spec *spec = codec->spec;
2094         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2095                                              stream_tag, format, substream);
2096 }
2097
2098 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2099                                          struct hda_codec *codec,
2100                                          struct snd_pcm_substream *substream)
2101 {
2102         struct alc_spec *spec = codec->spec;
2103         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2104 }
2105
2106 /*
2107  * Analog capture
2108  */
2109 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2110                                       struct hda_codec *codec,
2111                                       unsigned int stream_tag,
2112                                       unsigned int format,
2113                                       struct snd_pcm_substream *substream)
2114 {
2115         struct alc_spec *spec = codec->spec;
2116
2117         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2118                                    stream_tag, 0, format);
2119         return 0;
2120 }
2121
2122 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2123                                       struct hda_codec *codec,
2124                                       struct snd_pcm_substream *substream)
2125 {
2126         struct alc_spec *spec = codec->spec;
2127
2128         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2129                                    0, 0, 0);
2130         return 0;
2131 }
2132
2133
2134 /*
2135  */
2136 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2137         .substreams = 1,
2138         .channels_min = 2,
2139         .channels_max = 8,
2140         /* NID is set in alc_build_pcms */
2141         .ops = {
2142                 .open = alc880_playback_pcm_open,
2143                 .prepare = alc880_playback_pcm_prepare,
2144                 .cleanup = alc880_playback_pcm_cleanup
2145         },
2146 };
2147
2148 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2149         .substreams = 2,
2150         .channels_min = 2,
2151         .channels_max = 2,
2152         /* NID is set in alc_build_pcms */
2153         .ops = {
2154                 .prepare = alc880_capture_pcm_prepare,
2155                 .cleanup = alc880_capture_pcm_cleanup
2156         },
2157 };
2158
2159 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2160         .substreams = 1,
2161         .channels_min = 2,
2162         .channels_max = 2,
2163         /* NID is set in alc_build_pcms */
2164         .ops = {
2165                 .open = alc880_dig_playback_pcm_open,
2166                 .close = alc880_dig_playback_pcm_close,
2167                 .prepare = alc880_dig_playback_pcm_prepare
2168         },
2169 };
2170
2171 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2172         .substreams = 1,
2173         .channels_min = 2,
2174         .channels_max = 2,
2175         /* NID is set in alc_build_pcms */
2176 };
2177
2178 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2179 static struct hda_pcm_stream alc_pcm_null_playback = {
2180         .substreams = 0,
2181         .channels_min = 0,
2182         .channels_max = 0,
2183 };
2184
2185 static int alc_build_pcms(struct hda_codec *codec)
2186 {
2187         struct alc_spec *spec = codec->spec;
2188         struct hda_pcm *info = spec->pcm_rec;
2189         int i;
2190
2191         codec->num_pcms = 1;
2192         codec->pcm_info = info;
2193
2194         info->name = spec->stream_name_analog;
2195         if (spec->stream_analog_playback) {
2196                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2197                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2198                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2199         }
2200         if (spec->stream_analog_capture) {
2201                 snd_assert(spec->adc_nids, return -EINVAL);
2202                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2203                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2204         }
2205
2206         if (spec->channel_mode) {
2207                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2208                 for (i = 0; i < spec->num_channel_mode; i++) {
2209                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2210                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2211                         }
2212                 }
2213         }
2214
2215         /* SPDIF for stream index #1 */
2216         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2217                 codec->num_pcms = 2;
2218                 info = spec->pcm_rec + 1;
2219                 info->name = spec->stream_name_digital;
2220                 if (spec->multiout.dig_out_nid &&
2221                     spec->stream_digital_playback) {
2222                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2223                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2224                 }
2225                 if (spec->dig_in_nid &&
2226                     spec->stream_digital_capture) {
2227                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2228                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2229                 }
2230         }
2231
2232         /* If the use of more than one ADC is requested for the current
2233          * model, configure a second analog capture-only PCM.
2234          */
2235         /* Additional Analaog capture for index #2 */
2236         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2237             spec->adc_nids) {
2238                 codec->num_pcms = 3;
2239                 info = spec->pcm_rec + 2;
2240                 info->name = spec->stream_name_analog;
2241                 /* No playback stream for second PCM */
2242                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2243                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2244                 if (spec->stream_analog_capture) {
2245                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2246                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2247                 }
2248         }
2249
2250         return 0;
2251 }
2252
2253 static void alc_free(struct hda_codec *codec)
2254 {
2255         struct alc_spec *spec = codec->spec;
2256         unsigned int i;
2257
2258         if (!spec)
2259                 return;
2260
2261         if (spec->kctl_alloc) {
2262                 for (i = 0; i < spec->num_kctl_used; i++)
2263                         kfree(spec->kctl_alloc[i].name);
2264                 kfree(spec->kctl_alloc);
2265         }
2266         kfree(spec);
2267 }
2268
2269 /*
2270  */
2271 static struct hda_codec_ops alc_patch_ops = {
2272         .build_controls = alc_build_controls,
2273         .build_pcms = alc_build_pcms,
2274         .init = alc_init,
2275         .free = alc_free,
2276         .unsol_event = alc_unsol_event,
2277 #ifdef CONFIG_SND_HDA_POWER_SAVE
2278         .check_power_status = alc_check_power_status,
2279 #endif
2280 };
2281
2282
2283 /*
2284  * Test configuration for debugging
2285  *
2286  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2287  * enum controls.
2288  */
2289 #ifdef CONFIG_SND_DEBUG
2290 static hda_nid_t alc880_test_dac_nids[4] = {
2291         0x02, 0x03, 0x04, 0x05
2292 };
2293
2294 static struct hda_input_mux alc880_test_capture_source = {
2295         .num_items = 7,
2296         .items = {
2297                 { "In-1", 0x0 },
2298                 { "In-2", 0x1 },
2299                 { "In-3", 0x2 },
2300                 { "In-4", 0x3 },
2301                 { "CD", 0x4 },
2302                 { "Front", 0x5 },
2303                 { "Surround", 0x6 },
2304         },
2305 };
2306
2307 static struct hda_channel_mode alc880_test_modes[4] = {
2308         { 2, NULL },
2309         { 4, NULL },
2310         { 6, NULL },
2311         { 8, NULL },
2312 };
2313
2314 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2315                                  struct snd_ctl_elem_info *uinfo)
2316 {
2317         static char *texts[] = {
2318                 "N/A", "Line Out", "HP Out",
2319                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2320         };
2321         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2322         uinfo->count = 1;
2323         uinfo->value.enumerated.items = 8;
2324         if (uinfo->value.enumerated.item >= 8)
2325                 uinfo->value.enumerated.item = 7;
2326         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2327         return 0;
2328 }
2329
2330 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2331                                 struct snd_ctl_elem_value *ucontrol)
2332 {
2333         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2334         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2335         unsigned int pin_ctl, item = 0;
2336
2337         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2338                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2339         if (pin_ctl & AC_PINCTL_OUT_EN) {
2340                 if (pin_ctl & AC_PINCTL_HP_EN)
2341                         item = 2;
2342                 else
2343                         item = 1;
2344         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2345                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2346                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2347                 case AC_PINCTL_VREF_50:  item = 4; break;
2348                 case AC_PINCTL_VREF_GRD: item = 5; break;
2349                 case AC_PINCTL_VREF_80:  item = 6; break;
2350                 case AC_PINCTL_VREF_100: item = 7; break;
2351                 }
2352         }
2353         ucontrol->value.enumerated.item[0] = item;
2354         return 0;
2355 }
2356
2357 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2358                                 struct snd_ctl_elem_value *ucontrol)
2359 {
2360         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2361         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2362         static unsigned int ctls[] = {
2363                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2364                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2365                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2366                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2367                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2368                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2369         };
2370         unsigned int old_ctl, new_ctl;
2371
2372         old_ctl = snd_hda_codec_read(codec, nid, 0,
2373                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2374         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2375         if (old_ctl != new_ctl) {
2376                 int val;
2377                 snd_hda_codec_write_cache(codec, nid, 0,
2378                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
2379                                           new_ctl);
2380                 val = ucontrol->value.enumerated.item[0] >= 3 ?
2381                         HDA_AMP_MUTE : 0;
2382                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2383                                          HDA_AMP_MUTE, val);
2384                 return 1;
2385         }
2386         return 0;
2387 }
2388
2389 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2390                                  struct snd_ctl_elem_info *uinfo)
2391 {
2392         static char *texts[] = {
2393                 "Front", "Surround", "CLFE", "Side"
2394         };
2395         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2396         uinfo->count = 1;
2397         uinfo->value.enumerated.items = 4;
2398         if (uinfo->value.enumerated.item >= 4)
2399                 uinfo->value.enumerated.item = 3;
2400         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2401         return 0;
2402 }
2403
2404 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2405                                 struct snd_ctl_elem_value *ucontrol)
2406 {
2407         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2408         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2409         unsigned int sel;
2410
2411         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2412         ucontrol->value.enumerated.item[0] = sel & 3;
2413         return 0;
2414 }
2415
2416 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2417                                 struct snd_ctl_elem_value *ucontrol)
2418 {
2419         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2420         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2421         unsigned int sel;
2422
2423         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2424         if (ucontrol->value.enumerated.item[0] != sel) {
2425                 sel = ucontrol->value.enumerated.item[0] & 3;
2426                 snd_hda_codec_write_cache(codec, nid, 0,
2427                                           AC_VERB_SET_CONNECT_SEL, sel);
2428                 return 1;
2429         }
2430         return 0;
2431 }
2432
2433 #define PIN_CTL_TEST(xname,nid) {                       \
2434                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2435                         .name = xname,                 \
2436                         .info = alc_test_pin_ctl_info, \
2437                         .get = alc_test_pin_ctl_get,   \
2438                         .put = alc_test_pin_ctl_put,   \
2439                         .private_value = nid           \
2440                         }
2441
2442 #define PIN_SRC_TEST(xname,nid) {                       \
2443                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2444                         .name = xname,                 \
2445                         .info = alc_test_pin_src_info, \
2446                         .get = alc_test_pin_src_get,   \
2447                         .put = alc_test_pin_src_put,   \
2448                         .private_value = nid           \
2449                         }
2450
2451 static struct snd_kcontrol_new alc880_test_mixer[] = {
2452         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2453         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2454         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2455         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2456         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2457         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2458         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2459         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2460         PIN_CTL_TEST("Front Pin Mode", 0x14),
2461         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2462         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2463         PIN_CTL_TEST("Side Pin Mode", 0x17),
2464         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2465         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2466         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2467         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2468         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2469         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2470         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2471         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2472         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2473         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2474         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2475         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2476         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2477         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2478         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2479         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2480         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2481         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2482         {
2483                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2484                 .name = "Channel Mode",
2485                 .info = alc_ch_mode_info,
2486                 .get = alc_ch_mode_get,
2487                 .put = alc_ch_mode_put,
2488         },
2489         { } /* end */
2490 };
2491
2492 static struct hda_verb alc880_test_init_verbs[] = {
2493         /* Unmute inputs of 0x0c - 0x0f */
2494         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2495         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2496         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2497         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2498         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2499         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2500         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2501         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2502         /* Vol output for 0x0c-0x0f */
2503         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2504         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2505         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2506         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2507         /* Set output pins 0x14-0x17 */
2508         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2509         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2510         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2511         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2512         /* Unmute output pins 0x14-0x17 */
2513         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2514         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2515         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2516         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2517         /* Set input pins 0x18-0x1c */
2518         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2519         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2520         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2521         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2522         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2523         /* Mute input pins 0x18-0x1b */
2524         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2525         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2526         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2527         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2528         /* ADC set up */
2529         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2530         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2531         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2532         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2533         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2534         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2535         /* Analog input/passthru */
2536         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2537         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2538         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2539         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2540         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2541         { }
2542 };
2543 #endif
2544
2545 /*
2546  */
2547
2548 static const char *alc880_models[ALC880_MODEL_LAST] = {
2549         [ALC880_3ST]            = "3stack",
2550         [ALC880_TCL_S700]       = "tcl",
2551         [ALC880_3ST_DIG]        = "3stack-digout",
2552         [ALC880_CLEVO]          = "clevo",
2553         [ALC880_5ST]            = "5stack",
2554         [ALC880_5ST_DIG]        = "5stack-digout",
2555         [ALC880_W810]           = "w810",
2556         [ALC880_Z71V]           = "z71v",
2557         [ALC880_6ST]            = "6stack",
2558         [ALC880_6ST_DIG]        = "6stack-digout",
2559         [ALC880_ASUS]           = "asus",
2560         [ALC880_ASUS_W1V]       = "asus-w1v",
2561         [ALC880_ASUS_DIG]       = "asus-dig",
2562         [ALC880_ASUS_DIG2]      = "asus-dig2",
2563         [ALC880_UNIWILL_DIG]    = "uniwill",
2564         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2565         [ALC880_FUJITSU]        = "fujitsu",
2566         [ALC880_F1734]          = "F1734",
2567         [ALC880_LG]             = "lg",
2568         [ALC880_LG_LW]          = "lg-lw",
2569 #ifdef CONFIG_SND_DEBUG
2570         [ALC880_TEST]           = "test",
2571 #endif
2572         [ALC880_AUTO]           = "auto",
2573 };
2574
2575 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2576         /* Broken BIOS configuration */
2577         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2578         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2579
2580         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2581         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2582         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2583         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2584         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2585         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2586         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2587         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2588         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2589
2590         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2591         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2592
2593         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2594         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2595         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2596         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2597         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2598         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2599         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2600         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2601         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2602         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2603         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2604         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2605         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2606         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2607         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2608
2609         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2610         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2611         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2612         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2613         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2614         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2615         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2616         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2617         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2618         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2619         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2620         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2621         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2622         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2623         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2624         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2625         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2626         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2627
2628         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2629         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2630         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2631         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2632
2633         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2634         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2635         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2636         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2637
2638         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2639         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2640         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2641         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2642
2643         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2644         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2645         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2646         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2647         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2648         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2649         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2650         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2651         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2652         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2653         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2654
2655         {}
2656 };
2657
2658 /*
2659  * ALC880 codec presets
2660  */
2661 static struct alc_config_preset alc880_presets[] = {
2662         [ALC880_3ST] = {
2663                 .mixers = { alc880_three_stack_mixer },
2664                 .init_verbs = { alc880_volume_init_verbs,
2665                                 alc880_pin_3stack_init_verbs },
2666                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2667                 .dac_nids = alc880_dac_nids,
2668                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2669                 .channel_mode = alc880_threestack_modes,
2670                 .need_dac_fix = 1,
2671                 .input_mux = &alc880_capture_source,
2672         },
2673         [ALC880_3ST_DIG] = {
2674                 .mixers = { alc880_three_stack_mixer },
2675                 .init_verbs = { alc880_volume_init_verbs,
2676                                 alc880_pin_3stack_init_verbs },
2677                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2678                 .dac_nids = alc880_dac_nids,
2679                 .dig_out_nid = ALC880_DIGOUT_NID,
2680                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2681                 .channel_mode = alc880_threestack_modes,
2682                 .need_dac_fix = 1,
2683                 .input_mux = &alc880_capture_source,
2684         },
2685         [ALC880_TCL_S700] = {
2686                 .mixers = { alc880_tcl_s700_mixer },
2687                 .init_verbs = { alc880_volume_init_verbs,
2688                                 alc880_pin_tcl_S700_init_verbs,
2689                                 alc880_gpio2_init_verbs },
2690                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2691                 .dac_nids = alc880_dac_nids,
2692                 .hp_nid = 0x03,
2693                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2694                 .channel_mode = alc880_2_jack_modes,
2695                 .input_mux = &alc880_capture_source,
2696         },
2697         [ALC880_5ST] = {
2698                 .mixers = { alc880_three_stack_mixer,
2699                             alc880_five_stack_mixer},
2700                 .init_verbs = { alc880_volume_init_verbs,
2701                                 alc880_pin_5stack_init_verbs },
2702                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2703                 .dac_nids = alc880_dac_nids,
2704                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2705                 .channel_mode = alc880_fivestack_modes,
2706                 .input_mux = &alc880_capture_source,
2707         },
2708         [ALC880_5ST_DIG] = {
2709                 .mixers = { alc880_three_stack_mixer,
2710                             alc880_five_stack_mixer },
2711                 .init_verbs = { alc880_volume_init_verbs,
2712                                 alc880_pin_5stack_init_verbs },
2713                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2714                 .dac_nids = alc880_dac_nids,
2715                 .dig_out_nid = ALC880_DIGOUT_NID,
2716                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2717                 .channel_mode = alc880_fivestack_modes,
2718                 .input_mux = &alc880_capture_source,
2719         },
2720         [ALC880_6ST] = {
2721                 .mixers = { alc880_six_stack_mixer },
2722                 .init_verbs = { alc880_volume_init_verbs,
2723                                 alc880_pin_6stack_init_verbs },
2724                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2725                 .dac_nids = alc880_6st_dac_nids,
2726                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2727                 .channel_mode = alc880_sixstack_modes,
2728                 .input_mux = &alc880_6stack_capture_source,
2729         },
2730         [ALC880_6ST_DIG] = {
2731                 .mixers = { alc880_six_stack_mixer },
2732                 .init_verbs = { alc880_volume_init_verbs,
2733                                 alc880_pin_6stack_init_verbs },
2734                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2735                 .dac_nids = alc880_6st_dac_nids,
2736                 .dig_out_nid = ALC880_DIGOUT_NID,
2737                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2738                 .channel_mode = alc880_sixstack_modes,
2739                 .input_mux = &alc880_6stack_capture_source,
2740         },
2741         [ALC880_W810] = {
2742                 .mixers = { alc880_w810_base_mixer },
2743                 .init_verbs = { alc880_volume_init_verbs,
2744                                 alc880_pin_w810_init_verbs,
2745                                 alc880_gpio2_init_verbs },
2746                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2747                 .dac_nids = alc880_w810_dac_nids,
2748                 .dig_out_nid = ALC880_DIGOUT_NID,
2749                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2750                 .channel_mode = alc880_w810_modes,
2751                 .input_mux = &alc880_capture_source,
2752         },
2753         [ALC880_Z71V] = {
2754                 .mixers = { alc880_z71v_mixer },
2755                 .init_verbs = { alc880_volume_init_verbs,
2756                                 alc880_pin_z71v_init_verbs },
2757                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2758                 .dac_nids = alc880_z71v_dac_nids,
2759                 .dig_out_nid = ALC880_DIGOUT_NID,
2760                 .hp_nid = 0x03,
2761                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2762                 .channel_mode = alc880_2_jack_modes,
2763                 .input_mux = &alc880_capture_source,
2764         },
2765         [ALC880_F1734] = {
2766                 .mixers = { alc880_f1734_mixer },
2767                 .init_verbs = { alc880_volume_init_verbs,
2768                                 alc880_pin_f1734_init_verbs },
2769                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2770                 .dac_nids = alc880_f1734_dac_nids,
2771                 .hp_nid = 0x02,
2772                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2773                 .channel_mode = alc880_2_jack_modes,
2774                 .input_mux = &alc880_capture_source,
2775         },
2776         [ALC880_ASUS] = {
2777                 .mixers = { alc880_asus_mixer },
2778                 .init_verbs = { alc880_volume_init_verbs,
2779                                 alc880_pin_asus_init_verbs,
2780                                 alc880_gpio1_init_verbs },
2781                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2782                 .dac_nids = alc880_asus_dac_nids,
2783                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2784                 .channel_mode = alc880_asus_modes,
2785                 .need_dac_fix = 1,
2786                 .input_mux = &alc880_capture_source,
2787         },
2788         [ALC880_ASUS_DIG] = {
2789                 .mixers = { alc880_asus_mixer },
2790                 .init_verbs = { alc880_volume_init_verbs,
2791                                 alc880_pin_asus_init_verbs,
2792                                 alc880_gpio1_init_verbs },
2793                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2794                 .dac_nids = alc880_asus_dac_nids,
2795                 .dig_out_nid = ALC880_DIGOUT_NID,
2796                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2797                 .channel_mode = alc880_asus_modes,
2798                 .need_dac_fix = 1,
2799                 .input_mux = &alc880_capture_source,
2800         },
2801         [ALC880_ASUS_DIG2] = {
2802                 .mixers = { alc880_asus_mixer },
2803                 .init_verbs = { alc880_volume_init_verbs,
2804                                 alc880_pin_asus_init_verbs,
2805                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2806                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2807                 .dac_nids = alc880_asus_dac_nids,
2808                 .dig_out_nid = ALC880_DIGOUT_NID,
2809                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2810                 .channel_mode = alc880_asus_modes,
2811                 .need_dac_fix = 1,
2812                 .input_mux = &alc880_capture_source,
2813         },
2814         [ALC880_ASUS_W1V] = {
2815                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2816                 .init_verbs = { alc880_volume_init_verbs,
2817                                 alc880_pin_asus_init_verbs,
2818                                 alc880_gpio1_init_verbs },
2819                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2820                 .dac_nids = alc880_asus_dac_nids,
2821                 .dig_out_nid = ALC880_DIGOUT_NID,
2822                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2823                 .channel_mode = alc880_asus_modes,
2824                 .need_dac_fix = 1,
2825                 .input_mux = &alc880_capture_source,
2826         },
2827         [ALC880_UNIWILL_DIG] = {
2828                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2829                 .init_verbs = { alc880_volume_init_verbs,
2830                                 alc880_pin_asus_init_verbs },
2831                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2832                 .dac_nids = alc880_asus_dac_nids,
2833                 .dig_out_nid = ALC880_DIGOUT_NID,
2834                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2835                 .channel_mode = alc880_asus_modes,
2836                 .need_dac_fix = 1,
2837                 .input_mux = &alc880_capture_source,
2838         },
2839         [ALC880_UNIWILL] = {
2840                 .mixers = { alc880_uniwill_mixer },
2841                 .init_verbs = { alc880_volume_init_verbs,
2842                                 alc880_uniwill_init_verbs },
2843                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2844                 .dac_nids = alc880_asus_dac_nids,
2845                 .dig_out_nid = ALC880_DIGOUT_NID,
2846                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2847                 .channel_mode = alc880_threestack_modes,
2848                 .need_dac_fix = 1,
2849                 .input_mux = &alc880_capture_source,
2850                 .unsol_event = alc880_uniwill_unsol_event,
2851                 .init_hook = alc880_uniwill_automute,
2852         },
2853         [ALC880_UNIWILL_P53] = {
2854                 .mixers = { alc880_uniwill_p53_mixer },
2855                 .init_verbs = { alc880_volume_init_verbs,
2856                                 alc880_uniwill_p53_init_verbs },
2857                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2858                 .dac_nids = alc880_asus_dac_nids,
2859                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2860                 .channel_mode = alc880_threestack_modes,
2861                 .input_mux = &alc880_capture_source,
2862                 .unsol_event = alc880_uniwill_p53_unsol_event,
2863                 .init_hook = alc880_uniwill_p53_hp_automute,
2864         },
2865         [ALC880_FUJITSU] = {
2866                 .mixers = { alc880_fujitsu_mixer,
2867                             alc880_pcbeep_mixer, },
2868                 .init_verbs = { alc880_volume_init_verbs,
2869                                 alc880_uniwill_p53_init_verbs,
2870                                 alc880_beep_init_verbs },
2871                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2872                 .dac_nids = alc880_dac_nids,
2873                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2874                 .channel_mode = alc880_2_jack_modes,
2875                 .input_mux = &alc880_capture_source,
2876                 .unsol_event = alc880_uniwill_p53_unsol_event,
2877                 .init_hook = alc880_uniwill_p53_hp_automute,
2878         },
2879         [ALC880_CLEVO] = {
2880                 .mixers = { alc880_three_stack_mixer },
2881                 .init_verbs = { alc880_volume_init_verbs,
2882                                 alc880_pin_clevo_init_verbs },
2883                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2884                 .dac_nids = alc880_dac_nids,
2885                 .hp_nid = 0x03,
2886                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2887                 .channel_mode = alc880_threestack_modes,
2888                 .need_dac_fix = 1,
2889                 .input_mux = &alc880_capture_source,
2890         },
2891         [ALC880_LG] = {
2892                 .mixers = { alc880_lg_mixer },
2893                 .init_verbs = { alc880_volume_init_verbs,
2894                                 alc880_lg_init_verbs },
2895                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2896                 .dac_nids = alc880_lg_dac_nids,
2897                 .dig_out_nid = ALC880_DIGOUT_NID,
2898                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2899                 .channel_mode = alc880_lg_ch_modes,
2900                 .need_dac_fix = 1,
2901                 .input_mux = &alc880_lg_capture_source,
2902                 .unsol_event = alc880_lg_unsol_event,
2903                 .init_hook = alc880_lg_automute,
2904 #ifdef CONFIG_SND_HDA_POWER_SAVE
2905                 .loopbacks = alc880_lg_loopbacks,
2906 #endif
2907         },
2908         [ALC880_LG_LW] = {
2909                 .mixers = { alc880_lg_lw_mixer },
2910                 .init_verbs = { alc880_volume_init_verbs,
2911                                 alc880_lg_lw_init_verbs },
2912                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2913                 .dac_nids = alc880_dac_nids,
2914                 .dig_out_nid = ALC880_DIGOUT_NID,
2915                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2916                 .channel_mode = alc880_lg_lw_modes,
2917                 .input_mux = &alc880_lg_lw_capture_source,
2918                 .unsol_event = alc880_lg_lw_unsol_event,
2919                 .init_hook = alc880_lg_lw_automute,
2920         },
2921 #ifdef CONFIG_SND_DEBUG
2922         [ALC880_TEST] = {
2923                 .mixers = { alc880_test_mixer },
2924                 .init_verbs = { alc880_test_init_verbs },
2925                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2926                 .dac_nids = alc880_test_dac_nids,
2927                 .dig_out_nid = ALC880_DIGOUT_NID,
2928                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2929                 .channel_mode = alc880_test_modes,
2930                 .input_mux = &alc880_test_capture_source,
2931         },
2932 #endif
2933 };
2934
2935 /*
2936  * Automatic parse of I/O pins from the BIOS configuration
2937  */
2938
2939 #define NUM_CONTROL_ALLOC       32
2940 #define NUM_VERB_ALLOC          32
2941
2942 enum {
2943         ALC_CTL_WIDGET_VOL,
2944         ALC_CTL_WIDGET_MUTE,
2945         ALC_CTL_BIND_MUTE,
2946 };
2947 static struct snd_kcontrol_new alc880_control_templates[] = {
2948         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2949         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2950         HDA_BIND_MUTE(NULL, 0, 0, 0),
2951 };
2952
2953 /* add dynamic controls */
2954 static int add_control(struct alc_spec *spec, int type, const char *name,
2955                        unsigned long val)
2956 {
2957         struct snd_kcontrol_new *knew;
2958
2959         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2960                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2961
2962                 /* array + terminator */
2963                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2964                 if (!knew)
2965                         return -ENOMEM;
2966                 if (spec->kctl_alloc) {
2967                         memcpy(knew, spec->kctl_alloc,
2968                                sizeof(*knew) * spec->num_kctl_alloc);
2969                         kfree(spec->kctl_alloc);
2970                 }
2971                 spec->kctl_alloc = knew;
2972                 spec->num_kctl_alloc = num;
2973         }
2974
2975         knew = &spec->kctl_alloc[spec->num_kctl_used];
2976         *knew = alc880_control_templates[type];
2977         knew->name = kstrdup(name, GFP_KERNEL);
2978         if (!knew->name)
2979                 return -ENOMEM;
2980         knew->private_value = val;
2981         spec->num_kctl_used++;
2982         return 0;
2983 }
2984
2985 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
2986 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
2987 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
2988 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
2989 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
2990 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
2991 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
2992 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
2993 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
2994 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
2995 #define ALC880_PIN_CD_NID               0x1c
2996
2997 /* fill in the dac_nids table from the parsed pin configuration */
2998 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
2999                                      const struct auto_pin_cfg *cfg)
3000 {
3001         hda_nid_t nid;
3002         int assigned[4];
3003         int i, j;
3004
3005         memset(assigned, 0, sizeof(assigned));
3006         spec->multiout.dac_nids = spec->private_dac_nids;
3007
3008         /* check the pins hardwired to audio widget */
3009         for (i = 0; i < cfg->line_outs; i++) {
3010                 nid = cfg->line_out_pins[i];
3011                 if (alc880_is_fixed_pin(nid)) {
3012                         int idx = alc880_fixed_pin_idx(nid);
3013                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3014                         assigned[idx] = 1;
3015                 }
3016         }
3017         /* left pins can be connect to any audio widget */
3018         for (i = 0; i < cfg->line_outs; i++) {
3019                 nid = cfg->line_out_pins[i];
3020                 if (alc880_is_fixed_pin(nid))
3021                         continue;
3022                 /* search for an empty channel */
3023                 for (j = 0; j < cfg->line_outs; j++) {
3024                         if (!assigned[j]) {
3025                                 spec->multiout.dac_nids[i] =
3026                                         alc880_idx_to_dac(j);
3027                                 assigned[j] = 1;
3028                                 break;
3029                         }
3030                 }
3031         }
3032         spec->multiout.num_dacs = cfg->line_outs;
3033         return 0;
3034 }
3035
3036 /* add playback controls from the parsed DAC table */
3037 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3038                                              const struct auto_pin_cfg *cfg)
3039 {
3040         char name[32];
3041         static const char *chname[4] = {
3042                 "Front", "Surround", NULL /*CLFE*/, "Side"
3043         };
3044         hda_nid_t nid;
3045         int i, err;
3046
3047         for (i = 0; i < cfg->line_outs; i++) {
3048                 if (!spec->multiout.dac_nids[i])
3049                         continue;
3050                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3051                 if (i == 2) {
3052                         /* Center/LFE */
3053                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3054                                           "Center Playback Volume",
3055                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3056                                                               HDA_OUTPUT));
3057                         if (err < 0)
3058                                 return err;
3059                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3060                                           "LFE Playback Volume",
3061                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3062                                                               HDA_OUTPUT));
3063                         if (err < 0)
3064                                 return err;
3065                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3066                                           "Center Playback Switch",
3067                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3068                                                               HDA_INPUT));
3069                         if (err < 0)
3070                                 return err;
3071                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3072                                           "LFE Playback Switch",
3073                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3074                                                               HDA_INPUT));
3075                         if (err < 0)
3076                                 return err;
3077                 } else {
3078                         sprintf(name, "%s Playback Volume", chname[i]);
3079                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3080                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3081                                                               HDA_OUTPUT));
3082                         if (err < 0)
3083                                 return err;
3084                         sprintf(name, "%s Playback Switch", chname[i]);
3085                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3086                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3087                                                               HDA_INPUT));
3088                         if (err < 0)
3089                                 return err;
3090                 }
3091         }
3092         return 0;
3093 }
3094
3095 /* add playback controls for speaker and HP outputs */
3096 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3097                                         const char *pfx)
3098 {
3099         hda_nid_t nid;
3100         int err;
3101         char name[32];
3102
3103         if (!pin)
3104                 return 0;
3105
3106         if (alc880_is_fixed_pin(pin)) {
3107                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3108                 /* specify the DAC as the extra output */
3109                 if (!spec->multiout.hp_nid)
3110                         spec->multiout.hp_nid = nid;
3111                 else
3112                         spec->multiout.extra_out_nid[0] = nid;
3113                 /* control HP volume/switch on the output mixer amp */
3114                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3115                 sprintf(name, "%s Playback Volume", pfx);
3116                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3117                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3118                 if (err < 0)
3119                         return err;
3120                 sprintf(name, "%s Playback Switch", pfx);
3121                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3122                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3123                 if (err < 0)
3124                         return err;
3125         } else if (alc880_is_multi_pin(pin)) {
3126                 /* set manual connection */
3127                 /* we have only a switch on HP-out PIN */
3128                 sprintf(name, "%s Playback Switch", pfx);
3129                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3130                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3131                 if (err < 0)
3132                         return err;
3133         }
3134         return 0;
3135 }
3136
3137 /* create input playback/capture controls for the given pin */
3138 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3139                             const char *ctlname,
3140                             int idx, hda_nid_t mix_nid)
3141 {
3142         char name[32];
3143         int err;
3144
3145         sprintf(name, "%s Playback Volume", ctlname);
3146         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3147                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3148         if (err < 0)
3149                 return err;
3150         sprintf(name, "%s Playback Switch", ctlname);
3151         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3152                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3153         if (err < 0)
3154                 return err;
3155         return 0;
3156 }
3157
3158 /* create playback/capture controls for input pins */
3159 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3160                                                 const struct auto_pin_cfg *cfg)
3161 {
3162         struct hda_input_mux *imux = &spec->private_imux;
3163         int i, err, idx;
3164
3165         for (i = 0; i < AUTO_PIN_LAST; i++) {
3166                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3167                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3168                         err = new_analog_input(spec, cfg->input_pins[i],
3169                                                auto_pin_cfg_labels[i],
3170                                                idx, 0x0b);
3171                         if (err < 0)
3172                                 return err;
3173                         imux->items[imux->num_items].label =
3174                                 auto_pin_cfg_labels[i];
3175                         imux->items[imux->num_items].index =
3176                                 alc880_input_pin_idx(cfg->input_pins[i]);
3177                         imux->num_items++;
3178                 }
3179         }
3180         return 0;
3181 }
3182
3183 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3184                                               hda_nid_t nid, int pin_type,
3185                                               int dac_idx)
3186 {
3187         /* set as output */
3188         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3189                             pin_type);
3190         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3191                             AMP_OUT_UNMUTE);
3192         /* need the manual connection? */
3193         if (alc880_is_multi_pin(nid)) {
3194                 struct alc_spec *spec = codec->spec;
3195                 int idx = alc880_multi_pin_idx(nid);
3196                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3197                                     AC_VERB_SET_CONNECT_SEL,
3198                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3199         }
3200 }
3201
3202 static int get_pin_type(int line_out_type)
3203 {
3204         if (line_out_type == AUTO_PIN_HP_OUT)
3205                 return PIN_HP;
3206         else
3207                 return PIN_OUT;
3208 }
3209
3210 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3211 {
3212         struct alc_spec *spec = codec->spec;
3213         int i;
3214         
3215         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3216         for (i = 0; i < spec->autocfg.line_outs; i++) {
3217                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3218                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3219                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3220         }
3221 }
3222
3223 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3224 {
3225         struct alc_spec *spec = codec->spec;
3226         hda_nid_t pin;
3227
3228         pin = spec->autocfg.speaker_pins[0];
3229         if (pin) /* connect to front */
3230                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3231         pin = spec->autocfg.hp_pins[0];
3232         if (pin) /* connect to front */
3233                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3234 }
3235
3236 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3237 {
3238         struct alc_spec *spec = codec->spec;
3239         int i;
3240
3241         for (i = 0; i < AUTO_PIN_LAST; i++) {
3242                 hda_nid_t nid = spec->autocfg.input_pins[i];
3243                 if (alc880_is_input_pin(nid)) {
3244                         snd_hda_codec_write(codec, nid, 0,
3245                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3246                                             i <= AUTO_PIN_FRONT_MIC ?
3247                                             PIN_VREF80 : PIN_IN);
3248                         if (nid != ALC880_PIN_CD_NID)
3249                                 snd_hda_codec_write(codec, nid, 0,
3250                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3251                                                     AMP_OUT_MUTE);
3252                 }
3253         }
3254 }
3255
3256 /* parse the BIOS configuration and set up the alc_spec */
3257 /* return 1 if successful, 0 if the proper config is not found,
3258  * or a negative error code
3259  */
3260 static int alc880_parse_auto_config(struct hda_codec *codec)
3261 {
3262         struct alc_spec *spec = codec->spec;
3263         int err;
3264         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3265
3266         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3267                                            alc880_ignore);
3268         if (err < 0)
3269                 return err;
3270         if (!spec->autocfg.line_outs)
3271                 return 0; /* can't find valid BIOS pin config */
3272
3273         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3274         if (err < 0)
3275                 return err;
3276         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3277         if (err < 0)
3278                 return err;
3279         err = alc880_auto_create_extra_out(spec,
3280                                            spec->autocfg.speaker_pins[0],
3281                                            "Speaker");
3282         if (err < 0)
3283                 return err;
3284         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3285                                            "Headphone");
3286         if (err < 0)
3287                 return err;
3288         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3289         if (err < 0)
3290                 return err;
3291
3292         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3293
3294         if (spec->autocfg.dig_out_pin)
3295                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3296         if (spec->autocfg.dig_in_pin)
3297                 spec->dig_in_nid = ALC880_DIGIN_NID;
3298
3299         if (spec->kctl_alloc)
3300                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3301
3302         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3303
3304         spec->num_mux_defs = 1;
3305         spec->input_mux = &spec->private_imux;
3306
3307         return 1;
3308 }
3309
3310 /* additional initialization for auto-configuration model */
3311 static void alc880_auto_init(struct hda_codec *codec)
3312 {
3313         alc880_auto_init_multi_out(codec);
3314         alc880_auto_init_extra_out(codec);
3315         alc880_auto_init_analog_input(codec);
3316 }
3317
3318 /*
3319  * OK, here we have finally the patch for ALC880
3320  */
3321
3322 static int patch_alc880(struct hda_codec *codec)
3323 {
3324         struct alc_spec *spec;
3325         int board_config;
3326         int err;
3327
3328         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3329         if (spec == NULL)
3330                 return -ENOMEM;
3331
3332         codec->spec = spec;
3333
3334         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3335                                                   alc880_models,
3336                                                   alc880_cfg_tbl);
3337         if (board_config < 0) {
3338                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3339                        "trying auto-probe from BIOS...\n");
3340                 board_config = ALC880_AUTO;
3341         }
3342
3343         if (board_config == ALC880_AUTO) {
3344                 /* automatic parse from the BIOS config */
3345                 err = alc880_parse_auto_config(codec);
3346                 if (err < 0) {
3347                         alc_free(codec);
3348                         return err;
3349                 } else if (!err) {
3350                         printk(KERN_INFO
3351                                "hda_codec: Cannot set up configuration "
3352                                "from BIOS.  Using 3-stack mode...\n");
3353                         board_config = ALC880_3ST;
3354                 }
3355         }
3356
3357         if (board_config != ALC880_AUTO)
3358                 setup_preset(spec, &alc880_presets[board_config]);
3359
3360         spec->stream_name_analog = "ALC880 Analog";
3361         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3362         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3363
3364         spec->stream_name_digital = "ALC880 Digital";
3365         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3366         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3367
3368         if (!spec->adc_nids && spec->input_mux) {
3369                 /* check whether NID 0x07 is valid */
3370                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3371                 /* get type */
3372                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3373                 if (wcap != AC_WID_AUD_IN) {
3374                         spec->adc_nids = alc880_adc_nids_alt;
3375                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3376                         spec->mixers[spec->num_mixers] =
3377                                 alc880_capture_alt_mixer;
3378                         spec->num_mixers++;
3379                 } else {
3380                         spec->adc_nids = alc880_adc_nids;
3381                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3382                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3383                         spec->num_mixers++;
3384                 }
3385         }
3386
3387         codec->patch_ops = alc_patch_ops;
3388         if (board_config == ALC880_AUTO)
3389                 spec->init_hook = alc880_auto_init;
3390 #ifdef CONFIG_SND_HDA_POWER_SAVE
3391         if (!spec->loopback.amplist)
3392                 spec->loopback.amplist = alc880_loopbacks;
3393 #endif
3394
3395         return 0;
3396 }
3397
3398
3399 /*
3400  * ALC260 support
3401  */
3402
3403 static hda_nid_t alc260_dac_nids[1] = {
3404         /* front */
3405         0x02,
3406 };
3407
3408 static hda_nid_t alc260_adc_nids[1] = {
3409         /* ADC0 */
3410         0x04,
3411 };
3412
3413 static hda_nid_t alc260_adc_nids_alt[1] = {
3414         /* ADC1 */
3415         0x05,
3416 };
3417
3418 static hda_nid_t alc260_hp_adc_nids[2] = {
3419         /* ADC1, 0 */
3420         0x05, 0x04
3421 };
3422
3423 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3424  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3425  */
3426 static hda_nid_t alc260_dual_adc_nids[2] = {
3427         /* ADC0, ADC1 */
3428         0x04, 0x05
3429 };
3430
3431 #define ALC260_DIGOUT_NID       0x03
3432 #define ALC260_DIGIN_NID        0x06
3433
3434 static struct hda_input_mux alc260_capture_source = {
3435         .num_items = 4,
3436         .items = {
3437                 { "Mic", 0x0 },
3438                 { "Front Mic", 0x1 },
3439                 { "Line", 0x2 },
3440                 { "CD", 0x4 },
3441         },
3442 };
3443
3444 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3445  * headphone jack and the internal CD lines since these are the only pins at
3446  * which audio can appear.  For flexibility, also allow the option of
3447  * recording the mixer output on the second ADC (ADC0 doesn't have a
3448  * connection to the mixer output).
3449  */
3450 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3451         {
3452                 .num_items = 3,
3453                 .items = {
3454                         { "Mic/Line", 0x0 },
3455                         { "CD", 0x4 },
3456                         { "Headphone", 0x2 },
3457                 },
3458         },
3459         {
3460                 .num_items = 4,
3461                 .items = {
3462                         { "Mic/Line", 0x0 },
3463                         { "CD", 0x4 },
3464                         { "Headphone", 0x2 },
3465                         { "Mixer", 0x5 },
3466                 },
3467         },
3468
3469 };
3470
3471 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3472  * the Fujitsu S702x, but jacks are marked differently.
3473  */
3474 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3475         {
3476                 .num_items = 4,
3477                 .items = {
3478                         { "Mic", 0x0 },
3479                         { "Line", 0x2 },
3480                         { "CD", 0x4 },
3481                         { "Headphone", 0x5 },
3482                 },
3483         },
3484         {
3485                 .num_items = 5,
3486                 .items = {
3487                         { "Mic", 0x0 },
3488                         { "Line", 0x2 },
3489                         { "CD", 0x4 },
3490                         { "Headphone", 0x6 },
3491                         { "Mixer", 0x5 },
3492                 },
3493         },
3494 };
3495 /*
3496  * This is just place-holder, so there's something for alc_build_pcms to look
3497  * at when it calculates the maximum number of channels. ALC260 has no mixer
3498  * element which allows changing the channel mode, so the verb list is
3499  * never used.
3500  */
3501 static struct hda_channel_mode alc260_modes[1] = {
3502         { 2, NULL },
3503 };
3504
3505
3506 /* Mixer combinations
3507  *
3508  * basic: base_output + input + pc_beep + capture
3509  * HP: base_output + input + capture_alt
3510  * HP_3013: hp_3013 + input + capture
3511  * fujitsu: fujitsu + capture
3512  * acer: acer + capture
3513  */
3514
3515 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3516         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3517         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3518         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3519         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3520         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3521         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3522         { } /* end */
3523 };
3524
3525 static struct snd_kcontrol_new alc260_input_mixer[] = {
3526         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3527         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3528         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3529         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3530         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3531         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3532         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3533         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3534         { } /* end */
3535 };
3536
3537 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3538         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3539         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3540         { } /* end */
3541 };
3542
3543 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3544         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3545         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3546         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3547         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3548         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3549         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3550         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3551         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3552         { } /* end */
3553 };
3554
3555 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3556  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3557  */
3558 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3559         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3560         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3561         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3562         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3563         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3564         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3565         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3566         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3567         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3568         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3569         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3570         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3571         { } /* end */
3572 };
3573
3574 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3575  * versions of the ALC260 don't act on requests to enable mic bias from NID
3576  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3577  * datasheet doesn't mention this restriction.  At this stage it's not clear
3578  * whether this behaviour is intentional or is a hardware bug in chip
3579  * revisions available in early 2006.  Therefore for now allow the
3580  * "Headphone Jack Mode" control to span all choices, but if it turns out
3581  * that the lack of mic bias for this NID is intentional we could change the
3582  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3583  *
3584  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3585  * don't appear to make the mic bias available from the "line" jack, even
3586  * though the NID used for this jack (0x14) can supply it.  The theory is
3587  * that perhaps Acer have included blocking capacitors between the ALC260
3588  * and the output jack.  If this turns out to be the case for all such
3589  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3590  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3591  *
3592  * The C20x Tablet series have a mono internal speaker which is controlled
3593  * via the chip's Mono sum widget and pin complex, so include the necessary
3594  * controls for such models.  On models without a "mono speaker" the control
3595  * won't do anything.
3596  */
3597 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3598         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3599         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3600         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3601         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3602                               HDA_OUTPUT),
3603         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3604                            HDA_INPUT),
3605         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3606         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3607         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3608         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3609         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3610         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3611         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3612         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3613         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3614         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3615         { } /* end */
3616 };
3617
3618 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3619  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3620  */
3621 static struct snd_kcontrol_new alc260_will_mixer[] = {
3622         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3623         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3624         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3625         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3626         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3627         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3628         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3629         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3630         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3631         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3632         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3633         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3634         { } /* end */
3635 };
3636
3637 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3638  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3639  */
3640 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3641         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3642         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3643         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3644         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3645         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3646         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3647         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3648         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3649         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3650         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3651         { } /* end */
3652 };
3653
3654 /* capture mixer elements */
3655 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3656         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3657         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3658         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3659         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3660         {
3661                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3662                 /* The multiple "Capture Source" controls confuse alsamixer
3663                  * So call somewhat different..
3664                  * FIXME: the controls appear in the "playback" view!
3665                  */
3666                 /* .name = "Capture Source", */
3667                 .name = "Input Source",
3668                 .count = 2,
3669                 .info = alc_mux_enum_info,
3670                 .get = alc_mux_enum_get,
3671                 .put = alc_mux_enum_put,
3672         },
3673         { } /* end */
3674 };
3675
3676 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3677         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3678         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3679         {
3680                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3681                 /* The multiple "Capture Source" controls confuse alsamixer
3682                  * So call somewhat different..
3683                  * FIXME: the controls appear in the "playback" view!
3684                  */
3685                 /* .name = "Capture Source", */
3686                 .name = "Input Source",
3687                 .count = 1,
3688                 .info = alc_mux_enum_info,
3689                 .get = alc_mux_enum_get,
3690                 .put = alc_mux_enum_put,
3691         },
3692         { } /* end */
3693 };
3694
3695 /*
3696  * initialization verbs
3697  */
3698 static struct hda_verb alc260_init_verbs[] = {
3699         /* Line In pin widget for input */
3700         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3701         /* CD pin widget for input */
3702         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3703         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3704         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3705         /* Mic2 (front panel) pin widget for input and vref at 80% */
3706         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3707         /* LINE-2 is used for line-out in rear */
3708         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3709         /* select line-out */
3710         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3711         /* LINE-OUT pin */
3712         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3713         /* enable HP */
3714         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3715         /* enable Mono */
3716         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3717         /* mute capture amp left and right */
3718         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3719         /* set connection select to line in (default select for this ADC) */
3720         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3721         /* mute capture amp left and right */
3722         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3723         /* set connection select to line in (default select for this ADC) */
3724         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3725         /* set vol=0 Line-Out mixer amp left and right */
3726         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3727         /* unmute pin widget amp left and right (no gain on this amp) */
3728         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3729         /* set vol=0 HP mixer amp left and right */
3730         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3731         /* unmute pin widget amp left and right (no gain on this amp) */
3732         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3733         /* set vol=0 Mono mixer amp left and right */
3734         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3735         /* unmute pin widget amp left and right (no gain on this amp) */
3736         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3737         /* unmute LINE-2 out pin */
3738         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3739         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3740          * Line In 2 = 0x03
3741          */
3742         /* mute analog inputs */
3743         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3744         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3745         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3746         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3747         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3748         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3749         /* mute Front out path */
3750         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3751         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3752         /* mute Headphone out path */
3753         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3754         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3755         /* mute Mono out path */
3756         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3757         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3758         { }
3759 };
3760
3761 #if 0 /* should be identical with alc260_init_verbs? */
3762 static struct hda_verb alc260_hp_init_verbs[] = {
3763         /* Headphone and output */
3764         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3765         /* mono output */
3766         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3767         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3768         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3769         /* Mic2 (front panel) pin widget for input and vref at 80% */
3770         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3771         /* Line In pin widget for input */
3772         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3773         /* Line-2 pin widget for output */
3774         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3775         /* CD pin widget for input */
3776         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3777         /* unmute amp left and right */
3778         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3779         /* set connection select to line in (default select for this ADC) */
3780         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3781         /* unmute Line-Out mixer amp left and right (volume = 0) */
3782         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3783         /* mute pin widget amp left and right (no gain on this amp) */
3784         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3785         /* unmute HP mixer amp left and right (volume = 0) */
3786         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3787         /* mute pin widget amp left and right (no gain on this amp) */
3788         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3789         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3790          * Line In 2 = 0x03
3791          */
3792         /* mute analog inputs */
3793         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3794         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3795         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3796         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3797         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3798         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3799         /* Unmute Front out path */
3800         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3801         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3802         /* Unmute Headphone out path */
3803         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3804         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3805         /* Unmute Mono out path */
3806         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3807         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3808         { }
3809 };
3810 #endif
3811
3812 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3813         /* Line out and output */
3814         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3815         /* mono output */
3816         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3817         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3818         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3819         /* Mic2 (front panel) pin widget for input and vref at 80% */
3820         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3821         /* Line In pin widget for input */
3822         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3823         /* Headphone pin widget for output */
3824         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3825         /* CD pin widget for input */
3826         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3827         /* unmute amp left and right */
3828         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3829         /* set connection select to line in (default select for this ADC) */
3830         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3831         /* unmute Line-Out mixer amp left and right (volume = 0) */
3832         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3833         /* mute pin widget amp left and right (no gain on this amp) */
3834         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3835         /* unmute HP mixer amp left and right (volume = 0) */
3836         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3837         /* mute pin widget amp left and right (no gain on this amp) */
3838         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3839         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3840          * Line In 2 = 0x03
3841          */
3842         /* mute analog inputs */
3843         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3844         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3845         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3846         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3847         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3848         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3849         /* Unmute Front out path */
3850         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3851         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3852         /* Unmute Headphone out path */
3853         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3854         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3855         /* Unmute Mono out path */
3856         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3857         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3858         { }
3859 };
3860
3861 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3862  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3863  * audio = 0x16, internal speaker = 0x10.
3864  */
3865 static struct hda_verb alc260_fujitsu_init_verbs[] = {
3866         /* Disable all GPIOs */
3867         {0x01, AC_VERB_SET_GPIO_MASK, 0},
3868         /* Internal speaker is connected to headphone pin */
3869         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3870         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3871         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3872         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3873         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3874         /* Ensure all other unused pins are disabled and muted. */
3875         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3876         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3877         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3878         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3879         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3880         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3881         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3882         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3883
3884         /* Disable digital (SPDIF) pins */
3885         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3886         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3887
3888         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
3889          * when acting as an output.
3890          */
3891         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3892
3893         /* Start with output sum widgets muted and their output gains at min */
3894         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3895         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3896         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3897         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3898         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3899         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3900         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3901         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3902         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3903
3904         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3905         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3906         /* Unmute Line1 pin widget output buffer since it starts as an output.
3907          * If the pin mode is changed by the user the pin mode control will
3908          * take care of enabling the pin's input/output buffers as needed.
3909          * Therefore there's no need to enable the input buffer at this
3910          * stage.
3911          */
3912         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3913         /* Unmute input buffer of pin widget used for Line-in (no equiv 
3914          * mixer ctrl)
3915          */
3916         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3917
3918         /* Mute capture amp left and right */
3919         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3920         /* Set ADC connection select to match default mixer setting - line 
3921          * in (on mic1 pin)
3922          */
3923         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3924
3925         /* Do the same for the second ADC: mute capture input amp and
3926          * set ADC connection to line in (on mic1 pin)
3927          */
3928         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3929         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3930
3931         /* Mute all inputs to mixer widget (even unconnected ones) */
3932         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3933         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3934         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3935         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3936         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3937         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3938         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3939         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3940
3941         { }
3942 };
3943
3944 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3945  * similar laptops (adapted from Fujitsu init verbs).
3946  */
3947 static struct hda_verb alc260_acer_init_verbs[] = {
3948         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3949          * the headphone jack.  Turn this on and rely on the standard mute
3950          * methods whenever the user wants to turn these outputs off.
3951          */
3952         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3953         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3954         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3955         /* Internal speaker/Headphone jack is connected to Line-out pin */
3956         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3957         /* Internal microphone/Mic jack is connected to Mic1 pin */
3958         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3959         /* Line In jack is connected to Line1 pin */
3960         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3961         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3962         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3963         /* Ensure all other unused pins are disabled and muted. */
3964         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3965         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3966         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3967         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3968         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3969         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3970         /* Disable digital (SPDIF) pins */
3971         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3972         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3973
3974         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
3975          * bus when acting as outputs.
3976          */
3977         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3978         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3979
3980         /* Start with output sum widgets muted and their output gains at min */
3981         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3982         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3983         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3984         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3985         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3986         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3987         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3988         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3989         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3990
3991         /* Unmute Line-out pin widget amp left and right
3992          * (no equiv mixer ctrl)
3993          */
3994         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3995         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3996         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3997         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3998          * inputs. If the pin mode is changed by the user the pin mode control
3999          * will take care of enabling the pin's input/output buffers as needed.
4000          * Therefore there's no need to enable the input buffer at this
4001          * stage.
4002          */
4003         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4004         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4005
4006         /* Mute capture amp left and right */
4007         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4008         /* Set ADC connection select to match default mixer setting - mic
4009          * (on mic1 pin)
4010          */
4011         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4012
4013         /* Do similar with the second ADC: mute capture input amp and
4014          * set ADC connection to mic to match ALSA's default state.
4015          */
4016         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4017         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4018
4019         /* Mute all inputs to mixer widget (even unconnected ones) */
4020         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4021         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4022         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4023         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4024         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4025         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4026         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4027         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4028
4029         { }
4030 };
4031
4032 static struct hda_verb alc260_will_verbs[] = {
4033         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4034         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4035         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4036         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4037         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4038         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4039         {}
4040 };
4041
4042 static struct hda_verb alc260_replacer_672v_verbs[] = {
4043         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4044         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4045         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4046
4047         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4048         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4049         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4050
4051         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4052         {}
4053 };
4054
4055 /* toggle speaker-output according to the hp-jack state */
4056 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4057 {
4058         unsigned int present;
4059
4060         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4061         present = snd_hda_codec_read(codec, 0x0f, 0,
4062                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4063         if (present) {
4064                 snd_hda_codec_write_cache(codec, 0x01, 0,
4065                                           AC_VERB_SET_GPIO_DATA, 1);
4066                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4067                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4068                                           PIN_HP);
4069         } else {
4070                 snd_hda_codec_write_cache(codec, 0x01, 0,
4071                                           AC_VERB_SET_GPIO_DATA, 0);
4072                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4073                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4074                                           PIN_OUT);
4075         }
4076 }
4077
4078 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4079                                        unsigned int res)
4080 {
4081         if ((res >> 26) == ALC880_HP_EVENT)
4082                 alc260_replacer_672v_automute(codec);
4083 }
4084
4085 /* Test configuration for debugging, modelled after the ALC880 test
4086  * configuration.
4087  */
4088 #ifdef CONFIG_SND_DEBUG
4089 static hda_nid_t alc260_test_dac_nids[1] = {
4090         0x02,
4091 };
4092 static hda_nid_t alc260_test_adc_nids[2] = {
4093         0x04, 0x05,
4094 };
4095 /* For testing the ALC260, each input MUX needs its own definition since
4096  * the signal assignments are different.  This assumes that the first ADC 
4097  * is NID 0x04.
4098  */
4099 static struct hda_input_mux alc260_test_capture_sources[2] = {
4100         {
4101                 .num_items = 7,
4102                 .items = {
4103                         { "MIC1 pin", 0x0 },
4104                         { "MIC2 pin", 0x1 },
4105                         { "LINE1 pin", 0x2 },
4106                         { "LINE2 pin", 0x3 },
4107                         { "CD pin", 0x4 },
4108                         { "LINE-OUT pin", 0x5 },
4109                         { "HP-OUT pin", 0x6 },
4110                 },
4111         },
4112         {
4113                 .num_items = 8,
4114                 .items = {
4115                         { "MIC1 pin", 0x0 },
4116                         { "MIC2 pin", 0x1 },
4117                         { "LINE1 pin", 0x2 },
4118                         { "LINE2 pin", 0x3 },
4119                         { "CD pin", 0x4 },
4120                         { "Mixer", 0x5 },
4121                         { "LINE-OUT pin", 0x6 },
4122                         { "HP-OUT pin", 0x7 },
4123                 },
4124         },
4125 };
4126 static struct snd_kcontrol_new alc260_test_mixer[] = {
4127         /* Output driver widgets */
4128         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4129         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4130         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4131         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4132         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4133         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4134
4135         /* Modes for retasking pin widgets
4136          * Note: the ALC260 doesn't seem to act on requests to enable mic
4137          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4138          * mention this restriction.  At this stage it's not clear whether
4139          * this behaviour is intentional or is a hardware bug in chip
4140          * revisions available at least up until early 2006.  Therefore for
4141          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4142          * choices, but if it turns out that the lack of mic bias for these
4143          * NIDs is intentional we could change their modes from
4144          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4145          */
4146         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4147         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4148         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4149         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4150         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4151         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4152
4153         /* Loopback mixer controls */
4154         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4155         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4156         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4157         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4158         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4159         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4160         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4161         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4162         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4163         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4164         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4165         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4166         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4167         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4168         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4169         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4170
4171         /* Controls for GPIO pins, assuming they are configured as outputs */
4172         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4173         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4174         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4175         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4176
4177         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4178          * is ambigious as to which NID is which; testing on laptops which
4179          * make this output available should provide clarification. 
4180          */
4181         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4182         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4183
4184         { } /* end */
4185 };
4186 static struct hda_verb alc260_test_init_verbs[] = {
4187         /* Enable all GPIOs as outputs with an initial value of 0 */
4188         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4189         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4190         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4191
4192         /* Enable retasking pins as output, initially without power amp */
4193         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4194         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4195         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4196         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4197         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4198         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4199
4200         /* Disable digital (SPDIF) pins initially, but users can enable
4201          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4202          * payload also sets the generation to 0, output to be in "consumer"
4203          * PCM format, copyright asserted, no pre-emphasis and no validity
4204          * control.
4205          */
4206         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4207         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4208
4209         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4210          * OUT1 sum bus when acting as an output.
4211          */
4212         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4213         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4214         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4215         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4216
4217         /* Start with output sum widgets muted and their output gains at min */
4218         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4219         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4220         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4221         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4222         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4223         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4224         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4225         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4226         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4227
4228         /* Unmute retasking pin widget output buffers since the default
4229          * state appears to be output.  As the pin mode is changed by the
4230          * user the pin mode control will take care of enabling the pin's
4231          * input/output buffers as needed.
4232          */
4233         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4234         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4235         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4236         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4237         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4238         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4239         /* Also unmute the mono-out pin widget */
4240         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4241
4242         /* Mute capture amp left and right */
4243         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4244         /* Set ADC connection select to match default mixer setting (mic1
4245          * pin)
4246          */
4247         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4248
4249         /* Do the same for the second ADC: mute capture input amp and
4250          * set ADC connection to mic1 pin
4251          */
4252         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4253         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4254
4255         /* Mute all inputs to mixer widget (even unconnected ones) */
4256         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4257         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4258         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4259         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4260         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4261         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4262         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4263         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4264
4265         { }
4266 };
4267 #endif
4268
4269 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4270         .substreams = 1,
4271         .channels_min = 2,
4272         .channels_max = 2,
4273 };
4274
4275 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4276         .substreams = 1,
4277         .channels_min = 2,
4278         .channels_max = 2,
4279 };
4280
4281 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4282 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4283
4284 /*
4285  * for BIOS auto-configuration
4286  */
4287
4288 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4289                                         const char *pfx)
4290 {
4291         hda_nid_t nid_vol;
4292         unsigned long vol_val, sw_val;
4293         char name[32];
4294         int err;
4295
4296         if (nid >= 0x0f && nid < 0x11) {
4297                 nid_vol = nid - 0x7;
4298                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4299                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4300         } else if (nid == 0x11) {
4301                 nid_vol = nid - 0x7;
4302                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4303                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4304         } else if (nid >= 0x12 && nid <= 0x15) {
4305                 nid_vol = 0x08;
4306                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4307                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4308         } else
4309                 return 0; /* N/A */
4310         
4311         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4312         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4313         if (err < 0)
4314                 return err;
4315         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4316         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4317         if (err < 0)
4318                 return err;
4319         return 1;
4320 }
4321
4322 /* add playback controls from the parsed DAC table */
4323 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4324                                              const struct auto_pin_cfg *cfg)
4325 {
4326         hda_nid_t nid;
4327         int err;
4328
4329         spec->multiout.num_dacs = 1;
4330         spec->multiout.dac_nids = spec->private_dac_nids;
4331         spec->multiout.dac_nids[0] = 0x02;
4332
4333         nid = cfg->line_out_pins[0];
4334         if (nid) {
4335                 err = alc260_add_playback_controls(spec, nid, "Front");
4336                 if (err < 0)
4337                         return err;
4338         }
4339
4340         nid = cfg->speaker_pins[0];
4341         if (nid) {
4342                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4343                 if (err < 0)
4344                         return err;
4345         }
4346
4347         nid = cfg->hp_pins[0];
4348         if (nid) {
4349                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4350                 if (err < 0)
4351                         return err;
4352         }
4353         return 0;
4354 }
4355
4356 /* create playback/capture controls for input pins */
4357 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4358                                                 const struct auto_pin_cfg *cfg)
4359 {
4360         struct hda_input_mux *imux = &spec->private_imux;
4361         int i, err, idx;
4362
4363         for (i = 0; i < AUTO_PIN_LAST; i++) {
4364                 if (cfg->input_pins[i] >= 0x12) {
4365                         idx = cfg->input_pins[i] - 0x12;
4366                         err = new_analog_input(spec, cfg->input_pins[i],
4367                                                auto_pin_cfg_labels[i], idx,
4368                                                0x07);
4369                         if (err < 0)
4370                                 return err;
4371                         imux->items[imux->num_items].label =
4372                                 auto_pin_cfg_labels[i];
4373                         imux->items[imux->num_items].index = idx;
4374                         imux->num_items++;
4375                 }
4376                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4377                         idx = cfg->input_pins[i] - 0x09;
4378                         err = new_analog_input(spec, cfg->input_pins[i],
4379                                                auto_pin_cfg_labels[i], idx,
4380                                                0x07);
4381                         if (err < 0)
4382                                 return err;
4383                         imux->items[imux->num_items].label =
4384                                 auto_pin_cfg_labels[i];
4385                         imux->items[imux->num_items].index = idx;
4386                         imux->num_items++;
4387                 }
4388         }
4389         return 0;
4390 }
4391
4392 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4393                                               hda_nid_t nid, int pin_type,
4394                                               int sel_idx)
4395 {
4396         /* set as output */
4397         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4398                             pin_type);
4399         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4400                             AMP_OUT_UNMUTE);
4401         /* need the manual connection? */
4402         if (nid >= 0x12) {
4403                 int idx = nid - 0x12;
4404                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4405                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4406         }
4407 }
4408
4409 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4410 {
4411         struct alc_spec *spec = codec->spec;
4412         hda_nid_t nid;
4413
4414         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4415         nid = spec->autocfg.line_out_pins[0];
4416         if (nid) {
4417                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4418                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4419         }
4420         
4421         nid = spec->autocfg.speaker_pins[0];
4422         if (nid)
4423                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4424
4425         nid = spec->autocfg.hp_pins[0];
4426         if (nid)
4427                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4428 }
4429
4430 #define ALC260_PIN_CD_NID               0x16
4431 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4432 {
4433         struct alc_spec *spec = codec->spec;
4434         int i;
4435
4436         for (i = 0; i < AUTO_PIN_LAST; i++) {
4437                 hda_nid_t nid = spec->autocfg.input_pins[i];
4438                 if (nid >= 0x12) {
4439                         snd_hda_codec_write(codec, nid, 0,
4440                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4441                                             i <= AUTO_PIN_FRONT_MIC ?
4442                                             PIN_VREF80 : PIN_IN);
4443                         if (nid != ALC260_PIN_CD_NID)
4444                                 snd_hda_codec_write(codec, nid, 0,
4445                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4446                                                     AMP_OUT_MUTE);
4447                 }
4448         }
4449 }
4450
4451 /*
4452  * generic initialization of ADC, input mixers and output mixers
4453  */
4454 static struct hda_verb alc260_volume_init_verbs[] = {
4455         /*
4456          * Unmute ADC0-1 and set the default input to mic-in
4457          */
4458         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4459         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4460         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4461         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4462         
4463         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4464          * mixer widget
4465          * Note: PASD motherboards uses the Line In 2 as the input for
4466          * front panel mic (mic 2)
4467          */
4468         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4469         /* mute analog inputs */
4470         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4471         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4472         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4473         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4474         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4475
4476         /*
4477          * Set up output mixers (0x08 - 0x0a)
4478          */
4479         /* set vol=0 to output mixers */
4480         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4481         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4482         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4483         /* set up input amps for analog loopback */
4484         /* Amp Indices: DAC = 0, mixer = 1 */
4485         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4486         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4487         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4488         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4489         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4490         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4491         
4492         { }
4493 };
4494
4495 static int alc260_parse_auto_config(struct hda_codec *codec)
4496 {
4497         struct alc_spec *spec = codec->spec;
4498         unsigned int wcap;
4499         int err;
4500         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4501
4502         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4503                                            alc260_ignore);
4504         if (err < 0)
4505                 return err;
4506         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4507         if (err < 0)
4508                 return err;
4509         if (!spec->kctl_alloc)
4510                 return 0; /* can't find valid BIOS pin config */
4511         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4512         if (err < 0)
4513                 return err;
4514
4515         spec->multiout.max_channels = 2;
4516
4517         if (spec->autocfg.dig_out_pin)
4518                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4519         if (spec->kctl_alloc)
4520                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4521
4522         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4523
4524         spec->num_mux_defs = 1;
4525         spec->input_mux = &spec->private_imux;
4526
4527         /* check whether NID 0x04 is valid */
4528         wcap = get_wcaps(codec, 0x04);
4529         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4530         if (wcap != AC_WID_AUD_IN) {
4531                 spec->adc_nids = alc260_adc_nids_alt;
4532                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4533                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4534         } else {
4535                 spec->adc_nids = alc260_adc_nids;
4536                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4537                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4538         }
4539         spec->num_mixers++;
4540
4541         return 1;
4542 }
4543
4544 /* additional initialization for auto-configuration model */
4545 static void alc260_auto_init(struct hda_codec *codec)
4546 {
4547         alc260_auto_init_multi_out(codec);
4548         alc260_auto_init_analog_input(codec);
4549 }
4550
4551 #ifdef CONFIG_SND_HDA_POWER_SAVE
4552 static struct hda_amp_list alc260_loopbacks[] = {
4553         { 0x07, HDA_INPUT, 0 },
4554         { 0x07, HDA_INPUT, 1 },
4555         { 0x07, HDA_INPUT, 2 },
4556         { 0x07, HDA_INPUT, 3 },
4557         { 0x07, HDA_INPUT, 4 },
4558         { } /* end */
4559 };
4560 #endif
4561
4562 /*
4563  * ALC260 configurations
4564  */
4565 static const char *alc260_models[ALC260_MODEL_LAST] = {
4566         [ALC260_BASIC]          = "basic",
4567         [ALC260_HP]             = "hp",
4568         [ALC260_HP_3013]        = "hp-3013",
4569         [ALC260_FUJITSU_S702X]  = "fujitsu",
4570         [ALC260_ACER]           = "acer",
4571         [ALC260_WILL]           = "will",
4572         [ALC260_REPLACER_672V]  = "replacer",
4573 #ifdef CONFIG_SND_DEBUG
4574         [ALC260_TEST]           = "test",
4575 #endif
4576         [ALC260_AUTO]           = "auto",
4577 };
4578
4579 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4580         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4581         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4582         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4583         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4584         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4585         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4586         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4587         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4588         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4589         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4590         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4591         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4592         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4593         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4594         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4595         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4596         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4597         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4598         {}
4599 };
4600
4601 static struct alc_config_preset alc260_presets[] = {
4602         [ALC260_BASIC] = {
4603                 .mixers = { alc260_base_output_mixer,
4604                             alc260_input_mixer,
4605                             alc260_pc_beep_mixer,
4606                             alc260_capture_mixer },
4607                 .init_verbs = { alc260_init_verbs },
4608                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4609                 .dac_nids = alc260_dac_nids,
4610                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4611                 .adc_nids = alc260_adc_nids,
4612                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4613                 .channel_mode = alc260_modes,
4614                 .input_mux = &alc260_capture_source,
4615         },
4616         [ALC260_HP] = {
4617                 .mixers = { alc260_base_output_mixer,
4618                             alc260_input_mixer,
4619                             alc260_capture_alt_mixer },
4620                 .init_verbs = { alc260_init_verbs },
4621                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4622                 .dac_nids = alc260_dac_nids,
4623                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4624                 .adc_nids = alc260_hp_adc_nids,
4625                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4626                 .channel_mode = alc260_modes,
4627                 .input_mux = &alc260_capture_source,
4628         },
4629         [ALC260_HP_3013] = {
4630                 .mixers = { alc260_hp_3013_mixer,
4631                             alc260_input_mixer,
4632                             alc260_capture_alt_mixer },
4633                 .init_verbs = { alc260_hp_3013_init_verbs },
4634                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4635                 .dac_nids = alc260_dac_nids,
4636                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4637                 .adc_nids = alc260_hp_adc_nids,
4638                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4639                 .channel_mode = alc260_modes,
4640                 .input_mux = &alc260_capture_source,
4641         },
4642         [ALC260_FUJITSU_S702X] = {
4643                 .mixers = { alc260_fujitsu_mixer,
4644                             alc260_capture_mixer },
4645                 .init_verbs = { alc260_fujitsu_init_verbs },
4646                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4647                 .dac_nids = alc260_dac_nids,
4648                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4649                 .adc_nids = alc260_dual_adc_nids,
4650                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4651                 .channel_mode = alc260_modes,
4652                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4653                 .input_mux = alc260_fujitsu_capture_sources,
4654         },
4655         [ALC260_ACER] = {
4656                 .mixers = { alc260_acer_mixer,
4657                             alc260_capture_mixer },
4658                 .init_verbs = { alc260_acer_init_verbs },
4659                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4660                 .dac_nids = alc260_dac_nids,
4661                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4662                 .adc_nids = alc260_dual_adc_nids,
4663                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4664                 .channel_mode = alc260_modes,
4665                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4666                 .input_mux = alc260_acer_capture_sources,
4667         },
4668         [ALC260_WILL] = {
4669                 .mixers = { alc260_will_mixer,
4670                             alc260_capture_mixer },
4671                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4672                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4673                 .dac_nids = alc260_dac_nids,
4674                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4675                 .adc_nids = alc260_adc_nids,
4676                 .dig_out_nid = ALC260_DIGOUT_NID,
4677                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4678                 .channel_mode = alc260_modes,
4679                 .input_mux = &alc260_capture_source,
4680         },
4681         [ALC260_REPLACER_672V] = {
4682                 .mixers = { alc260_replacer_672v_mixer,
4683                             alc260_capture_mixer },
4684                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4685                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4686                 .dac_nids = alc260_dac_nids,
4687                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4688                 .adc_nids = alc260_adc_nids,
4689                 .dig_out_nid = ALC260_DIGOUT_NID,
4690                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4691                 .channel_mode = alc260_modes,
4692                 .input_mux = &alc260_capture_source,
4693                 .unsol_event = alc260_replacer_672v_unsol_event,
4694                 .init_hook = alc260_replacer_672v_automute,
4695         },
4696 #ifdef CONFIG_SND_DEBUG
4697         [ALC260_TEST] = {
4698                 .mixers = { alc260_test_mixer,
4699                             alc260_capture_mixer },
4700                 .init_verbs = { alc260_test_init_verbs },
4701                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4702                 .dac_nids = alc260_test_dac_nids,
4703                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4704                 .adc_nids = alc260_test_adc_nids,
4705                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4706                 .channel_mode = alc260_modes,
4707                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4708                 .input_mux = alc260_test_capture_sources,
4709         },
4710 #endif
4711 };
4712
4713 static int patch_alc260(struct hda_codec *codec)
4714 {
4715         struct alc_spec *spec;
4716         int err, board_config;
4717
4718         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4719         if (spec == NULL)
4720                 return -ENOMEM;
4721
4722         codec->spec = spec;
4723
4724         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4725                                                   alc260_models,
4726                                                   alc260_cfg_tbl);
4727         if (board_config < 0) {
4728                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4729                            "trying auto-probe from BIOS...\n");
4730                 board_config = ALC260_AUTO;
4731         }
4732
4733         if (board_config == ALC260_AUTO) {
4734                 /* automatic parse from the BIOS config */
4735                 err = alc260_parse_auto_config(codec);
4736                 if (err < 0) {
4737                         alc_free(codec);
4738                         return err;
4739                 } else if (!err) {
4740                         printk(KERN_INFO
4741                                "hda_codec: Cannot set up configuration "
4742                                "from BIOS.  Using base mode...\n");
4743                         board_config = ALC260_BASIC;
4744                 }
4745         }
4746
4747         if (board_config != ALC260_AUTO)
4748                 setup_preset(spec, &alc260_presets[board_config]);
4749
4750         spec->stream_name_analog = "ALC260 Analog";
4751         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4752         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4753
4754         spec->stream_name_digital = "ALC260 Digital";
4755         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4756         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4757
4758         codec->patch_ops = alc_patch_ops;
4759         if (board_config == ALC260_AUTO)
4760                 spec->init_hook = alc260_auto_init;
4761 #ifdef CONFIG_SND_HDA_POWER_SAVE
4762         if (!spec->loopback.amplist)
4763                 spec->loopback.amplist = alc260_loopbacks;
4764 #endif
4765
4766         return 0;
4767 }
4768
4769
4770 /*
4771  * ALC882 support
4772  *
4773  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4774  * configuration.  Each pin widget can choose any input DACs and a mixer.
4775  * Each ADC is connected from a mixer of all inputs.  This makes possible
4776  * 6-channel independent captures.
4777  *
4778  * In addition, an independent DAC for the multi-playback (not used in this
4779  * driver yet).
4780  */
4781 #define ALC882_DIGOUT_NID       0x06
4782 #define ALC882_DIGIN_NID        0x0a
4783
4784 static struct hda_channel_mode alc882_ch_modes[1] = {
4785         { 8, NULL }
4786 };
4787
4788 static hda_nid_t alc882_dac_nids[4] = {
4789         /* front, rear, clfe, rear_surr */
4790         0x02, 0x03, 0x04, 0x05
4791 };
4792
4793 /* identical with ALC880 */
4794 #define alc882_adc_nids         alc880_adc_nids
4795 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4796
4797 /* input MUX */
4798 /* FIXME: should be a matrix-type input source selection */
4799
4800 static struct hda_input_mux alc882_capture_source = {
4801         .num_items = 4,
4802         .items = {
4803                 { "Mic", 0x0 },
4804                 { "Front Mic", 0x1 },
4805                 { "Line", 0x2 },
4806                 { "CD", 0x4 },
4807         },
4808 };
4809 #define alc882_mux_enum_info alc_mux_enum_info
4810 #define alc882_mux_enum_get alc_mux_enum_get
4811
4812 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4813                                struct snd_ctl_elem_value *ucontrol)
4814 {
4815         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4816         struct alc_spec *spec = codec->spec;
4817         const struct hda_input_mux *imux = spec->input_mux;
4818         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4819         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4820         hda_nid_t nid = capture_mixers[adc_idx];
4821         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4822         unsigned int i, idx;
4823
4824         idx = ucontrol->value.enumerated.item[0];
4825         if (idx >= imux->num_items)
4826                 idx = imux->num_items - 1;
4827         if (*cur_val == idx)
4828                 return 0;
4829         for (i = 0; i < imux->num_items; i++) {
4830                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4831                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4832                                          imux->items[i].index,
4833                                          HDA_AMP_MUTE, v);
4834         }
4835         *cur_val = idx;
4836         return 1;
4837 }
4838
4839 /*
4840  * 2ch mode
4841  */
4842 static struct hda_verb alc882_3ST_ch2_init[] = {
4843         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4844         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4845         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4846         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4847         { } /* end */
4848 };
4849
4850 /*
4851  * 6ch mode
4852  */
4853 static struct hda_verb alc882_3ST_ch6_init[] = {
4854         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4855         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4856         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4857         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4858         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4859         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4860         { } /* end */
4861 };
4862
4863 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4864         { 2, alc882_3ST_ch2_init },
4865         { 6, alc882_3ST_ch6_init },
4866 };
4867
4868 /*
4869  * 6ch mode
4870  */
4871 static struct hda_verb alc882_sixstack_ch6_init[] = {
4872         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4873         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4874         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4875         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4876         { } /* end */
4877 };
4878
4879 /*
4880  * 8ch mode
4881  */
4882 static struct hda_verb alc882_sixstack_ch8_init[] = {
4883         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4884         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4885         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4886         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4887         { } /* end */
4888 };
4889
4890 static struct hda_channel_mode alc882_sixstack_modes[2] = {
4891         { 6, alc882_sixstack_ch6_init },
4892         { 8, alc882_sixstack_ch8_init },
4893 };
4894
4895 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4896  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4897  */
4898 static struct snd_kcontrol_new alc882_base_mixer[] = {
4899         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4900         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4901         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4902         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4903         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4904         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4905         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4906         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4907         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4908         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4909         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4910         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4911         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4912         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4913         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4914         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4915         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4916         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4917         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4918         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4919         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4920         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4921         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4922         { } /* end */
4923 };
4924
4925 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4926         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4927         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4928         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4929         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4930         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4931         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4932         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4933         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4934         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4935         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4936         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4937         { } /* end */
4938 };
4939
4940 static struct snd_kcontrol_new alc882_targa_mixer[] = {
4941         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4942         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4943         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4944         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4945         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4946         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4947         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4948         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4949         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4950         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4951         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4952         { } /* end */
4953 };
4954
4955 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4956  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4957  */
4958 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4959         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4960         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4961         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4962         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4963         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4964         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4965         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4966         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4967         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4968         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4969         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4970         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4971         { } /* end */
4972 };
4973
4974 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4975         {
4976                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4977                 .name = "Channel Mode",
4978                 .info = alc_ch_mode_info,
4979                 .get = alc_ch_mode_get,
4980                 .put = alc_ch_mode_put,
4981         },
4982         { } /* end */
4983 };
4984
4985 static struct hda_verb alc882_init_verbs[] = {
4986         /* Front mixer: unmute input/output amp left and right (volume = 0) */
4987         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4988         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4989         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4990         /* Rear mixer */
4991         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4992         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4993         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4994         /* CLFE mixer */
4995         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4996         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4997         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4998         /* Side mixer */
4999         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5000         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5001         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5002
5003         /* Front Pin: output 0 (0x0c) */
5004         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5005         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5006         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5007         /* Rear Pin: output 1 (0x0d) */
5008         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5009         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5010         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5011         /* CLFE Pin: output 2 (0x0e) */
5012         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5013         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5014         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5015         /* Side Pin: output 3 (0x0f) */
5016         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5017         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5018         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5019         /* Mic (rear) pin: input vref at 80% */
5020         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5021         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5022         /* Front Mic pin: input vref at 80% */
5023         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5024         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5025         /* Line In pin: input */
5026         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5027         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5028         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5029         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5030         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5031         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5032         /* CD pin widget for input */
5033         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5034
5035         /* FIXME: use matrix-type input source selection */
5036         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5037         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5038         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5039         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5040         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5041         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5042         /* Input mixer2 */
5043         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5044         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5045         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5046         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5047         /* Input mixer3 */
5048         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5049         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5050         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5051         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5052         /* ADC1: mute amp left and right */
5053         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5054         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5055         /* ADC2: mute amp left and right */
5056         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5057         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5058         /* ADC3: mute amp left and right */
5059         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5060         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5061
5062         { }
5063 };
5064
5065 static struct hda_verb alc882_eapd_verbs[] = {
5066         /* change to EAPD mode */
5067         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5068         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5069         { }
5070 };
5071
5072 /* Mac Pro test */
5073 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5074         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5075         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5076         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5077         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5078         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5079         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5080         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5081         { } /* end */
5082 };
5083
5084 static struct hda_verb alc882_macpro_init_verbs[] = {
5085         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5086         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5087         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5088         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5089         /* Front Pin: output 0 (0x0c) */
5090         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5091         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5092         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5093         /* Front Mic pin: input vref at 80% */
5094         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5095         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5096         /* Speaker:  output */
5097         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5098         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5099         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5100         /* Headphone output (output 0 - 0x0c) */
5101         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5102         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5103         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5104
5105         /* FIXME: use matrix-type input source selection */
5106         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5107         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5108         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5109         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5110         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5111         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5112         /* Input mixer2 */
5113         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5114         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5115         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5116         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5117         /* Input mixer3 */
5118         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5119         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5120         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5121         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5122         /* ADC1: mute amp left and right */
5123         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5124         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5125         /* ADC2: mute amp left and right */
5126         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5127         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5128         /* ADC3: mute amp left and right */
5129         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5130         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5131
5132         { }
5133 };
5134
5135 /* iMac 24 mixer. */
5136 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5137         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5138         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5139         { } /* end */
5140 };
5141
5142 /* iMac 24 init verbs. */
5143 static struct hda_verb alc885_imac24_init_verbs[] = {
5144         /* Internal speakers: output 0 (0x0c) */
5145         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5146         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5147         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5148         /* Internal speakers: output 0 (0x0c) */
5149         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5150         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5151         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5152         /* Headphone: output 0 (0x0c) */
5153         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5154         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5155         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5156         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5157         /* Front Mic: input vref at 80% */
5158         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5159         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5160         { }
5161 };
5162
5163 /* Toggle speaker-output according to the hp-jack state */
5164 static void alc885_imac24_automute(struct hda_codec *codec)
5165 {
5166         unsigned int present;
5167
5168         present = snd_hda_codec_read(codec, 0x14, 0,
5169                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5170         snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5171                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5172         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5173                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5174 }
5175
5176 /* Processes unsolicited events. */
5177 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5178                                       unsigned int res)
5179 {
5180         /* Headphone insertion or removal. */
5181         if ((res >> 26) == ALC880_HP_EVENT)
5182                 alc885_imac24_automute(codec);
5183 }
5184
5185 static struct hda_verb alc882_targa_verbs[] = {
5186         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5187         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5188
5189         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5190         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5191         
5192         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5193         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5194         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5195
5196         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5197         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5198         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5199         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5200         { } /* end */
5201 };
5202
5203 /* toggle speaker-output according to the hp-jack state */
5204 static void alc882_targa_automute(struct hda_codec *codec)
5205 {
5206         unsigned int present;
5207  
5208         present = snd_hda_codec_read(codec, 0x14, 0,
5209                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5210         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5211                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5212         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5213                                   present ? 1 : 3);
5214 }
5215
5216 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5217 {
5218         /* Looks like the unsol event is incompatible with the standard
5219          * definition.  4bit tag is placed at 26 bit!
5220          */
5221         if (((res >> 26) == ALC880_HP_EVENT)) {
5222                 alc882_targa_automute(codec);
5223         }
5224 }
5225
5226 static struct hda_verb alc882_asus_a7j_verbs[] = {
5227         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5228         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5229
5230         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5231         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5232         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5233         
5234         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5235         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5236         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5237
5238         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5239         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5240         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5241         { } /* end */
5242 };
5243
5244 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5245 {
5246         unsigned int gpiostate, gpiomask, gpiodir;
5247
5248         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5249                                        AC_VERB_GET_GPIO_DATA, 0);
5250
5251         if (!muted)
5252                 gpiostate |= (1 << pin);
5253         else
5254                 gpiostate &= ~(1 << pin);
5255
5256         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5257                                       AC_VERB_GET_GPIO_MASK, 0);
5258         gpiomask |= (1 << pin);
5259
5260         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5261                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5262         gpiodir |= (1 << pin);
5263
5264
5265         snd_hda_codec_write(codec, codec->afg, 0,
5266                             AC_VERB_SET_GPIO_MASK, gpiomask);
5267         snd_hda_codec_write(codec, codec->afg, 0,
5268                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5269
5270         msleep(1);
5271
5272         snd_hda_codec_write(codec, codec->afg, 0,
5273                             AC_VERB_SET_GPIO_DATA, gpiostate);
5274 }
5275
5276 /*
5277  * generic initialization of ADC, input mixers and output mixers
5278  */
5279 static struct hda_verb alc882_auto_init_verbs[] = {
5280         /*
5281          * Unmute ADC0-2 and set the default input to mic-in
5282          */
5283         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5284         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5285         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5286         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5287         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5288         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5289
5290         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5291          * mixer widget
5292          * Note: PASD motherboards uses the Line In 2 as the input for
5293          * front panel mic (mic 2)
5294          */
5295         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5296         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5297         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5298         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5299         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5300         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5301
5302         /*
5303          * Set up output mixers (0x0c - 0x0f)
5304          */
5305         /* set vol=0 to output mixers */
5306         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5307         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5308         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5309         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5310         /* set up input amps for analog loopback */
5311         /* Amp Indices: DAC = 0, mixer = 1 */
5312         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5313         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5314         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5315         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5316         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5317         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5318         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5319         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5320         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5321         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5322
5323         /* FIXME: use matrix-type input source selection */
5324         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5325         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5326         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5327         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5328         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5329         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5330         /* Input mixer2 */
5331         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5332         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5333         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5334         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5335         /* Input mixer3 */
5336         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5337         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5338         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5339         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5340
5341         { }
5342 };
5343
5344 /* capture mixer elements */
5345 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5346         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5347         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5348         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5349         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5350         {
5351                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5352                 /* The multiple "Capture Source" controls confuse alsamixer
5353                  * So call somewhat different..
5354                  * FIXME: the controls appear in the "playback" view!
5355                  */
5356                 /* .name = "Capture Source", */
5357                 .name = "Input Source",
5358                 .count = 2,
5359                 .info = alc882_mux_enum_info,
5360                 .get = alc882_mux_enum_get,
5361                 .put = alc882_mux_enum_put,
5362         },
5363         { } /* end */
5364 };
5365
5366 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5367         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5368         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5369         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5370         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5371         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5372         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5373         {
5374                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5375                 /* The multiple "Capture Source" controls confuse alsamixer
5376                  * So call somewhat different..
5377                  * FIXME: the controls appear in the "playback" view!
5378                  */
5379                 /* .name = "Capture Source", */
5380                 .name = "Input Source",
5381                 .count = 3,
5382                 .info = alc882_mux_enum_info,
5383                 .get = alc882_mux_enum_get,
5384                 .put = alc882_mux_enum_put,
5385         },
5386         { } /* end */
5387 };
5388
5389 #ifdef CONFIG_SND_HDA_POWER_SAVE
5390 #define alc882_loopbacks        alc880_loopbacks
5391 #endif
5392
5393 /* pcm configuration: identiacal with ALC880 */
5394 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5395 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5396 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5397 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5398
5399 /*
5400  * configuration and preset
5401  */
5402 static const char *alc882_models[ALC882_MODEL_LAST] = {
5403         [ALC882_3ST_DIG]        = "3stack-dig",
5404         [ALC882_6ST_DIG]        = "6stack-dig",
5405         [ALC882_ARIMA]          = "arima",
5406         [ALC882_W2JC]           = "w2jc",
5407         [ALC885_MACPRO]         = "macpro",
5408         [ALC885_IMAC24]         = "imac24",
5409         [ALC882_AUTO]           = "auto",
5410 };
5411
5412 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5413         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5414         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5415         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5416         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5417         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5418         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5419         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5420         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5421         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5422         {}
5423 };
5424
5425 static struct alc_config_preset alc882_presets[] = {
5426         [ALC882_3ST_DIG] = {
5427                 .mixers = { alc882_base_mixer },
5428                 .init_verbs = { alc882_init_verbs },
5429                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5430                 .dac_nids = alc882_dac_nids,
5431                 .dig_out_nid = ALC882_DIGOUT_NID,
5432                 .dig_in_nid = ALC882_DIGIN_NID,
5433                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5434                 .channel_mode = alc882_ch_modes,
5435                 .need_dac_fix = 1,
5436                 .input_mux = &alc882_capture_source,
5437         },
5438         [ALC882_6ST_DIG] = {
5439                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5440                 .init_verbs = { alc882_init_verbs },
5441                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5442                 .dac_nids = alc882_dac_nids,
5443                 .dig_out_nid = ALC882_DIGOUT_NID,
5444                 .dig_in_nid = ALC882_DIGIN_NID,
5445                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5446                 .channel_mode = alc882_sixstack_modes,
5447                 .input_mux = &alc882_capture_source,
5448         },
5449         [ALC882_ARIMA] = {
5450                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5451                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5452                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5453                 .dac_nids = alc882_dac_nids,
5454                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5455                 .channel_mode = alc882_sixstack_modes,
5456                 .input_mux = &alc882_capture_source,
5457         },
5458         [ALC882_W2JC] = {
5459                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5460                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5461                                 alc880_gpio1_init_verbs },
5462                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5463                 .dac_nids = alc882_dac_nids,
5464                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5465                 .channel_mode = alc880_threestack_modes,
5466                 .need_dac_fix = 1,
5467                 .input_mux = &alc882_capture_source,
5468                 .dig_out_nid = ALC882_DIGOUT_NID,
5469         },
5470         [ALC885_MACPRO] = {
5471                 .mixers = { alc882_macpro_mixer },
5472                 .init_verbs = { alc882_macpro_init_verbs },
5473                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5474                 .dac_nids = alc882_dac_nids,
5475                 .dig_out_nid = ALC882_DIGOUT_NID,
5476                 .dig_in_nid = ALC882_DIGIN_NID,
5477                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5478                 .channel_mode = alc882_ch_modes,
5479                 .input_mux = &alc882_capture_source,
5480         },
5481         [ALC885_IMAC24] = {
5482                 .mixers = { alc885_imac24_mixer },
5483                 .init_verbs = { alc885_imac24_init_verbs },
5484                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5485                 .dac_nids = alc882_dac_nids,
5486                 .dig_out_nid = ALC882_DIGOUT_NID,
5487                 .dig_in_nid = ALC882_DIGIN_NID,
5488                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5489                 .channel_mode = alc882_ch_modes,
5490                 .input_mux = &alc882_capture_source,
5491                 .unsol_event = alc885_imac24_unsol_event,
5492                 .init_hook = alc885_imac24_automute,
5493         },
5494         [ALC882_TARGA] = {
5495                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5496                             alc882_capture_mixer },
5497                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5498                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5499                 .dac_nids = alc882_dac_nids,
5500                 .dig_out_nid = ALC882_DIGOUT_NID,
5501                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5502                 .adc_nids = alc882_adc_nids,
5503                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5504                 .channel_mode = alc882_3ST_6ch_modes,
5505                 .need_dac_fix = 1,
5506                 .input_mux = &alc882_capture_source,
5507                 .unsol_event = alc882_targa_unsol_event,
5508                 .init_hook = alc882_targa_automute,
5509         },
5510         [ALC882_ASUS_A7J] = {
5511                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5512                             alc882_capture_mixer },
5513                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5514                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5515                 .dac_nids = alc882_dac_nids,
5516                 .dig_out_nid = ALC882_DIGOUT_NID,
5517                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5518                 .adc_nids = alc882_adc_nids,
5519                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5520                 .channel_mode = alc882_3ST_6ch_modes,
5521                 .need_dac_fix = 1,
5522                 .input_mux = &alc882_capture_source,
5523         },      
5524 };
5525
5526
5527 /*
5528  * Pin config fixes
5529  */
5530 enum { 
5531         PINFIX_ABIT_AW9D_MAX
5532 };
5533
5534 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5535         { 0x15, 0x01080104 }, /* side */
5536         { 0x16, 0x01011012 }, /* rear */
5537         { 0x17, 0x01016011 }, /* clfe */
5538         { }
5539 };
5540
5541 static const struct alc_pincfg *alc882_pin_fixes[] = {
5542         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5543 };
5544
5545 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5546         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5547         {}
5548 };
5549
5550 /*
5551  * BIOS auto configuration
5552  */
5553 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5554                                               hda_nid_t nid, int pin_type,
5555                                               int dac_idx)
5556 {
5557         /* set as output */
5558         struct alc_spec *spec = codec->spec;
5559         int idx;
5560
5561         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5562                 idx = 4;
5563         else
5564                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5565
5566         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5567                             pin_type);
5568         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5569                             AMP_OUT_UNMUTE);
5570         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5571
5572 }
5573
5574 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5575 {
5576         struct alc_spec *spec = codec->spec;
5577         int i;
5578
5579         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5580         for (i = 0; i <= HDA_SIDE; i++) {
5581                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5582                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5583                 if (nid)
5584                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5585                                                           i);
5586         }
5587 }
5588
5589 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5590 {
5591         struct alc_spec *spec = codec->spec;
5592         hda_nid_t pin;
5593
5594         pin = spec->autocfg.hp_pins[0];
5595         if (pin) /* connect to front */
5596                 /* use dac 0 */
5597                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5598 }
5599
5600 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5601 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5602
5603 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5604 {
5605         struct alc_spec *spec = codec->spec;
5606         int i;
5607
5608         for (i = 0; i < AUTO_PIN_LAST; i++) {
5609                 hda_nid_t nid = spec->autocfg.input_pins[i];
5610                 if (alc882_is_input_pin(nid)) {
5611                         snd_hda_codec_write(codec, nid, 0,
5612                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5613                                             i <= AUTO_PIN_FRONT_MIC ?
5614                                             PIN_VREF80 : PIN_IN);
5615                         if (nid != ALC882_PIN_CD_NID)
5616                                 snd_hda_codec_write(codec, nid, 0,
5617                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5618                                                     AMP_OUT_MUTE);
5619                 }
5620         }
5621 }
5622
5623 /* almost identical with ALC880 parser... */
5624 static int alc882_parse_auto_config(struct hda_codec *codec)
5625 {
5626         struct alc_spec *spec = codec->spec;
5627         int err = alc880_parse_auto_config(codec);
5628
5629         if (err < 0)
5630                 return err;
5631         else if (err > 0)
5632                 /* hack - override the init verbs */
5633                 spec->init_verbs[0] = alc882_auto_init_verbs;
5634         return err;
5635 }
5636
5637 /* additional initialization for auto-configuration model */
5638 static void alc882_auto_init(struct hda_codec *codec)
5639 {
5640         alc882_auto_init_multi_out(codec);
5641         alc882_auto_init_hp_out(codec);
5642         alc882_auto_init_analog_input(codec);
5643 }
5644
5645 static int patch_alc882(struct hda_codec *codec)
5646 {
5647         struct alc_spec *spec;
5648         int err, board_config;
5649
5650         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5651         if (spec == NULL)
5652                 return -ENOMEM;
5653
5654         codec->spec = spec;
5655
5656         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5657                                                   alc882_models,
5658                                                   alc882_cfg_tbl);
5659
5660         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5661                 /* Pick up systems that don't supply PCI SSID */
5662                 switch (codec->subsystem_id) {
5663                 case 0x106b0c00: /* Mac Pro */
5664                         board_config = ALC885_MACPRO;
5665                         break;
5666                 case 0x106b1000: /* iMac 24 */
5667                         board_config = ALC885_IMAC24;
5668                         break;
5669                 default:
5670                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5671                                          "trying auto-probe from BIOS...\n");
5672                         board_config = ALC882_AUTO;
5673                 }
5674         }
5675
5676         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5677
5678         if (board_config == ALC882_AUTO) {
5679                 /* automatic parse from the BIOS config */
5680                 err = alc882_parse_auto_config(codec);
5681                 if (err < 0) {
5682                         alc_free(codec);
5683                         return err;
5684                 } else if (!err) {
5685                         printk(KERN_INFO
5686                                "hda_codec: Cannot set up configuration "
5687                                "from BIOS.  Using base mode...\n");
5688                         board_config = ALC882_3ST_DIG;
5689                 }
5690         }
5691
5692         if (board_config != ALC882_AUTO)
5693                 setup_preset(spec, &alc882_presets[board_config]);
5694
5695         if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
5696                 alc882_gpio_mute(codec, 0, 0);
5697                 alc882_gpio_mute(codec, 1, 0);
5698         }
5699
5700         spec->stream_name_analog = "ALC882 Analog";
5701         spec->stream_analog_playback = &alc882_pcm_analog_playback;
5702         spec->stream_analog_capture = &alc882_pcm_analog_capture;
5703
5704         spec->stream_name_digital = "ALC882 Digital";
5705         spec->stream_digital_playback = &alc882_pcm_digital_playback;
5706         spec->stream_digital_capture = &alc882_pcm_digital_capture;
5707
5708         if (!spec->adc_nids && spec->input_mux) {
5709                 /* check whether NID 0x07 is valid */
5710                 unsigned int wcap = get_wcaps(codec, 0x07);
5711                 /* get type */
5712                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5713                 if (wcap != AC_WID_AUD_IN) {
5714                         spec->adc_nids = alc882_adc_nids_alt;
5715                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5716                         spec->mixers[spec->num_mixers] =
5717                                 alc882_capture_alt_mixer;
5718                         spec->num_mixers++;
5719                 } else {
5720                         spec->adc_nids = alc882_adc_nids;
5721                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5722                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5723                         spec->num_mixers++;
5724                 }
5725         }
5726
5727         codec->patch_ops = alc_patch_ops;
5728         if (board_config == ALC882_AUTO)
5729                 spec->init_hook = alc882_auto_init;
5730 #ifdef CONFIG_SND_HDA_POWER_SAVE
5731         if (!spec->loopback.amplist)
5732                 spec->loopback.amplist = alc882_loopbacks;
5733 #endif
5734
5735         return 0;
5736 }
5737
5738 /*
5739  * ALC883 support
5740  *
5741  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5742  * configuration.  Each pin widget can choose any input DACs and a mixer.
5743  * Each ADC is connected from a mixer of all inputs.  This makes possible
5744  * 6-channel independent captures.
5745  *
5746  * In addition, an independent DAC for the multi-playback (not used in this
5747  * driver yet).
5748  */
5749 #define ALC883_DIGOUT_NID       0x06
5750 #define ALC883_DIGIN_NID        0x0a
5751
5752 static hda_nid_t alc883_dac_nids[4] = {
5753         /* front, rear, clfe, rear_surr */
5754         0x02, 0x04, 0x03, 0x05
5755 };
5756
5757 static hda_nid_t alc883_adc_nids[2] = {
5758         /* ADC1-2 */
5759         0x08, 0x09,
5760 };
5761
5762 /* input MUX */
5763 /* FIXME: should be a matrix-type input source selection */
5764
5765 static struct hda_input_mux alc883_capture_source = {
5766         .num_items = 4,
5767         .items = {
5768                 { "Mic", 0x0 },
5769                 { "Front Mic", 0x1 },
5770                 { "Line", 0x2 },
5771                 { "CD", 0x4 },
5772         },
5773 };
5774
5775 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5776         .num_items = 2,
5777         .items = {
5778                 { "Mic", 0x1 },
5779                 { "Line", 0x2 },
5780         },
5781 };
5782
5783 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5784         .num_items = 4,
5785         .items = {
5786                 { "Mic", 0x0 },
5787                 { "iMic", 0x1 },
5788                 { "Line", 0x2 },
5789                 { "CD", 0x4 },
5790         },
5791 };
5792
5793 #define alc883_mux_enum_info alc_mux_enum_info
5794 #define alc883_mux_enum_get alc_mux_enum_get
5795
5796 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5797                                struct snd_ctl_elem_value *ucontrol)
5798 {
5799         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5800         struct alc_spec *spec = codec->spec;
5801         const struct hda_input_mux *imux = spec->input_mux;
5802         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5803         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5804         hda_nid_t nid = capture_mixers[adc_idx];
5805         unsigned int *cur_val = &spec->cur_mux[adc_idx];
5806         unsigned int i, idx;
5807
5808         idx = ucontrol->value.enumerated.item[0];
5809         if (idx >= imux->num_items)
5810                 idx = imux->num_items - 1;
5811         if (*cur_val == idx)
5812                 return 0;
5813         for (i = 0; i < imux->num_items; i++) {
5814                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5815                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5816                                          imux->items[i].index,
5817                                          HDA_AMP_MUTE, v);
5818         }
5819         *cur_val = idx;
5820         return 1;
5821 }
5822
5823 /*
5824  * 2ch mode
5825  */
5826 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5827         { 2, NULL }
5828 };
5829
5830 /*
5831  * 2ch mode
5832  */
5833 static struct hda_verb alc883_3ST_ch2_init[] = {
5834         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5835         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5836         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5837         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5838         { } /* end */
5839 };
5840
5841 /*
5842  * 6ch mode
5843  */
5844 static struct hda_verb alc883_3ST_ch6_init[] = {
5845         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5846         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5847         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5848         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5849         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5850         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5851         { } /* end */
5852 };
5853
5854 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5855         { 2, alc883_3ST_ch2_init },
5856         { 6, alc883_3ST_ch6_init },
5857 };
5858
5859 /*
5860  * 6ch mode
5861  */
5862 static struct hda_verb alc883_sixstack_ch6_init[] = {
5863         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5864         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5865         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5866         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5867         { } /* end */
5868 };
5869
5870 /*
5871  * 8ch mode
5872  */
5873 static struct hda_verb alc883_sixstack_ch8_init[] = {
5874         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5875         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5876         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5877         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5878         { } /* end */
5879 };
5880
5881 static struct hda_channel_mode alc883_sixstack_modes[2] = {
5882         { 6, alc883_sixstack_ch6_init },
5883         { 8, alc883_sixstack_ch8_init },
5884 };
5885
5886 static struct hda_verb alc883_medion_eapd_verbs[] = {
5887         /* eanable EAPD on medion laptop */
5888         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5889         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5890         { }
5891 };
5892
5893 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5894  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5895  */
5896
5897 static struct snd_kcontrol_new alc883_base_mixer[] = {
5898         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5899         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5900         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5901         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5902         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5903         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5904         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5905         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5906         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5907         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5908         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5909         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5910         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5911         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5912         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5913         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5914         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5915         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5916         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5917         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5918         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5919         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5920         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5921         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5922         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5923         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5924         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5925         {
5926                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5927                 /* .name = "Capture Source", */
5928                 .name = "Input Source",
5929                 .count = 2,
5930                 .info = alc883_mux_enum_info,
5931                 .get = alc883_mux_enum_get,
5932                 .put = alc883_mux_enum_put,
5933         },
5934         { } /* end */
5935 };
5936
5937 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5938         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5939         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5940         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5941         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5942         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5943         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5944         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5945         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5946         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5947         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5948         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5949         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5950         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5951         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5952         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5953         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5954         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5955         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5956         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5957         {
5958                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5959                 /* .name = "Capture Source", */
5960                 .name = "Input Source",
5961                 .count = 2,
5962                 .info = alc883_mux_enum_info,
5963                 .get = alc883_mux_enum_get,
5964                 .put = alc883_mux_enum_put,
5965         },
5966         { } /* end */
5967 };
5968
5969 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5970         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5971         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5972         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5973         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5974         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5975         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5976         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5977         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5978         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5979         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5980         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5981         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5982         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5983         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5984         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5985         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5986         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5987         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5988         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5989         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5990         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5991         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5992         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5993         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5994         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5995         {
5996                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5997                 /* .name = "Capture Source", */
5998                 .name = "Input Source",
5999                 .count = 2,
6000                 .info = alc883_mux_enum_info,
6001                 .get = alc883_mux_enum_get,
6002                 .put = alc883_mux_enum_put,
6003         },
6004         { } /* end */
6005 };
6006
6007 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6008         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6009         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6010         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6011         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6012         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6013         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6014         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6015         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6016         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6017         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6018         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6019         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6020         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6021         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6022         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6023         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6024         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6025         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6026         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6027         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6028         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6029         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6030         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6031
6032         {
6033                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6034                 /* .name = "Capture Source", */
6035                 .name = "Input Source",
6036                 .count = 1,
6037                 .info = alc883_mux_enum_info,
6038                 .get = alc883_mux_enum_get,
6039                 .put = alc883_mux_enum_put,
6040         },
6041         { } /* end */
6042 };
6043
6044 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6045         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6046         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6047         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6048         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6049         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6050         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6051         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6052         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6053         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6054         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6055         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6056         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6057         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6058         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6059         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6060         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6061         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6062         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6063         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6064         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6065         {
6066                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6067                 /* .name = "Capture Source", */
6068                 .name = "Input Source",
6069                 .count = 2,
6070                 .info = alc883_mux_enum_info,
6071                 .get = alc883_mux_enum_get,
6072                 .put = alc883_mux_enum_put,
6073         },
6074         { } /* end */
6075 };
6076
6077 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6078         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6079         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6080         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6081         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6082         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6083         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6084         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6085         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6086         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6087         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6088         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6089         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6090         {
6091                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6092                 /* .name = "Capture Source", */
6093                 .name = "Input Source",
6094                 .count = 2,
6095                 .info = alc883_mux_enum_info,
6096                 .get = alc883_mux_enum_get,
6097                 .put = alc883_mux_enum_put,
6098         },
6099         { } /* end */
6100 };
6101
6102 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6103         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6104         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6105         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6106         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6107         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6108         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6109         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6110         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6111         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6112         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6113         {
6114                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6115                 /* .name = "Capture Source", */
6116                 .name = "Input Source",
6117                 .count = 1,
6118                 .info = alc883_mux_enum_info,
6119                 .get = alc883_mux_enum_get,
6120                 .put = alc883_mux_enum_put,
6121         },
6122         { } /* end */
6123 };
6124
6125 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6126         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6127         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6128         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6129         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6130         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6131         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6132         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6133         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6134         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6135         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6136         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6137         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6138         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6139         {
6140                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6141                 /* .name = "Capture Source", */
6142                 .name = "Input Source",
6143                 .count = 2,
6144                 .info = alc883_mux_enum_info,
6145                 .get = alc883_mux_enum_get,
6146                 .put = alc883_mux_enum_put,
6147         },
6148         { } /* end */
6149 };
6150
6151 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6152         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6153         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6154         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6155         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6156         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6157         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6158         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6159         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6160         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6161         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6162         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6163         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6164         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6165         {
6166                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6167                 /* .name = "Capture Source", */
6168                 .name = "Input Source",
6169                 .count = 2,
6170                 .info = alc883_mux_enum_info,
6171                 .get = alc883_mux_enum_get,
6172                 .put = alc883_mux_enum_put,
6173         },
6174         { } /* end */
6175 };      
6176
6177 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6178         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6179         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6180         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6181         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6182         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6183         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6184         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6185         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6186         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6187         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6188         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6189         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6190         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6191         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6192         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6193         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6194         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6195         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6196         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6197         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6198         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6199         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6200         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6201         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6202         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6203         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6204         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6205         {
6206                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6207                 /* .name = "Capture Source", */
6208                 .name = "Input Source",
6209                 .count = 2,
6210                 .info = alc883_mux_enum_info,
6211                 .get = alc883_mux_enum_get,
6212                 .put = alc883_mux_enum_put,
6213         },
6214         { } /* end */
6215 };
6216
6217 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6218         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6219         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6220         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6221         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6222         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6223         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6224         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6225         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6226         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6227         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6228         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6229         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6230         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6231         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6232         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6233         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6234         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6235         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6236         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6237         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6238         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6239         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6240         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6241         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6242         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6243         {
6244                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6245                 /* .name = "Capture Source", */
6246                 .name = "Input Source",
6247                 .count = 2,
6248                 .info = alc883_mux_enum_info,
6249                 .get = alc883_mux_enum_get,
6250                 .put = alc883_mux_enum_put,
6251         },
6252         { } /* end */
6253 };
6254
6255 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6256         HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6257         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6258         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6259         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6260         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6261         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6262         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6263         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6264         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6265         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6266         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6267         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6268         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6269         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6270         {
6271                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6272                 /* .name = "Capture Source", */
6273                 .name = "Input Source",
6274                 .count = 2,
6275                 .info = alc883_mux_enum_info,
6276                 .get = alc883_mux_enum_get,
6277                 .put = alc883_mux_enum_put,
6278         },
6279         { } /* end */
6280 };      
6281
6282 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6283         {
6284                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6285                 .name = "Channel Mode",
6286                 .info = alc_ch_mode_info,
6287                 .get = alc_ch_mode_get,
6288                 .put = alc_ch_mode_put,
6289         },
6290         { } /* end */
6291 };
6292
6293 static struct hda_verb alc883_init_verbs[] = {
6294         /* ADC1: mute amp left and right */
6295         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6296         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6297         /* ADC2: mute amp left and right */
6298         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6299         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6300         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6301         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6302         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6303         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6304         /* Rear mixer */
6305         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6306         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6307         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6308         /* CLFE mixer */
6309         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6310         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6311         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6312         /* Side mixer */
6313         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6314         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6315         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6316
6317         /* mute analog input loopbacks */
6318         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6319         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6320         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6321         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6322         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6323
6324         /* Front Pin: output 0 (0x0c) */
6325         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6326         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6327         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6328         /* Rear Pin: output 1 (0x0d) */
6329         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6330         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6331         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6332         /* CLFE Pin: output 2 (0x0e) */
6333         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6334         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6335         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6336         /* Side Pin: output 3 (0x0f) */
6337         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6338         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6339         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6340         /* Mic (rear) pin: input vref at 80% */
6341         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6342         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6343         /* Front Mic pin: input vref at 80% */
6344         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6345         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6346         /* Line In pin: input */
6347         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6348         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6349         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6350         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6351         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6352         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6353         /* CD pin widget for input */
6354         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6355
6356         /* FIXME: use matrix-type input source selection */
6357         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6358         /* Input mixer2 */
6359         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6360         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6361         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6362         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6363         /* Input mixer3 */
6364         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6365         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6366         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6367         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6368         { }
6369 };
6370
6371 static struct hda_verb alc883_tagra_verbs[] = {
6372         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6373         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6374
6375         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6376         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6377         
6378         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6379         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6380         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6381
6382         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6383         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6384         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6385         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6386
6387         { } /* end */
6388 };
6389
6390 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6391         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6392         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6393         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6394         { } /* end */
6395 };
6396
6397 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6398         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6399         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6400         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6401         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6402         { } /* end */
6403 };
6404
6405 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6406         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6407         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6408         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6409         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6410         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6411         { } /* end */
6412 };
6413
6414 static struct hda_verb alc888_6st_hp_verbs[] = {
6415         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6416         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6417         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6418         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6419         { }
6420 };
6421
6422 static struct hda_verb alc888_3st_hp_verbs[] = {
6423         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6424         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6425         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6426         { }
6427 };
6428
6429 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6430         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6431         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6432         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6433         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6434         { }
6435 };
6436
6437 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6438         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6439         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6440         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6441         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6442         { }
6443 };
6444
6445 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6446         { 2, alc888_3st_hp_2ch_init },
6447         { 6, alc888_3st_hp_6ch_init },
6448 };
6449
6450 /* toggle front-jack and RCA according to the hp-jack state */
6451 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6452 {
6453         unsigned int present;
6454  
6455         present = snd_hda_codec_read(codec, 0x1b, 0,
6456                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6457         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6458                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6459         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6460                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6461 }
6462
6463 /* toggle RCA according to the front-jack state */
6464 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6465 {
6466         unsigned int present;
6467  
6468         present = snd_hda_codec_read(codec, 0x14, 0,
6469                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6470         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6471                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6472 }
6473
6474 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6475                                              unsigned int res)
6476 {
6477         if ((res >> 26) == ALC880_HP_EVENT)
6478                 alc888_lenovo_ms7195_front_automute(codec);
6479         if ((res >> 26) == ALC880_FRONT_EVENT)
6480                 alc888_lenovo_ms7195_rca_automute(codec);
6481 }
6482
6483 static struct hda_verb alc883_medion_md2_verbs[] = {
6484         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6485         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6486
6487         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6488
6489         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6490         { } /* end */
6491 };
6492
6493 static struct hda_verb alc883_acer_aspire_verbs[] = {
6494         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6495         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6496         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6497         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6498
6499         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6500
6501         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6502         { } /* end */
6503 };
6504
6505 /* toggle speaker-output according to the hp-jack state */
6506 static void alc883_medion_md2_automute(struct hda_codec *codec)
6507 {
6508         unsigned int present;
6509  
6510         present = snd_hda_codec_read(codec, 0x14, 0,
6511                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6512         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6513                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6514 }
6515
6516 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6517                                           unsigned int res)
6518 {
6519         if ((res >> 26) == ALC880_HP_EVENT)
6520                 alc883_medion_md2_automute(codec);
6521 }
6522
6523 /* toggle speaker-output according to the hp-jack state */
6524 static void alc883_tagra_automute(struct hda_codec *codec)
6525 {
6526         unsigned int present;
6527         unsigned char bits;
6528
6529         present = snd_hda_codec_read(codec, 0x14, 0,
6530                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6531         bits = present ? HDA_AMP_MUTE : 0;
6532         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6533                                  HDA_AMP_MUTE, bits);
6534         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6535                                   present ? 1 : 3);
6536 }
6537
6538 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6539 {
6540         if ((res >> 26) == ALC880_HP_EVENT)
6541                 alc883_tagra_automute(codec);
6542 }
6543
6544 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6545 {
6546         unsigned int present;
6547         unsigned char bits;
6548
6549         present = snd_hda_codec_read(codec, 0x14, 0,
6550                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6551         bits = present ? HDA_AMP_MUTE : 0;
6552         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6553                                  HDA_AMP_MUTE, bits);
6554 }
6555
6556 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6557 {
6558         unsigned int present;
6559         unsigned char bits;
6560
6561         present = snd_hda_codec_read(codec, 0x1b, 0,
6562                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6563         bits = present ? HDA_AMP_MUTE : 0;
6564         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6565                                  HDA_AMP_MUTE, bits);
6566         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6567                                  HDA_AMP_MUTE, bits);
6568 }
6569
6570 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6571                                            unsigned int res)
6572 {
6573         if ((res >> 26) == ALC880_HP_EVENT)
6574                 alc883_lenovo_101e_all_automute(codec);
6575         if ((res >> 26) == ALC880_FRONT_EVENT)
6576                 alc883_lenovo_101e_ispeaker_automute(codec);
6577 }
6578
6579 /*
6580  * generic initialization of ADC, input mixers and output mixers
6581  */
6582 static struct hda_verb alc883_auto_init_verbs[] = {
6583         /*
6584          * Unmute ADC0-2 and set the default input to mic-in
6585          */
6586         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6587         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6588         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6589         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6590
6591         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6592          * mixer widget
6593          * Note: PASD motherboards uses the Line In 2 as the input for
6594          * front panel mic (mic 2)
6595          */
6596         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6597         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6598         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6599         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6600         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6601         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6602
6603         /*
6604          * Set up output mixers (0x0c - 0x0f)
6605          */
6606         /* set vol=0 to output mixers */
6607         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6608         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6609         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6610         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6611         /* set up input amps for analog loopback */
6612         /* Amp Indices: DAC = 0, mixer = 1 */
6613         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6614         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6615         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6616         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6617         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6618         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6619         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6620         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6621         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6622         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6623
6624         /* FIXME: use matrix-type input source selection */
6625         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6626         /* Input mixer1 */
6627         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6628         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6629         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6630         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6631         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6632         /* Input mixer2 */
6633         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6634         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6635         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6636         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6637         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6638
6639         { }
6640 };
6641
6642 /* capture mixer elements */
6643 static struct snd_kcontrol_new alc883_capture_mixer[] = {
6644         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6645         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6646         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6647         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6648         {
6649                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6650                 /* The multiple "Capture Source" controls confuse alsamixer
6651                  * So call somewhat different..
6652                  * FIXME: the controls appear in the "playback" view!
6653                  */
6654                 /* .name = "Capture Source", */
6655                 .name = "Input Source",
6656                 .count = 2,
6657                 .info = alc882_mux_enum_info,
6658                 .get = alc882_mux_enum_get,
6659                 .put = alc882_mux_enum_put,
6660         },
6661         { } /* end */
6662 };
6663
6664 #ifdef CONFIG_SND_HDA_POWER_SAVE
6665 #define alc883_loopbacks        alc880_loopbacks
6666 #endif
6667
6668 /* pcm configuration: identiacal with ALC880 */
6669 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
6670 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
6671 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
6672 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
6673
6674 /*
6675  * configuration and preset
6676  */
6677 static const char *alc883_models[ALC883_MODEL_LAST] = {
6678         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
6679         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
6680         [ALC883_3ST_6ch]        = "3stack-6ch",
6681         [ALC883_6ST_DIG]        = "6stack-dig",
6682         [ALC883_TARGA_DIG]      = "targa-dig",
6683         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
6684         [ALC883_ACER]           = "acer",
6685         [ALC883_ACER_ASPIRE]    = "acer-aspire",
6686         [ALC883_MEDION]         = "medion",
6687         [ALC883_MEDION_MD2]     = "medion-md2",
6688         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
6689         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6690         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
6691         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6692         [ALC888_6ST_HP]         = "6stack-hp",
6693         [ALC888_3ST_HP]         = "3stack-hp",
6694         [ALC883_AUTO]           = "auto",
6695 };
6696
6697 static struct snd_pci_quirk alc883_cfg_tbl[] = {
6698         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6699         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6700         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6701         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6702         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6703         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6704         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6705         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6706         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6707         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6708         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6709         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6710         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6711         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6712         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6713         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6714         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6715         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6716         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6717         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6718         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6719         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6720         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6721         SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
6722         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6723         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6724         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6725         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6726         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6727         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6728         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6729         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6730         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6731         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6732         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6733         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6734         {}
6735 };
6736
6737 static struct alc_config_preset alc883_presets[] = {
6738         [ALC883_3ST_2ch_DIG] = {
6739                 .mixers = { alc883_3ST_2ch_mixer },
6740                 .init_verbs = { alc883_init_verbs },
6741                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6742                 .dac_nids = alc883_dac_nids,
6743                 .dig_out_nid = ALC883_DIGOUT_NID,
6744                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6745                 .adc_nids = alc883_adc_nids,
6746                 .dig_in_nid = ALC883_DIGIN_NID,
6747                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6748                 .channel_mode = alc883_3ST_2ch_modes,
6749                 .input_mux = &alc883_capture_source,
6750         },
6751         [ALC883_3ST_6ch_DIG] = {
6752                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6753                 .init_verbs = { alc883_init_verbs },
6754                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6755                 .dac_nids = alc883_dac_nids,
6756                 .dig_out_nid = ALC883_DIGOUT_NID,
6757                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6758                 .adc_nids = alc883_adc_nids,
6759                 .dig_in_nid = ALC883_DIGIN_NID,
6760                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6761                 .channel_mode = alc883_3ST_6ch_modes,
6762                 .need_dac_fix = 1,
6763                 .input_mux = &alc883_capture_source,
6764         },
6765         [ALC883_3ST_6ch] = {
6766                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6767                 .init_verbs = { alc883_init_verbs },
6768                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6769                 .dac_nids = alc883_dac_nids,
6770                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6771                 .adc_nids = alc883_adc_nids,
6772                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6773                 .channel_mode = alc883_3ST_6ch_modes,
6774                 .need_dac_fix = 1,
6775                 .input_mux = &alc883_capture_source,
6776         },
6777         [ALC883_6ST_DIG] = {
6778                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
6779                 .init_verbs = { alc883_init_verbs },
6780                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6781                 .dac_nids = alc883_dac_nids,
6782                 .dig_out_nid = ALC883_DIGOUT_NID,
6783                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6784                 .adc_nids = alc883_adc_nids,
6785                 .dig_in_nid = ALC883_DIGIN_NID,
6786                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6787                 .channel_mode = alc883_sixstack_modes,
6788                 .input_mux = &alc883_capture_source,
6789         },
6790         [ALC883_TARGA_DIG] = {
6791                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6792                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6793                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6794                 .dac_nids = alc883_dac_nids,
6795                 .dig_out_nid = ALC883_DIGOUT_NID,
6796                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6797                 .adc_nids = alc883_adc_nids,
6798                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6799                 .channel_mode = alc883_3ST_6ch_modes,
6800                 .need_dac_fix = 1,
6801                 .input_mux = &alc883_capture_source,
6802                 .unsol_event = alc883_tagra_unsol_event,
6803                 .init_hook = alc883_tagra_automute,
6804         },
6805         [ALC883_TARGA_2ch_DIG] = {
6806                 .mixers = { alc883_tagra_2ch_mixer},
6807                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6808                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6809                 .dac_nids = alc883_dac_nids,
6810                 .dig_out_nid = ALC883_DIGOUT_NID,
6811                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6812                 .adc_nids = alc883_adc_nids,
6813                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6814                 .channel_mode = alc883_3ST_2ch_modes,
6815                 .input_mux = &alc883_capture_source,
6816                 .unsol_event = alc883_tagra_unsol_event,
6817                 .init_hook = alc883_tagra_automute,
6818         },
6819         [ALC883_ACER] = {
6820                 .mixers = { alc883_base_mixer,
6821                             alc883_chmode_mixer },
6822                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
6823                  * and the headphone jack.  Turn this on and rely on the
6824                  * standard mute methods whenever the user wants to turn
6825                  * these outputs off.
6826                  */
6827                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6828                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6829                 .dac_nids = alc883_dac_nids,
6830                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6831                 .adc_nids = alc883_adc_nids,
6832                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6833                 .channel_mode = alc883_3ST_2ch_modes,
6834                 .input_mux = &alc883_capture_source,
6835         },
6836         [ALC883_ACER_ASPIRE] = {
6837                 .mixers = { alc883_acer_aspire_mixer},
6838                 .init_verbs = { alc883_init_verbs, alc883_acer_aspire_verbs},
6839                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6840                 .dac_nids = alc883_dac_nids,
6841                 .dig_out_nid = ALC883_DIGOUT_NID,
6842                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6843                 .adc_nids = alc883_adc_nids,
6844                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6845                 .channel_mode = alc883_3ST_2ch_modes,
6846                 .input_mux = &alc883_capture_source,
6847                 .unsol_event = alc883_medion_md2_unsol_event,
6848                 .init_hook = alc883_medion_md2_automute,
6849         },      
6850         [ALC883_MEDION] = {
6851                 .mixers = { alc883_fivestack_mixer,
6852                             alc883_chmode_mixer },
6853                 .init_verbs = { alc883_init_verbs,
6854                                 alc883_medion_eapd_verbs },
6855                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6856                 .dac_nids = alc883_dac_nids,
6857                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6858                 .adc_nids = alc883_adc_nids,
6859                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6860                 .channel_mode = alc883_sixstack_modes,
6861                 .input_mux = &alc883_capture_source,
6862         },
6863         [ALC883_MEDION_MD2] = {
6864                 .mixers = { alc883_medion_md2_mixer},
6865                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6866                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6867                 .dac_nids = alc883_dac_nids,
6868                 .dig_out_nid = ALC883_DIGOUT_NID,
6869                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6870                 .adc_nids = alc883_adc_nids,
6871                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6872                 .channel_mode = alc883_3ST_2ch_modes,
6873                 .input_mux = &alc883_capture_source,
6874                 .unsol_event = alc883_medion_md2_unsol_event,
6875                 .init_hook = alc883_medion_md2_automute,
6876         },      
6877         [ALC883_LAPTOP_EAPD] = {
6878                 .mixers = { alc883_base_mixer,
6879                             alc883_chmode_mixer },
6880                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6881                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6882                 .dac_nids = alc883_dac_nids,
6883                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6884                 .adc_nids = alc883_adc_nids,
6885                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6886                 .channel_mode = alc883_3ST_2ch_modes,
6887                 .input_mux = &alc883_capture_source,
6888         },
6889         [ALC883_LENOVO_101E_2ch] = {
6890                 .mixers = { alc883_lenovo_101e_2ch_mixer},
6891                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6892                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6893                 .dac_nids = alc883_dac_nids,
6894                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6895                 .adc_nids = alc883_adc_nids,
6896                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6897                 .channel_mode = alc883_3ST_2ch_modes,
6898                 .input_mux = &alc883_lenovo_101e_capture_source,
6899                 .unsol_event = alc883_lenovo_101e_unsol_event,
6900                 .init_hook = alc883_lenovo_101e_all_automute,
6901         },
6902         [ALC883_LENOVO_NB0763] = {
6903                 .mixers = { alc883_lenovo_nb0763_mixer },
6904                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6905                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6906                 .dac_nids = alc883_dac_nids,
6907                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6908                 .adc_nids = alc883_adc_nids,
6909                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6910                 .channel_mode = alc883_3ST_2ch_modes,
6911                 .need_dac_fix = 1,
6912                 .input_mux = &alc883_lenovo_nb0763_capture_source,
6913                 .unsol_event = alc883_medion_md2_unsol_event,
6914                 .init_hook = alc883_medion_md2_automute,
6915         },
6916         [ALC888_LENOVO_MS7195_DIG] = {
6917                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6918                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6919                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6920                 .dac_nids = alc883_dac_nids,
6921                 .dig_out_nid = ALC883_DIGOUT_NID,
6922                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6923                 .adc_nids = alc883_adc_nids,
6924                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6925                 .channel_mode = alc883_3ST_6ch_modes,
6926                 .need_dac_fix = 1,
6927                 .input_mux = &alc883_capture_source,
6928                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
6929                 .init_hook = alc888_lenovo_ms7195_front_automute,
6930         },      
6931         [ALC888_6ST_HP] = {
6932                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
6933                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
6934                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6935                 .dac_nids = alc883_dac_nids,
6936                 .dig_out_nid = ALC883_DIGOUT_NID,
6937                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6938                 .adc_nids = alc883_adc_nids,
6939                 .dig_in_nid = ALC883_DIGIN_NID,
6940                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6941                 .channel_mode = alc883_sixstack_modes,
6942                 .input_mux = &alc883_capture_source,
6943         },
6944         [ALC888_3ST_HP] = {
6945                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
6946                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
6947                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6948                 .dac_nids = alc883_dac_nids,
6949                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6950                 .adc_nids = alc883_adc_nids,
6951                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
6952                 .channel_mode = alc888_3st_hp_modes,
6953                 .need_dac_fix = 1,
6954                 .input_mux = &alc883_capture_source,
6955         },
6956 };
6957
6958
6959 /*
6960  * BIOS auto configuration
6961  */
6962 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6963                                               hda_nid_t nid, int pin_type,
6964                                               int dac_idx)
6965 {
6966         /* set as output */
6967         struct alc_spec *spec = codec->spec;
6968         int idx;
6969
6970         if (spec->multiout.dac_nids[dac_idx] == 0x25)
6971                 idx = 4;
6972         else
6973                 idx = spec->multiout.dac_nids[dac_idx] - 2;
6974
6975         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6976                             pin_type);
6977         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6978                             AMP_OUT_UNMUTE);
6979         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6980
6981 }
6982
6983 static void alc883_auto_init_multi_out(struct hda_codec *codec)
6984 {
6985         struct alc_spec *spec = codec->spec;
6986         int i;
6987
6988         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6989         for (i = 0; i <= HDA_SIDE; i++) {
6990                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6991                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6992                 if (nid)
6993                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6994                                                           i);
6995         }
6996 }
6997
6998 static void alc883_auto_init_hp_out(struct hda_codec *codec)
6999 {
7000         struct alc_spec *spec = codec->spec;
7001         hda_nid_t pin;
7002
7003         pin = spec->autocfg.hp_pins[0];
7004         if (pin) /* connect to front */
7005                 /* use dac 0 */
7006                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7007 }
7008
7009 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
7010 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
7011
7012 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7013 {
7014         struct alc_spec *spec = codec->spec;
7015         int i;
7016
7017         for (i = 0; i < AUTO_PIN_LAST; i++) {
7018                 hda_nid_t nid = spec->autocfg.input_pins[i];
7019                 if (alc883_is_input_pin(nid)) {
7020                         snd_hda_codec_write(codec, nid, 0,
7021                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
7022                                             (i <= AUTO_PIN_FRONT_MIC ?
7023                                              PIN_VREF80 : PIN_IN));
7024                         if (nid != ALC883_PIN_CD_NID)
7025                                 snd_hda_codec_write(codec, nid, 0,
7026                                                     AC_VERB_SET_AMP_GAIN_MUTE,
7027                                                     AMP_OUT_MUTE);
7028                 }
7029         }
7030 }
7031
7032 /* almost identical with ALC880 parser... */
7033 static int alc883_parse_auto_config(struct hda_codec *codec)
7034 {
7035         struct alc_spec *spec = codec->spec;
7036         int err = alc880_parse_auto_config(codec);
7037
7038         if (err < 0)
7039                 return err;
7040         else if (err > 0)
7041                 /* hack - override the init verbs */
7042                 spec->init_verbs[0] = alc883_auto_init_verbs;
7043         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7044         spec->num_mixers++;
7045         return err;
7046 }
7047
7048 /* additional initialization for auto-configuration model */
7049 static void alc883_auto_init(struct hda_codec *codec)
7050 {
7051         alc883_auto_init_multi_out(codec);
7052         alc883_auto_init_hp_out(codec);
7053         alc883_auto_init_analog_input(codec);
7054 }
7055
7056 static int patch_alc883(struct hda_codec *codec)
7057 {
7058         struct alc_spec *spec;
7059         int err, board_config;
7060
7061         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7062         if (spec == NULL)
7063                 return -ENOMEM;
7064
7065         codec->spec = spec;
7066
7067         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7068                                                   alc883_models,
7069                                                   alc883_cfg_tbl);
7070         if (board_config < 0) {
7071                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7072                        "trying auto-probe from BIOS...\n");
7073                 board_config = ALC883_AUTO;
7074         }
7075
7076         if (board_config == ALC883_AUTO) {
7077                 /* automatic parse from the BIOS config */
7078                 err = alc883_parse_auto_config(codec);
7079                 if (err < 0) {
7080                         alc_free(codec);
7081                         return err;
7082                 } else if (!err) {
7083                         printk(KERN_INFO
7084                                "hda_codec: Cannot set up configuration "
7085                                "from BIOS.  Using base mode...\n");
7086                         board_config = ALC883_3ST_2ch_DIG;
7087                 }
7088         }
7089
7090         if (board_config != ALC883_AUTO)
7091                 setup_preset(spec, &alc883_presets[board_config]);
7092
7093         spec->stream_name_analog = "ALC883 Analog";
7094         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7095         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7096
7097         spec->stream_name_digital = "ALC883 Digital";
7098         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7099         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7100
7101         if (!spec->adc_nids && spec->input_mux) {
7102                 spec->adc_nids = alc883_adc_nids;
7103                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7104         }
7105
7106         codec->patch_ops = alc_patch_ops;
7107         if (board_config == ALC883_AUTO)
7108                 spec->init_hook = alc883_auto_init;
7109 #ifdef CONFIG_SND_HDA_POWER_SAVE
7110         if (!spec->loopback.amplist)
7111                 spec->loopback.amplist = alc883_loopbacks;
7112 #endif
7113
7114         return 0;
7115 }
7116
7117 /*
7118  * ALC262 support
7119  */
7120
7121 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7122 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7123
7124 #define alc262_dac_nids         alc260_dac_nids
7125 #define alc262_adc_nids         alc882_adc_nids
7126 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7127
7128 #define alc262_modes            alc260_modes
7129 #define alc262_capture_source   alc882_capture_source
7130
7131 static struct snd_kcontrol_new alc262_base_mixer[] = {
7132         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7133         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7134         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7135         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7136         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7137         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7138         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7139         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7140         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7141         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7142         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7143         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7144         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7145            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7146         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7147         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7148         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7149         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7150         { } /* end */
7151 };
7152
7153 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7154         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7155         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7156         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7157         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7158         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7159         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7160         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7161         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7162         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7163         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7164         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7165         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7166         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7167            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7168         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7169         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7170         { } /* end */
7171 };
7172
7173 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7174         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7175         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7176         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7177         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7178         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7179
7180         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7181         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7182         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7183         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7184         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7185         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7186         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7187         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7188         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7189         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7190         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7191         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7192         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7193         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7194         { } /* end */
7195 };
7196
7197 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7198         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7199         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7200         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7201         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7202         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7203         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7204         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7205         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7206         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7207         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7208         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7209         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7210         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7211         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7212         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7213         { } /* end */
7214 };
7215
7216 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7217         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7218         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7219         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7220         { } /* end */
7221 };
7222
7223 static struct hda_bind_ctls alc262_sony_bind_sw = {
7224         .ops = &snd_hda_bind_sw,
7225         .values = {
7226                 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7227                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7228                 0,
7229         },
7230 };
7231
7232 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7233         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7234         HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw),
7235         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7236         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7237         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7238         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7239         { } /* end */
7240 };
7241
7242 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7243         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7244         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7245         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7246         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7247         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7248         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7249         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7250         { } /* end */
7251 };
7252
7253 #define alc262_capture_mixer            alc882_capture_mixer
7254 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7255
7256 /*
7257  * generic initialization of ADC, input mixers and output mixers
7258  */
7259 static struct hda_verb alc262_init_verbs[] = {
7260         /*
7261          * Unmute ADC0-2 and set the default input to mic-in
7262          */
7263         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7264         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7265         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7266         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7267         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7268         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7269
7270         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7271          * mixer widget
7272          * Note: PASD motherboards uses the Line In 2 as the input for
7273          * front panel mic (mic 2)
7274          */
7275         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7276         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7277         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7278         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7279         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7280         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7281
7282         /*
7283          * Set up output mixers (0x0c - 0x0e)
7284          */
7285         /* set vol=0 to output mixers */
7286         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7287         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7288         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7289         /* set up input amps for analog loopback */
7290         /* Amp Indices: DAC = 0, mixer = 1 */
7291         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7292         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7293         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7294         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7295         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7296         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7297
7298         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7299         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7300         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7301         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7302         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7303         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7304
7305         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7306         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7307         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7308         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7309         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7310         
7311         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7312         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7313         
7314         /* FIXME: use matrix-type input source selection */
7315         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7316         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7317         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7318         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7319         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7320         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7321         /* Input mixer2 */
7322         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7323         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7324         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7325         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7326         /* Input mixer3 */
7327         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7328         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7329         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7330         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7331
7332         { }
7333 };
7334
7335 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7336         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7337         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7338         {}
7339 };
7340
7341 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7342         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7343         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7344         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7345
7346         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7347         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7348         {}
7349 };
7350
7351 static struct hda_verb alc262_sony_unsol_verbs[] = {
7352         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7353         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7354         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7355
7356         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7357         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7358 };
7359
7360 /* mute/unmute internal speaker according to the hp jack and mute state */
7361 static void alc262_hippo_automute(struct hda_codec *codec)
7362 {
7363         struct alc_spec *spec = codec->spec;
7364         unsigned int mute;
7365         unsigned int present;
7366
7367         /* need to execute and sync at first */
7368         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7369         present = snd_hda_codec_read(codec, 0x15, 0,
7370                                      AC_VERB_GET_PIN_SENSE, 0);
7371         spec->jack_present = (present & 0x80000000) != 0;
7372         if (spec->jack_present) {
7373                 /* mute internal speaker */
7374                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7375                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7376         } else {
7377                 /* unmute internal speaker if necessary */
7378                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7379                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7380                                          HDA_AMP_MUTE, mute);
7381         }
7382 }
7383
7384 /* unsolicited event for HP jack sensing */
7385 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7386                                        unsigned int res)
7387 {
7388         if ((res >> 26) != ALC880_HP_EVENT)
7389                 return;
7390         alc262_hippo_automute(codec);
7391 }
7392
7393 static void alc262_hippo1_automute(struct hda_codec *codec)
7394 {
7395         unsigned int mute;
7396         unsigned int present;
7397
7398         snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7399         present = snd_hda_codec_read(codec, 0x1b, 0,
7400                                      AC_VERB_GET_PIN_SENSE, 0);
7401         present = (present & 0x80000000) != 0;
7402         if (present) {
7403                 /* mute internal speaker */
7404                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7405                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7406         } else {
7407                 /* unmute internal speaker if necessary */
7408                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7409                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7410                                          HDA_AMP_MUTE, mute);
7411         }
7412 }
7413
7414 /* unsolicited event for HP jack sensing */
7415 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7416                                        unsigned int res)
7417 {
7418         if ((res >> 26) != ALC880_HP_EVENT)
7419                 return;
7420         alc262_hippo1_automute(codec);
7421 }
7422
7423 /*
7424  * fujitsu model
7425  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7426  */
7427
7428 #define ALC_HP_EVENT    0x37
7429
7430 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7431         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7432         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7433         {}
7434 };
7435
7436 static struct hda_input_mux alc262_fujitsu_capture_source = {
7437         .num_items = 2,
7438         .items = {
7439                 { "Mic", 0x0 },
7440                 { "CD", 0x4 },
7441         },
7442 };
7443
7444 static struct hda_input_mux alc262_HP_capture_source = {
7445         .num_items = 5,
7446         .items = {
7447                 { "Mic", 0x0 },
7448                 { "Front Mic", 0x3 },
7449                 { "Line", 0x2 },
7450                 { "CD", 0x4 },
7451                 { "AUX IN", 0x6 },
7452         },
7453 };
7454
7455 /* mute/unmute internal speaker according to the hp jack and mute state */
7456 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7457 {
7458         struct alc_spec *spec = codec->spec;
7459         unsigned int mute;
7460
7461         if (force || !spec->sense_updated) {
7462                 unsigned int present;
7463                 /* need to execute and sync at first */
7464                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7465                 present = snd_hda_codec_read(codec, 0x14, 0,
7466                                          AC_VERB_GET_PIN_SENSE, 0);
7467                 spec->jack_present = (present & 0x80000000) != 0;
7468                 spec->sense_updated = 1;
7469         }
7470         if (spec->jack_present) {
7471                 /* mute internal speaker */
7472                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7473                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7474         } else {
7475                 /* unmute internal speaker if necessary */
7476                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7477                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7478                                          HDA_AMP_MUTE, mute);
7479         }
7480 }
7481
7482 /* unsolicited event for HP jack sensing */
7483 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7484                                        unsigned int res)
7485 {
7486         if ((res >> 26) != ALC_HP_EVENT)
7487                 return;
7488         alc262_fujitsu_automute(codec, 1);
7489 }
7490
7491 /* bind volumes of both NID 0x0c and 0x0d */
7492 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
7493         .ops = &snd_hda_bind_vol,
7494         .values = {
7495                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7496                 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7497                 0
7498         },
7499 };
7500
7501 /* bind hp and internal speaker mute (with plug check) */
7502 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7503                                          struct snd_ctl_elem_value *ucontrol)
7504 {
7505         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7506         long *valp = ucontrol->value.integer.value;
7507         int change;
7508
7509         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7510                                           HDA_AMP_MUTE,
7511                                           valp[0] ? 0 : HDA_AMP_MUTE);
7512         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7513                                            HDA_AMP_MUTE,
7514                                            valp[1] ? 0 : HDA_AMP_MUTE);
7515         if (change)
7516                 alc262_fujitsu_automute(codec, 0);
7517         return change;
7518 }
7519
7520 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7521         HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
7522         {
7523                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7524                 .name = "Master Playback Switch",
7525                 .info = snd_hda_mixer_amp_switch_info,
7526                 .get = snd_hda_mixer_amp_switch_get,
7527                 .put = alc262_fujitsu_master_sw_put,
7528                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7529         },
7530         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7531         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7532         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7533         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7534         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7535         { } /* end */
7536 };
7537
7538 /* additional init verbs for Benq laptops */
7539 static struct hda_verb alc262_EAPD_verbs[] = {
7540         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7541         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7542         {}
7543 };
7544
7545 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7546         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7547         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7548
7549         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7550         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7551         {}
7552 };
7553
7554 /* add playback controls from the parsed DAC table */
7555 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7556                                              const struct auto_pin_cfg *cfg)
7557 {
7558         hda_nid_t nid;
7559         int err;
7560
7561         spec->multiout.num_dacs = 1;    /* only use one dac */
7562         spec->multiout.dac_nids = spec->private_dac_nids;
7563         spec->multiout.dac_nids[0] = 2;
7564
7565         nid = cfg->line_out_pins[0];
7566         if (nid) {
7567                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7568                                   "Front Playback Volume",
7569                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7570                 if (err < 0)
7571                         return err;
7572                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7573                                   "Front Playback Switch",
7574                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7575                 if (err < 0)
7576                         return err;
7577         }
7578
7579         nid = cfg->speaker_pins[0];
7580         if (nid) {
7581                 if (nid == 0x16) {
7582                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7583                                           "Speaker Playback Volume",
7584                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7585                                                               HDA_OUTPUT));
7586                         if (err < 0)
7587                                 return err;
7588                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7589                                           "Speaker Playback Switch",
7590                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7591                                                               HDA_OUTPUT));
7592                         if (err < 0)
7593                                 return err;
7594                 } else {
7595                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7596                                           "Speaker Playback Switch",
7597                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7598                                                               HDA_OUTPUT));
7599                         if (err < 0)
7600                                 return err;
7601                 }
7602         }
7603         nid = cfg->hp_pins[0];
7604         if (nid) {
7605                 /* spec->multiout.hp_nid = 2; */
7606                 if (nid == 0x16) {
7607                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
7608                                           "Headphone Playback Volume",
7609                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7610                                                               HDA_OUTPUT));
7611                         if (err < 0)
7612                                 return err;
7613                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7614                                           "Headphone Playback Switch",
7615                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7616                                                               HDA_OUTPUT));
7617                         if (err < 0)
7618                                 return err;
7619                 } else {
7620                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7621                                           "Headphone Playback Switch",
7622                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7623                                                               HDA_OUTPUT));
7624                         if (err < 0)
7625                                 return err;
7626                 }
7627         }
7628         return 0;
7629 }
7630
7631 /* identical with ALC880 */
7632 #define alc262_auto_create_analog_input_ctls \
7633         alc880_auto_create_analog_input_ctls
7634
7635 /*
7636  * generic initialization of ADC, input mixers and output mixers
7637  */
7638 static struct hda_verb alc262_volume_init_verbs[] = {
7639         /*
7640          * Unmute ADC0-2 and set the default input to mic-in
7641          */
7642         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7643         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7644         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7645         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7646         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7647         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7648
7649         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7650          * mixer widget
7651          * Note: PASD motherboards uses the Line In 2 as the input for
7652          * front panel mic (mic 2)
7653          */
7654         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7655         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7656         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7657         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7658         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7659         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7660
7661         /*
7662          * Set up output mixers (0x0c - 0x0f)
7663          */
7664         /* set vol=0 to output mixers */
7665         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7666         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7667         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7668         
7669         /* set up input amps for analog loopback */
7670         /* Amp Indices: DAC = 0, mixer = 1 */
7671         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7672         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7673         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7674         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7675         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7676         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7677
7678         /* FIXME: use matrix-type input source selection */
7679         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7680         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7681         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7682         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7683         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7684         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7685         /* Input mixer2 */
7686         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7687         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7688         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7689         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7690         /* Input mixer3 */
7691         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7692         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7693         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7694         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7695
7696         { }
7697 };
7698
7699 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7700         /*
7701          * Unmute ADC0-2 and set the default input to mic-in
7702          */
7703         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7704         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7705         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7706         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7707         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7708         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7709
7710         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7711          * mixer widget
7712          * Note: PASD motherboards uses the Line In 2 as the input for
7713          * front panel mic (mic 2)
7714          */
7715         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7716         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7717         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7718         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7719         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7720         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7721         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7722         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7723         
7724         /*
7725          * Set up output mixers (0x0c - 0x0e)
7726          */
7727         /* set vol=0 to output mixers */
7728         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7729         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7730         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7731
7732         /* set up input amps for analog loopback */
7733         /* Amp Indices: DAC = 0, mixer = 1 */
7734         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7735         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7736         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7737         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7738         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7739         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7740
7741         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7742         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7743         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744
7745         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7746         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7747
7748         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7749         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7750
7751         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7752         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7753         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7754         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7755         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7756
7757         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7758         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7759         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7760         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7761         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7762         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7763
7764
7765         /* FIXME: use matrix-type input source selection */
7766         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7767         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7768         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7769         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7770         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7771         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7772         /* Input mixer2 */
7773         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7774         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7775         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7776         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7777         /* Input mixer3 */
7778         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7779         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7780         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7781         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7782
7783         { }
7784 };
7785
7786 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7787         /*
7788          * Unmute ADC0-2 and set the default input to mic-in
7789          */
7790         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7791         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7792         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7793         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7794         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7795         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7796
7797         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7798          * mixer widget
7799          * Note: PASD motherboards uses the Line In 2 as the input for front
7800          * panel mic (mic 2)
7801          */
7802         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7803         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7804         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7805         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7806         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7807         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7808         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7809         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7810         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
7811         /*
7812          * Set up output mixers (0x0c - 0x0e)
7813          */
7814         /* set vol=0 to output mixers */
7815         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7816         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7817         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7818
7819         /* set up input amps for analog loopback */
7820         /* Amp Indices: DAC = 0, mixer = 1 */
7821         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7822         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7823         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7824         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7825         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7826         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7827
7828
7829         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
7830         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
7831         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
7832         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
7833         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
7834         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
7835         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
7836
7837         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7838         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7839
7840         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7841         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7842
7843         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7844         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7845         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7846         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7847         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7848         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7849
7850         /* FIXME: use matrix-type input source selection */
7851         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7852         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7853         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7854         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7855         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7856         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7857         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7858         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7859         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7860         /* Input mixer2 */
7861         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7862         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7863         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7864         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7865         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7866         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7867         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7868         /* Input mixer3 */
7869         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7870         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7871         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7872         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7873         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7874         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7875         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7876
7877         { }
7878 };
7879
7880 #ifdef CONFIG_SND_HDA_POWER_SAVE
7881 #define alc262_loopbacks        alc880_loopbacks
7882 #endif
7883
7884 /* pcm configuration: identiacal with ALC880 */
7885 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
7886 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
7887 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
7888 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
7889
7890 /*
7891  * BIOS auto configuration
7892  */
7893 static int alc262_parse_auto_config(struct hda_codec *codec)
7894 {
7895         struct alc_spec *spec = codec->spec;
7896         int err;
7897         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7898
7899         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7900                                            alc262_ignore);
7901         if (err < 0)
7902                 return err;
7903         if (!spec->autocfg.line_outs)
7904                 return 0; /* can't find valid BIOS pin config */
7905         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7906         if (err < 0)
7907                 return err;
7908         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7909         if (err < 0)
7910                 return err;
7911
7912         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7913
7914         if (spec->autocfg.dig_out_pin)
7915                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7916         if (spec->autocfg.dig_in_pin)
7917                 spec->dig_in_nid = ALC262_DIGIN_NID;
7918
7919         if (spec->kctl_alloc)
7920                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7921
7922         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7923         spec->num_mux_defs = 1;
7924         spec->input_mux = &spec->private_imux;
7925
7926         return 1;
7927 }
7928
7929 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
7930 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
7931 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
7932
7933
7934 /* init callback for auto-configuration model -- overriding the default init */
7935 static void alc262_auto_init(struct hda_codec *codec)
7936 {
7937         alc262_auto_init_multi_out(codec);
7938         alc262_auto_init_hp_out(codec);
7939         alc262_auto_init_analog_input(codec);
7940 }
7941
7942 /*
7943  * configuration and preset
7944  */
7945 static const char *alc262_models[ALC262_MODEL_LAST] = {
7946         [ALC262_BASIC]          = "basic",
7947         [ALC262_HIPPO]          = "hippo",
7948         [ALC262_HIPPO_1]        = "hippo_1",
7949         [ALC262_FUJITSU]        = "fujitsu",
7950         [ALC262_HP_BPC]         = "hp-bpc",
7951         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7952         [ALC262_BENQ_ED8]       = "benq",
7953         [ALC262_BENQ_T31]       = "benq-t31",
7954         [ALC262_SONY_ASSAMD]    = "sony-assamd",
7955         [ALC262_AUTO]           = "auto",
7956 };
7957
7958 static struct snd_pci_quirk alc262_cfg_tbl[] = {
7959         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7960         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7961         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7962         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7963         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7964         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7965         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7966         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7967         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7968         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7969         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7970         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7971         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7972         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7973         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7974         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7975         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7976         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7977         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7978         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7979         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7980         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7981         SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7982         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7983         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7984         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7985         {}
7986 };
7987
7988 static struct alc_config_preset alc262_presets[] = {
7989         [ALC262_BASIC] = {
7990                 .mixers = { alc262_base_mixer },
7991                 .init_verbs = { alc262_init_verbs },
7992                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
7993                 .dac_nids = alc262_dac_nids,
7994                 .hp_nid = 0x03,
7995                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
7996                 .channel_mode = alc262_modes,
7997                 .input_mux = &alc262_capture_source,
7998         },
7999         [ALC262_HIPPO] = {
8000                 .mixers = { alc262_base_mixer },
8001                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8002                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8003                 .dac_nids = alc262_dac_nids,
8004                 .hp_nid = 0x03,
8005                 .dig_out_nid = ALC262_DIGOUT_NID,
8006                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8007                 .channel_mode = alc262_modes,
8008                 .input_mux = &alc262_capture_source,
8009                 .unsol_event = alc262_hippo_unsol_event,
8010                 .init_hook = alc262_hippo_automute,
8011         },
8012         [ALC262_HIPPO_1] = {
8013                 .mixers = { alc262_hippo1_mixer },
8014                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8015                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8016                 .dac_nids = alc262_dac_nids,
8017                 .hp_nid = 0x02,
8018                 .dig_out_nid = ALC262_DIGOUT_NID,
8019                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8020                 .channel_mode = alc262_modes,
8021                 .input_mux = &alc262_capture_source,
8022                 .unsol_event = alc262_hippo1_unsol_event,
8023                 .init_hook = alc262_hippo1_automute,
8024         },
8025         [ALC262_FUJITSU] = {
8026                 .mixers = { alc262_fujitsu_mixer },
8027                 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
8028                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8029                 .dac_nids = alc262_dac_nids,
8030                 .hp_nid = 0x03,
8031                 .dig_out_nid = ALC262_DIGOUT_NID,
8032                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8033                 .channel_mode = alc262_modes,
8034                 .input_mux = &alc262_fujitsu_capture_source,
8035                 .unsol_event = alc262_fujitsu_unsol_event,
8036         },
8037         [ALC262_HP_BPC] = {
8038                 .mixers = { alc262_HP_BPC_mixer },
8039                 .init_verbs = { alc262_HP_BPC_init_verbs },
8040                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8041                 .dac_nids = alc262_dac_nids,
8042                 .hp_nid = 0x03,
8043                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8044                 .channel_mode = alc262_modes,
8045                 .input_mux = &alc262_HP_capture_source,
8046         },
8047         [ALC262_HP_BPC_D7000_WF] = {
8048                 .mixers = { alc262_HP_BPC_WildWest_mixer },
8049                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8050                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8051                 .dac_nids = alc262_dac_nids,
8052                 .hp_nid = 0x03,
8053                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8054                 .channel_mode = alc262_modes,
8055                 .input_mux = &alc262_HP_capture_source,
8056         },
8057         [ALC262_HP_BPC_D7000_WL] = {
8058                 .mixers = { alc262_HP_BPC_WildWest_mixer,
8059                             alc262_HP_BPC_WildWest_option_mixer },
8060                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8061                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8062                 .dac_nids = alc262_dac_nids,
8063                 .hp_nid = 0x03,
8064                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8065                 .channel_mode = alc262_modes,
8066                 .input_mux = &alc262_HP_capture_source,
8067         },
8068         [ALC262_BENQ_ED8] = {
8069                 .mixers = { alc262_base_mixer },
8070                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8071                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8072                 .dac_nids = alc262_dac_nids,
8073                 .hp_nid = 0x03,
8074                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8075                 .channel_mode = alc262_modes,
8076                 .input_mux = &alc262_capture_source,
8077         },
8078         [ALC262_SONY_ASSAMD] = {
8079                 .mixers = { alc262_sony_mixer },
8080                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8081                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8082                 .dac_nids = alc262_dac_nids,
8083                 .hp_nid = 0x02,
8084                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8085                 .channel_mode = alc262_modes,
8086                 .input_mux = &alc262_capture_source,
8087                 .unsol_event = alc262_hippo_unsol_event,
8088                 .init_hook = alc262_hippo_automute,
8089         },
8090         [ALC262_BENQ_T31] = {
8091                 .mixers = { alc262_benq_t31_mixer },
8092                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8093                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8094                 .dac_nids = alc262_dac_nids,
8095                 .hp_nid = 0x03,
8096                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8097                 .channel_mode = alc262_modes,
8098                 .input_mux = &alc262_capture_source,
8099                 .unsol_event = alc262_hippo_unsol_event,
8100                 .init_hook = alc262_hippo_automute,
8101         },      
8102 };
8103
8104 static int patch_alc262(struct hda_codec *codec)
8105 {
8106         struct alc_spec *spec;
8107         int board_config;
8108         int err;
8109
8110         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8111         if (spec == NULL)
8112                 return -ENOMEM;
8113
8114         codec->spec = spec;
8115 #if 0
8116         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8117          * under-run
8118          */
8119         {
8120         int tmp;
8121         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8122         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8123         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8124         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8125         }
8126 #endif
8127
8128         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8129                                                   alc262_models,
8130                                                   alc262_cfg_tbl);
8131
8132         if (board_config < 0) {
8133                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8134                        "trying auto-probe from BIOS...\n");
8135                 board_config = ALC262_AUTO;
8136         }
8137
8138         if (board_config == ALC262_AUTO) {
8139                 /* automatic parse from the BIOS config */
8140                 err = alc262_parse_auto_config(codec);
8141                 if (err < 0) {
8142                         alc_free(codec);
8143                         return err;
8144                 } else if (!err) {
8145                         printk(KERN_INFO
8146                                "hda_codec: Cannot set up configuration "
8147                                "from BIOS.  Using base mode...\n");
8148                         board_config = ALC262_BASIC;
8149                 }
8150         }
8151
8152         if (board_config != ALC262_AUTO)
8153                 setup_preset(spec, &alc262_presets[board_config]);
8154
8155         spec->stream_name_analog = "ALC262 Analog";
8156         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8157         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8158                 
8159         spec->stream_name_digital = "ALC262 Digital";
8160         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8161         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8162
8163         if (!spec->adc_nids && spec->input_mux) {
8164                 /* check whether NID 0x07 is valid */
8165                 unsigned int wcap = get_wcaps(codec, 0x07);
8166
8167                 /* get type */
8168                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8169                 if (wcap != AC_WID_AUD_IN) {
8170                         spec->adc_nids = alc262_adc_nids_alt;
8171                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8172                         spec->mixers[spec->num_mixers] =
8173                                 alc262_capture_alt_mixer;
8174                         spec->num_mixers++;
8175                 } else {
8176                         spec->adc_nids = alc262_adc_nids;
8177                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8178                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8179                         spec->num_mixers++;
8180                 }
8181         }
8182
8183         codec->patch_ops = alc_patch_ops;
8184         if (board_config == ALC262_AUTO)
8185                 spec->init_hook = alc262_auto_init;
8186 #ifdef CONFIG_SND_HDA_POWER_SAVE
8187         if (!spec->loopback.amplist)
8188                 spec->loopback.amplist = alc262_loopbacks;
8189 #endif
8190                 
8191         return 0;
8192 }
8193
8194 /*
8195  *  ALC268 channel source setting (2 channel)
8196  */
8197 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8198 #define alc268_modes            alc260_modes
8199         
8200 static hda_nid_t alc268_dac_nids[2] = {
8201         /* front, hp */
8202         0x02, 0x03
8203 };
8204
8205 static hda_nid_t alc268_adc_nids[2] = {
8206         /* ADC0-1 */
8207         0x08, 0x07
8208 };
8209
8210 static hda_nid_t alc268_adc_nids_alt[1] = {
8211         /* ADC0 */
8212         0x08
8213 };
8214
8215 static struct snd_kcontrol_new alc268_base_mixer[] = {
8216         /* output mixer control */
8217         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8218         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8219         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8220         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8221         { }
8222 };
8223
8224 /*
8225  * generic initialization of ADC, input mixers and output mixers
8226  */
8227 static struct hda_verb alc268_base_init_verbs[] = {
8228         /* Unmute DAC0-1 and set vol = 0 */
8229         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8230         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8231         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8232         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8233         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8234         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8235
8236         /*
8237          * Set up output mixers (0x0c - 0x0e)
8238          */
8239         /* set vol=0 to output mixers */
8240         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8241         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8242         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8243         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8244
8245         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8246         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8247
8248         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8249         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8250         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8251         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8252         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8253         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8254         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8255         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8256
8257         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8258         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8259         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8260         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8261         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8262         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8263         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8264         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8265
8266         /* FIXME: use matrix-type input source selection */
8267         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8268         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8269         /* Input mixer2 */
8270         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8271         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8272         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8273         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8274
8275         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8276         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8277         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8278         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8279         { }
8280 };
8281
8282 /*
8283  * generic initialization of ADC, input mixers and output mixers
8284  */
8285 static struct hda_verb alc268_volume_init_verbs[] = {
8286         /* set output DAC */
8287         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8288         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8289         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8290         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8291
8292         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8293         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8294         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8295         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8296         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8297
8298         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8299         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8300         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8301         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8302         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8303
8304         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8305         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8306         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8307         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8308
8309         /* set PCBEEP vol = 0 */
8310         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8311
8312         { }
8313 };
8314
8315 #define alc268_mux_enum_info alc_mux_enum_info
8316 #define alc268_mux_enum_get alc_mux_enum_get
8317
8318 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8319                                struct snd_ctl_elem_value *ucontrol)
8320 {
8321         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8322         struct alc_spec *spec = codec->spec;
8323         const struct hda_input_mux *imux = spec->input_mux;
8324         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8325         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8326         hda_nid_t nid = capture_mixers[adc_idx];
8327         unsigned int *cur_val = &spec->cur_mux[adc_idx];
8328         unsigned int i, idx;
8329
8330         idx = ucontrol->value.enumerated.item[0];
8331         if (idx >= imux->num_items)
8332                 idx = imux->num_items - 1;
8333         if (*cur_val == idx)
8334                 return 0;
8335         for (i = 0; i < imux->num_items; i++) {
8336                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
8337                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
8338                                          imux->items[i].index,
8339                                          HDA_AMP_MUTE, v);
8340                 snd_hda_codec_write_cache(codec, nid, 0,
8341                                           AC_VERB_SET_CONNECT_SEL,
8342                                           idx );
8343         }
8344         *cur_val = idx;
8345         return 1;
8346 }
8347
8348 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8349         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8350         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8351         {
8352                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8353                 /* The multiple "Capture Source" controls confuse alsamixer
8354                  * So call somewhat different..
8355                  * FIXME: the controls appear in the "playback" view!
8356                  */
8357                 /* .name = "Capture Source", */
8358                 .name = "Input Source",
8359                 .count = 1,
8360                 .info = alc268_mux_enum_info,
8361                 .get = alc268_mux_enum_get,
8362                 .put = alc268_mux_enum_put,
8363         },
8364         { } /* end */
8365 };
8366
8367 static struct snd_kcontrol_new alc268_capture_mixer[] = {
8368         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8369         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8370         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8371         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8372         {
8373                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8374                 /* The multiple "Capture Source" controls confuse alsamixer
8375                  * So call somewhat different..
8376                  * FIXME: the controls appear in the "playback" view!
8377                  */
8378                 /* .name = "Capture Source", */
8379                 .name = "Input Source",
8380                 .count = 2,
8381                 .info = alc268_mux_enum_info,
8382                 .get = alc268_mux_enum_get,
8383                 .put = alc268_mux_enum_put,
8384         },
8385         { } /* end */
8386 };
8387
8388 static struct hda_input_mux alc268_capture_source = {
8389         .num_items = 4,
8390         .items = {
8391                 { "Mic", 0x0 },
8392                 { "Front Mic", 0x1 },
8393                 { "Line", 0x2 },
8394                 { "CD", 0x3 },
8395         },
8396 };
8397
8398 /* create input playback/capture controls for the given pin */
8399 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8400                                     const char *ctlname, int idx)
8401 {
8402         char name[32];
8403         int err;
8404
8405         sprintf(name, "%s Playback Volume", ctlname);
8406         if (nid == 0x14) {
8407                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8408                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8409                                                       HDA_OUTPUT));
8410                 if (err < 0)
8411                         return err;
8412         } else if (nid == 0x15) {
8413                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8414                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8415                                                       HDA_OUTPUT));
8416                 if (err < 0)
8417                         return err;
8418         } else
8419                 return -1;
8420         sprintf(name, "%s Playback Switch", ctlname);
8421         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8422                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8423         if (err < 0)
8424                 return err;
8425         return 0;
8426 }
8427
8428 /* add playback controls from the parsed DAC table */
8429 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8430                                              const struct auto_pin_cfg *cfg)
8431 {
8432         hda_nid_t nid;
8433         int err;
8434
8435         spec->multiout.num_dacs = 2;    /* only use one dac */
8436         spec->multiout.dac_nids = spec->private_dac_nids;
8437         spec->multiout.dac_nids[0] = 2;
8438         spec->multiout.dac_nids[1] = 3;
8439
8440         nid = cfg->line_out_pins[0];
8441         if (nid)
8442                 alc268_new_analog_output(spec, nid, "Front", 0);        
8443
8444         nid = cfg->speaker_pins[0];
8445         if (nid == 0x1d) {
8446                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8447                                   "Speaker Playback Volume",
8448                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8449                 if (err < 0)
8450                         return err;
8451         }
8452         nid = cfg->hp_pins[0];
8453         if (nid)
8454                 alc268_new_analog_output(spec, nid, "Headphone", 0);
8455
8456         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8457         if (nid == 0x16) {
8458                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8459                                   "Mono Playback Switch",
8460                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8461                 if (err < 0)
8462                         return err;
8463         }
8464         return 0;       
8465 }
8466
8467 /* create playback/capture controls for input pins */
8468 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8469                                                 const struct auto_pin_cfg *cfg)
8470 {
8471         struct hda_input_mux *imux = &spec->private_imux;
8472         int i, idx1;
8473
8474         for (i = 0; i < AUTO_PIN_LAST; i++) {
8475                 switch(cfg->input_pins[i]) {
8476                 case 0x18:
8477                         idx1 = 0;       /* Mic 1 */
8478                         break;
8479                 case 0x19:
8480                         idx1 = 1;       /* Mic 2 */
8481                         break;
8482                 case 0x1a:
8483                         idx1 = 2;       /* Line In */
8484                         break;
8485                 case 0x1c:      
8486                         idx1 = 3;       /* CD */
8487                         break;
8488                 default:
8489                         continue;
8490                 }
8491                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8492                 imux->items[imux->num_items].index = idx1;
8493                 imux->num_items++;      
8494         }
8495         return 0;
8496 }
8497
8498 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8499 {
8500         struct alc_spec *spec = codec->spec;
8501         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8502         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8503         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8504         unsigned int    dac_vol1, dac_vol2;
8505
8506         if (speaker_nid) {
8507                 snd_hda_codec_write(codec, speaker_nid, 0,
8508                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8509                 snd_hda_codec_write(codec, 0x0f, 0,
8510                                     AC_VERB_SET_AMP_GAIN_MUTE,
8511                                     AMP_IN_UNMUTE(1));
8512                 snd_hda_codec_write(codec, 0x10, 0,
8513                                     AC_VERB_SET_AMP_GAIN_MUTE,
8514                                     AMP_IN_UNMUTE(1));
8515         } else {
8516                 snd_hda_codec_write(codec, 0x0f, 0,
8517                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8518                 snd_hda_codec_write(codec, 0x10, 0,
8519                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8520         }
8521
8522         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
8523         if (line_nid == 0x14)   
8524                 dac_vol2 = AMP_OUT_ZERO;
8525         else if (line_nid == 0x15)
8526                 dac_vol1 = AMP_OUT_ZERO;
8527         if (hp_nid == 0x14)     
8528                 dac_vol2 = AMP_OUT_ZERO;
8529         else if (hp_nid == 0x15)
8530                 dac_vol1 = AMP_OUT_ZERO;
8531         if (line_nid != 0x16 || hp_nid != 0x16 ||
8532             spec->autocfg.line_out_pins[1] != 0x16 ||
8533             spec->autocfg.line_out_pins[2] != 0x16)
8534                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8535
8536         snd_hda_codec_write(codec, 0x02, 0,
8537                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8538         snd_hda_codec_write(codec, 0x03, 0,
8539                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8540 }
8541
8542 /* pcm configuration: identiacal with ALC880 */
8543 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
8544 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
8545 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
8546
8547 /*
8548  * BIOS auto configuration
8549  */
8550 static int alc268_parse_auto_config(struct hda_codec *codec)
8551 {
8552         struct alc_spec *spec = codec->spec;
8553         int err;
8554         static hda_nid_t alc268_ignore[] = { 0 };
8555
8556         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8557                                            alc268_ignore);
8558         if (err < 0)
8559                 return err;
8560         if (!spec->autocfg.line_outs)
8561                 return 0; /* can't find valid BIOS pin config */
8562
8563         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8564         if (err < 0)
8565                 return err;
8566         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8567         if (err < 0)
8568                 return err;
8569
8570         spec->multiout.max_channels = 2;
8571
8572         /* digital only support output */
8573         if (spec->autocfg.dig_out_pin)
8574                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8575
8576         if (spec->kctl_alloc)
8577                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8578
8579         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8580         spec->num_mux_defs = 1;
8581         spec->input_mux = &spec->private_imux;
8582
8583         return 1;
8584 }
8585
8586 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
8587 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
8588 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
8589
8590 /* init callback for auto-configuration model -- overriding the default init */
8591 static void alc268_auto_init(struct hda_codec *codec)
8592 {
8593         alc268_auto_init_multi_out(codec);
8594         alc268_auto_init_hp_out(codec);
8595         alc268_auto_init_mono_speaker_out(codec);
8596         alc268_auto_init_analog_input(codec);
8597 }
8598
8599 #ifdef CONFIG_SND_HDA_POWER_SAVE
8600 #define alc883_loopbacks        alc880_loopbacks
8601 #endif
8602
8603 /*
8604  * configuration and preset
8605  */
8606 static const char *alc268_models[ALC268_MODEL_LAST] = {
8607         [ALC268_3ST]            = "3stack",
8608         [ALC268_AUTO]           = "auto",
8609 };
8610
8611 static struct snd_pci_quirk alc268_cfg_tbl[] = {
8612         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8613         {}
8614 };
8615
8616 static struct alc_config_preset alc268_presets[] = {
8617         [ALC268_3ST] = {
8618                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8619                 .init_verbs = { alc268_base_init_verbs },
8620                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8621                 .dac_nids = alc268_dac_nids,
8622                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8623                 .adc_nids = alc268_adc_nids_alt,
8624                 .hp_nid = 0x03,
8625                 .dig_out_nid = ALC268_DIGOUT_NID,
8626                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8627                 .channel_mode = alc268_modes,
8628                 .input_mux = &alc268_capture_source,
8629         },
8630 };
8631
8632 static int patch_alc268(struct hda_codec *codec)
8633 {
8634         struct alc_spec *spec;
8635         int board_config;
8636         int err;
8637
8638         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8639         if (spec == NULL)
8640                 return -ENOMEM;
8641
8642         codec->spec = spec;
8643
8644         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8645                                                   alc268_models,
8646                                                   alc268_cfg_tbl);
8647
8648         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8649                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8650                        "trying auto-probe from BIOS...\n");
8651                 board_config = ALC268_AUTO;
8652         }
8653
8654         if (board_config == ALC268_AUTO) {
8655                 /* automatic parse from the BIOS config */
8656                 err = alc268_parse_auto_config(codec);
8657                 if (err < 0) {
8658                         alc_free(codec);
8659                         return err;
8660                 } else if (!err) {
8661                         printk(KERN_INFO
8662                                "hda_codec: Cannot set up configuration "
8663                                "from BIOS.  Using base mode...\n");
8664                         board_config = ALC268_3ST;
8665                 }
8666         }
8667
8668         if (board_config != ALC268_AUTO)
8669                 setup_preset(spec, &alc268_presets[board_config]);
8670
8671         spec->stream_name_analog = "ALC268 Analog";
8672         spec->stream_analog_playback = &alc268_pcm_analog_playback;
8673         spec->stream_analog_capture = &alc268_pcm_analog_capture;
8674
8675         spec->stream_name_digital = "ALC268 Digital";
8676         spec->stream_digital_playback = &alc268_pcm_digital_playback;
8677
8678         if (board_config == ALC268_AUTO) {
8679                 if (!spec->adc_nids && spec->input_mux) {
8680                         /* check whether NID 0x07 is valid */
8681                         unsigned int wcap = get_wcaps(codec, 0x07);
8682
8683                         /* get type */
8684                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8685                         if (wcap != AC_WID_AUD_IN) {
8686                                 spec->adc_nids = alc268_adc_nids_alt;
8687                                 spec->num_adc_nids =
8688                                         ARRAY_SIZE(alc268_adc_nids_alt);
8689                                 spec->mixers[spec->num_mixers] =
8690                                         alc268_capture_alt_mixer;
8691                                 spec->num_mixers++;
8692                         } else {
8693                                 spec->adc_nids = alc268_adc_nids;
8694                                 spec->num_adc_nids =
8695                                         ARRAY_SIZE(alc268_adc_nids);
8696                                 spec->mixers[spec->num_mixers] =
8697                                         alc268_capture_mixer;
8698                                 spec->num_mixers++;
8699                         }
8700                 }
8701         }
8702         codec->patch_ops = alc_patch_ops;
8703         if (board_config == ALC268_AUTO)
8704                 spec->init_hook = alc268_auto_init;
8705                 
8706         return 0;
8707 }
8708
8709 /*
8710  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8711  */
8712
8713 /*
8714  * set the path ways for 2 channel output
8715  * need to set the codec line out and mic 1 pin widgets to inputs
8716  */
8717 static struct hda_verb alc861_threestack_ch2_init[] = {
8718         /* set pin widget 1Ah (line in) for input */
8719         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8720         /* set pin widget 18h (mic1/2) for input, for mic also enable
8721          * the vref
8722          */
8723         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8724
8725         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8726 #if 0
8727         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8728         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8729 #endif
8730         { } /* end */
8731 };
8732 /*
8733  * 6ch mode
8734  * need to set the codec line out and mic 1 pin widgets to outputs
8735  */
8736 static struct hda_verb alc861_threestack_ch6_init[] = {
8737         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8738         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8739         /* set pin widget 18h (mic1) for output (CLFE)*/
8740         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8741
8742         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8743         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8744
8745         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8746 #if 0
8747         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8748         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8749 #endif
8750         { } /* end */
8751 };
8752
8753 static struct hda_channel_mode alc861_threestack_modes[2] = {
8754         { 2, alc861_threestack_ch2_init },
8755         { 6, alc861_threestack_ch6_init },
8756 };
8757 /* Set mic1 as input and unmute the mixer */
8758 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8759         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8760         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8761         { } /* end */
8762 };
8763 /* Set mic1 as output and mute mixer */
8764 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8765         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8766         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8767         { } /* end */
8768 };
8769
8770 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8771         { 2, alc861_uniwill_m31_ch2_init },
8772         { 4, alc861_uniwill_m31_ch4_init },
8773 };
8774
8775 /* Set mic1 and line-in as input and unmute the mixer */
8776 static struct hda_verb alc861_asus_ch2_init[] = {
8777         /* set pin widget 1Ah (line in) for input */
8778         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8779         /* set pin widget 18h (mic1/2) for input, for mic also enable
8780          * the vref
8781          */
8782         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8783
8784         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8785 #if 0
8786         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8787         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8788 #endif
8789         { } /* end */
8790 };
8791 /* Set mic1 nad line-in as output and mute mixer */
8792 static struct hda_verb alc861_asus_ch6_init[] = {
8793         /* set pin widget 1Ah (line in) for output (Back Surround)*/
8794         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8795         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8796         /* set pin widget 18h (mic1) for output (CLFE)*/
8797         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8798         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8799         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8800         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8801
8802         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8803 #if 0
8804         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8805         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8806 #endif
8807         { } /* end */
8808 };
8809
8810 static struct hda_channel_mode alc861_asus_modes[2] = {
8811         { 2, alc861_asus_ch2_init },
8812         { 6, alc861_asus_ch6_init },
8813 };
8814
8815 /* patch-ALC861 */
8816
8817 static struct snd_kcontrol_new alc861_base_mixer[] = {
8818         /* output mixer control */
8819         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8820         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8821         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8822         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8823         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8824
8825         /*Input mixer control */
8826         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8827            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8828         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8829         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8830         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8831         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8832         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8833         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8834         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8835         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8836
8837         /* Capture mixer control */
8838         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8839         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8840         {
8841                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8842                 .name = "Capture Source",
8843                 .count = 1,
8844                 .info = alc_mux_enum_info,
8845                 .get = alc_mux_enum_get,
8846                 .put = alc_mux_enum_put,
8847         },
8848         { } /* end */
8849 };
8850
8851 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8852         /* output mixer control */
8853         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8854         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8855         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8856         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8857         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8858
8859         /* Input mixer control */
8860         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8861            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8862         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8863         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8864         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8865         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8866         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8867         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8868         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8869         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8870
8871         /* Capture mixer control */
8872         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8873         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8874         {
8875                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8876                 .name = "Capture Source",
8877                 .count = 1,
8878                 .info = alc_mux_enum_info,
8879                 .get = alc_mux_enum_get,
8880                 .put = alc_mux_enum_put,
8881         },
8882         {
8883                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8884                 .name = "Channel Mode",
8885                 .info = alc_ch_mode_info,
8886                 .get = alc_ch_mode_get,
8887                 .put = alc_ch_mode_put,
8888                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
8889         },
8890         { } /* end */
8891 };
8892
8893 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8894         /* output mixer control */
8895         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8896         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8897         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8898         
8899         /*Capture mixer control */
8900         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8901         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8902         {
8903                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8904                 .name = "Capture Source",
8905                 .count = 1,
8906                 .info = alc_mux_enum_info,
8907                 .get = alc_mux_enum_get,
8908                 .put = alc_mux_enum_put,
8909         },
8910
8911         { } /* end */
8912 };
8913
8914 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8915         /* output mixer control */
8916         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8917         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8918         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8919         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8920         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8921
8922         /* Input mixer control */
8923         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8924            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8925         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8926         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8927         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8928         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8929         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8930         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8931         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8932         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8933
8934         /* Capture mixer control */
8935         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8936         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8937         {
8938                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8939                 .name = "Capture Source",
8940                 .count = 1,
8941                 .info = alc_mux_enum_info,
8942                 .get = alc_mux_enum_get,
8943                 .put = alc_mux_enum_put,
8944         },
8945         {
8946                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8947                 .name = "Channel Mode",
8948                 .info = alc_ch_mode_info,
8949                 .get = alc_ch_mode_get,
8950                 .put = alc_ch_mode_put,
8951                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8952         },
8953         { } /* end */
8954 };
8955
8956 static struct snd_kcontrol_new alc861_asus_mixer[] = {
8957         /* output mixer control */
8958         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8959         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8960         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8961         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8962         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8963
8964         /* Input mixer control */
8965         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8966         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8967         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8968         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8969         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8970         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8971         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8972         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8973         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8974         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
8975
8976         /* Capture mixer control */
8977         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8978         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8979         {
8980                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8981                 .name = "Capture Source",
8982                 .count = 1,
8983                 .info = alc_mux_enum_info,
8984                 .get = alc_mux_enum_get,
8985                 .put = alc_mux_enum_put,
8986         },
8987         {
8988                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8989                 .name = "Channel Mode",
8990                 .info = alc_ch_mode_info,
8991                 .get = alc_ch_mode_get,
8992                 .put = alc_ch_mode_put,
8993                 .private_value = ARRAY_SIZE(alc861_asus_modes),
8994         },
8995         { }
8996 };
8997
8998 /* additional mixer */
8999 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
9000         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9001         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9002         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
9003         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
9004         { }
9005 };
9006
9007 /*
9008  * generic initialization of ADC, input mixers and output mixers
9009  */
9010 static struct hda_verb alc861_base_init_verbs[] = {
9011         /*
9012          * Unmute ADC0 and set the default input to mic-in
9013          */
9014         /* port-A for surround (rear panel) */
9015         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9016         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
9017         /* port-B for mic-in (rear panel) with vref */
9018         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9019         /* port-C for line-in (rear panel) */
9020         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9021         /* port-D for Front */
9022         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9023         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9024         /* port-E for HP out (front panel) */
9025         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9026         /* route front PCM to HP */
9027         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9028         /* port-F for mic-in (front panel) with vref */
9029         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9030         /* port-G for CLFE (rear panel) */
9031         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9032         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9033         /* port-H for side (rear panel) */
9034         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9035         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
9036         /* CD-in */
9037         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9038         /* route front mic to ADC1*/
9039         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9040         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9041         
9042         /* Unmute DAC0~3 & spdif out*/
9043         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9044         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9045         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9046         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9047         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9048         
9049         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9050         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9051         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9052         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9053         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9054         
9055         /* Unmute Stereo Mixer 15 */
9056         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9057         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9058         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9059         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9060
9061         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9062         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9063         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9065         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9066         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9067         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9069         /* hp used DAC 3 (Front) */
9070         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9071         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9072
9073         { }
9074 };
9075
9076 static struct hda_verb alc861_threestack_init_verbs[] = {
9077         /*
9078          * Unmute ADC0 and set the default input to mic-in
9079          */
9080         /* port-A for surround (rear panel) */
9081         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9082         /* port-B for mic-in (rear panel) with vref */
9083         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9084         /* port-C for line-in (rear panel) */
9085         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9086         /* port-D for Front */
9087         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9088         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9089         /* port-E for HP out (front panel) */
9090         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9091         /* route front PCM to HP */
9092         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9093         /* port-F for mic-in (front panel) with vref */
9094         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9095         /* port-G for CLFE (rear panel) */
9096         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9097         /* port-H for side (rear panel) */
9098         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9099         /* CD-in */
9100         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9101         /* route front mic to ADC1*/
9102         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9103         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9104         /* Unmute DAC0~3 & spdif out*/
9105         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9106         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9107         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9108         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9109         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9110         
9111         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9112         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9113         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9114         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9115         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9116         
9117         /* Unmute Stereo Mixer 15 */
9118         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9119         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9120         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9121         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9122
9123         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9124         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9125         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9126         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9127         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9128         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9129         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9130         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9131         /* hp used DAC 3 (Front) */
9132         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9133         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9134         { }
9135 };
9136
9137 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9138         /*
9139          * Unmute ADC0 and set the default input to mic-in
9140          */
9141         /* port-A for surround (rear panel) */
9142         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9143         /* port-B for mic-in (rear panel) with vref */
9144         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9145         /* port-C for line-in (rear panel) */
9146         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9147         /* port-D for Front */
9148         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9149         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9150         /* port-E for HP out (front panel) */
9151         /* this has to be set to VREF80 */
9152         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9153         /* route front PCM to HP */
9154         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9155         /* port-F for mic-in (front panel) with vref */
9156         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9157         /* port-G for CLFE (rear panel) */
9158         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9159         /* port-H for side (rear panel) */
9160         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9161         /* CD-in */
9162         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9163         /* route front mic to ADC1*/
9164         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9165         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9166         /* Unmute DAC0~3 & spdif out*/
9167         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9168         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9169         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9170         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9171         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9172         
9173         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9174         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9175         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9176         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9177         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9178         
9179         /* Unmute Stereo Mixer 15 */
9180         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9181         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9182         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9183         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9184
9185         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9186         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9187         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9188         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9189         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9190         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9191         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9192         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9193         /* hp used DAC 3 (Front) */
9194         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9195         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9196         { }
9197 };
9198
9199 static struct hda_verb alc861_asus_init_verbs[] = {
9200         /*
9201          * Unmute ADC0 and set the default input to mic-in
9202          */
9203         /* port-A for surround (rear panel)
9204          * according to codec#0 this is the HP jack
9205          */
9206         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9207         /* route front PCM to HP */
9208         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9209         /* port-B for mic-in (rear panel) with vref */
9210         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9211         /* port-C for line-in (rear panel) */
9212         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9213         /* port-D for Front */
9214         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9215         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9216         /* port-E for HP out (front panel) */
9217         /* this has to be set to VREF80 */
9218         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9219         /* route front PCM to HP */
9220         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9221         /* port-F for mic-in (front panel) with vref */
9222         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9223         /* port-G for CLFE (rear panel) */
9224         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9225         /* port-H for side (rear panel) */
9226         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9227         /* CD-in */
9228         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9229         /* route front mic to ADC1*/
9230         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9231         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9232         /* Unmute DAC0~3 & spdif out*/
9233         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9234         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9235         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9236         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9237         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9238         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9239         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9240         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9241         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9242         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9243         
9244         /* Unmute Stereo Mixer 15 */
9245         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9246         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9247         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9248         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9249
9250         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9251         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9252         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9253         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9254         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9255         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9256         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9257         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9258         /* hp used DAC 3 (Front) */
9259         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9260         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9261         { }
9262 };
9263
9264 /* additional init verbs for ASUS laptops */
9265 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9266         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9267         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9268         { }
9269 };
9270
9271 /*
9272  * generic initialization of ADC, input mixers and output mixers
9273  */
9274 static struct hda_verb alc861_auto_init_verbs[] = {
9275         /*
9276          * Unmute ADC0 and set the default input to mic-in
9277          */
9278         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9279         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9280         
9281         /* Unmute DAC0~3 & spdif out*/
9282         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9283         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9284         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9285         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9286         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9287         
9288         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9289         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9290         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9291         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9292         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9293         
9294         /* Unmute Stereo Mixer 15 */
9295         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9296         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9297         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9298         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9299
9300         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9301         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9302         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9303         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9304         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9305         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9306         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9307         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9308
9309         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9310         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9311         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9312         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9313         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9314         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9315         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9316         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9317
9318         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
9319
9320         { }
9321 };
9322
9323 static struct hda_verb alc861_toshiba_init_verbs[] = {
9324         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9325
9326         { }
9327 };
9328
9329 /* toggle speaker-output according to the hp-jack state */
9330 static void alc861_toshiba_automute(struct hda_codec *codec)
9331 {
9332         unsigned int present;
9333
9334         present = snd_hda_codec_read(codec, 0x0f, 0,
9335                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9336         snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
9337                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9338         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
9339                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
9340 }
9341
9342 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9343                                        unsigned int res)
9344 {
9345         if ((res >> 26) == ALC880_HP_EVENT)
9346                 alc861_toshiba_automute(codec);
9347 }
9348
9349 /* pcm configuration: identiacal with ALC880 */
9350 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
9351 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
9352 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
9353 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
9354
9355
9356 #define ALC861_DIGOUT_NID       0x07
9357
9358 static struct hda_channel_mode alc861_8ch_modes[1] = {
9359         { 8, NULL }
9360 };
9361
9362 static hda_nid_t alc861_dac_nids[4] = {
9363         /* front, surround, clfe, side */
9364         0x03, 0x06, 0x05, 0x04
9365 };
9366
9367 static hda_nid_t alc660_dac_nids[3] = {
9368         /* front, clfe, surround */
9369         0x03, 0x05, 0x06
9370 };
9371
9372 static hda_nid_t alc861_adc_nids[1] = {
9373         /* ADC0-2 */
9374         0x08,
9375 };
9376
9377 static struct hda_input_mux alc861_capture_source = {
9378         .num_items = 5,
9379         .items = {
9380                 { "Mic", 0x0 },
9381                 { "Front Mic", 0x3 },
9382                 { "Line", 0x1 },
9383                 { "CD", 0x4 },
9384                 { "Mixer", 0x5 },
9385         },
9386 };
9387
9388 /* fill in the dac_nids table from the parsed pin configuration */
9389 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9390                                      const struct auto_pin_cfg *cfg)
9391 {
9392         int i;
9393         hda_nid_t nid;
9394
9395         spec->multiout.dac_nids = spec->private_dac_nids;
9396         for (i = 0; i < cfg->line_outs; i++) {
9397                 nid = cfg->line_out_pins[i];
9398                 if (nid) {
9399                         if (i >= ARRAY_SIZE(alc861_dac_nids))
9400                                 continue;
9401                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9402                 }
9403         }
9404         spec->multiout.num_dacs = cfg->line_outs;
9405         return 0;
9406 }
9407
9408 /* add playback controls from the parsed DAC table */
9409 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9410                                              const struct auto_pin_cfg *cfg)
9411 {
9412         char name[32];
9413         static const char *chname[4] = {
9414                 "Front", "Surround", NULL /*CLFE*/, "Side"
9415         };
9416         hda_nid_t nid;
9417         int i, idx, err;
9418
9419         for (i = 0; i < cfg->line_outs; i++) {
9420                 nid = spec->multiout.dac_nids[i];
9421                 if (!nid)
9422                         continue;
9423                 if (nid == 0x05) {
9424                         /* Center/LFE */
9425                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9426                                           "Center Playback Switch",
9427                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9428                                                               HDA_OUTPUT));
9429                         if (err < 0)
9430                                 return err;
9431                         err = add_control(spec, ALC_CTL_BIND_MUTE,
9432                                           "LFE Playback Switch",
9433                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9434                                                               HDA_OUTPUT));
9435                         if (err < 0)
9436                                 return err;
9437                 } else {
9438                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9439                              idx++)
9440                                 if (nid == alc861_dac_nids[idx])
9441                                         break;
9442                         sprintf(name, "%s Playback Switch", chname[idx]);
9443                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9444                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9445                                                               HDA_OUTPUT));
9446                         if (err < 0)
9447                                 return err;
9448                 }
9449         }
9450         return 0;
9451 }
9452
9453 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9454 {
9455         int err;
9456         hda_nid_t nid;
9457
9458         if (!pin)
9459                 return 0;
9460
9461         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9462                 nid = 0x03;
9463                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9464                                   "Headphone Playback Switch",
9465                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9466                 if (err < 0)
9467                         return err;
9468                 spec->multiout.hp_nid = nid;
9469         }
9470         return 0;
9471 }
9472
9473 /* create playback/capture controls for input pins */
9474 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9475                                                 const struct auto_pin_cfg *cfg)
9476 {
9477         struct hda_input_mux *imux = &spec->private_imux;
9478         int i, err, idx, idx1;
9479
9480         for (i = 0; i < AUTO_PIN_LAST; i++) {
9481                 switch (cfg->input_pins[i]) {
9482                 case 0x0c:
9483                         idx1 = 1;
9484                         idx = 2;        /* Line In */
9485                         break;
9486                 case 0x0f:
9487                         idx1 = 2;
9488                         idx = 2;        /* Line In */
9489                         break;
9490                 case 0x0d:
9491                         idx1 = 0;
9492                         idx = 1;        /* Mic In */
9493                         break;
9494                 case 0x10:
9495                         idx1 = 3;
9496                         idx = 1;        /* Mic In */
9497                         break;
9498                 case 0x11:
9499                         idx1 = 4;
9500                         idx = 0;        /* CD */
9501                         break;
9502                 default:
9503                         continue;
9504                 }
9505
9506                 err = new_analog_input(spec, cfg->input_pins[i],
9507                                        auto_pin_cfg_labels[i], idx, 0x15);
9508                 if (err < 0)
9509                         return err;
9510
9511                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9512                 imux->items[imux->num_items].index = idx1;
9513                 imux->num_items++;
9514         }
9515         return 0;
9516 }
9517
9518 static struct snd_kcontrol_new alc861_capture_mixer[] = {
9519         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9520         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9521
9522         {
9523                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9524                 /* The multiple "Capture Source" controls confuse alsamixer
9525                  * So call somewhat different..
9526                  *FIXME: the controls appear in the "playback" view!
9527                  */
9528                 /* .name = "Capture Source", */
9529                 .name = "Input Source",
9530                 .count = 1,
9531                 .info = alc_mux_enum_info,
9532                 .get = alc_mux_enum_get,
9533                 .put = alc_mux_enum_put,
9534         },
9535         { } /* end */
9536 };
9537
9538 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9539                                               hda_nid_t nid,
9540                                               int pin_type, int dac_idx)
9541 {
9542         /* set as output */
9543
9544         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9545                             pin_type);
9546         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9547                             AMP_OUT_UNMUTE);
9548
9549 }
9550
9551 static void alc861_auto_init_multi_out(struct hda_codec *codec)
9552 {
9553         struct alc_spec *spec = codec->spec;
9554         int i;
9555
9556         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9557         for (i = 0; i < spec->autocfg.line_outs; i++) {
9558                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9559                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9560                 if (nid)
9561                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9562                                                           spec->multiout.dac_nids[i]);
9563         }
9564 }
9565
9566 static void alc861_auto_init_hp_out(struct hda_codec *codec)
9567 {
9568         struct alc_spec *spec = codec->spec;
9569         hda_nid_t pin;
9570
9571         pin = spec->autocfg.hp_pins[0];
9572         if (pin) /* connect to front */
9573                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9574                                                   spec->multiout.dac_nids[0]);
9575 }
9576
9577 static void alc861_auto_init_analog_input(struct hda_codec *codec)
9578 {
9579         struct alc_spec *spec = codec->spec;
9580         int i;
9581
9582         for (i = 0; i < AUTO_PIN_LAST; i++) {
9583                 hda_nid_t nid = spec->autocfg.input_pins[i];
9584                 if (nid >= 0x0c && nid <= 0x11) {
9585                         snd_hda_codec_write(codec, nid, 0,
9586                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
9587                                             i <= AUTO_PIN_FRONT_MIC ?
9588                                             PIN_VREF80 : PIN_IN);
9589                 }
9590         }
9591 }
9592
9593 /* parse the BIOS configuration and set up the alc_spec */
9594 /* return 1 if successful, 0 if the proper config is not found,
9595  * or a negative error code
9596  */
9597 static int alc861_parse_auto_config(struct hda_codec *codec)
9598 {
9599         struct alc_spec *spec = codec->spec;
9600         int err;
9601         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9602
9603         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9604                                            alc861_ignore);
9605         if (err < 0)
9606                 return err;
9607         if (!spec->autocfg.line_outs)
9608                 return 0; /* can't find valid BIOS pin config */
9609
9610         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9611         if (err < 0)
9612                 return err;
9613         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9614         if (err < 0)
9615                 return err;
9616         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9617         if (err < 0)
9618                 return err;
9619         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9620         if (err < 0)
9621                 return err;
9622
9623         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9624
9625         if (spec->autocfg.dig_out_pin)
9626                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9627
9628         if (spec->kctl_alloc)
9629                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9630
9631         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9632
9633         spec->num_mux_defs = 1;
9634         spec->input_mux = &spec->private_imux;
9635
9636         spec->adc_nids = alc861_adc_nids;
9637         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9638         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9639         spec->num_mixers++;
9640
9641         return 1;
9642 }
9643
9644 /* additional initialization for auto-configuration model */
9645 static void alc861_auto_init(struct hda_codec *codec)
9646 {
9647         alc861_auto_init_multi_out(codec);
9648         alc861_auto_init_hp_out(codec);
9649         alc861_auto_init_analog_input(codec);
9650 }
9651
9652 #ifdef CONFIG_SND_HDA_POWER_SAVE
9653 static struct hda_amp_list alc861_loopbacks[] = {
9654         { 0x15, HDA_INPUT, 0 },
9655         { 0x15, HDA_INPUT, 1 },
9656         { 0x15, HDA_INPUT, 2 },
9657         { 0x15, HDA_INPUT, 3 },
9658         { } /* end */
9659 };
9660 #endif
9661
9662
9663 /*
9664  * configuration and preset
9665  */
9666 static const char *alc861_models[ALC861_MODEL_LAST] = {
9667         [ALC861_3ST]            = "3stack",
9668         [ALC660_3ST]            = "3stack-660",
9669         [ALC861_3ST_DIG]        = "3stack-dig",
9670         [ALC861_6ST_DIG]        = "6stack-dig",
9671         [ALC861_UNIWILL_M31]    = "uniwill-m31",
9672         [ALC861_TOSHIBA]        = "toshiba",
9673         [ALC861_ASUS]           = "asus",
9674         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
9675         [ALC861_AUTO]           = "auto",
9676 };
9677
9678 static struct snd_pci_quirk alc861_cfg_tbl[] = {
9679         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9680         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9681         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9682         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9683         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9684         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9685         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9686         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9687         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9688          *        Any other models that need this preset?
9689          */
9690         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9691         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9692         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9693         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9694         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9695         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9696         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9697         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9698         {}
9699 };
9700
9701 static struct alc_config_preset alc861_presets[] = {
9702         [ALC861_3ST] = {
9703                 .mixers = { alc861_3ST_mixer },
9704                 .init_verbs = { alc861_threestack_init_verbs },
9705                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9706                 .dac_nids = alc861_dac_nids,
9707                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9708                 .channel_mode = alc861_threestack_modes,
9709                 .need_dac_fix = 1,
9710                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9711                 .adc_nids = alc861_adc_nids,
9712                 .input_mux = &alc861_capture_source,
9713         },
9714         [ALC861_3ST_DIG] = {
9715                 .mixers = { alc861_base_mixer },
9716                 .init_verbs = { alc861_threestack_init_verbs },
9717                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9718                 .dac_nids = alc861_dac_nids,
9719                 .dig_out_nid = ALC861_DIGOUT_NID,
9720                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9721                 .channel_mode = alc861_threestack_modes,
9722                 .need_dac_fix = 1,
9723                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9724                 .adc_nids = alc861_adc_nids,
9725                 .input_mux = &alc861_capture_source,
9726         },
9727         [ALC861_6ST_DIG] = {
9728                 .mixers = { alc861_base_mixer },
9729                 .init_verbs = { alc861_base_init_verbs },
9730                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9731                 .dac_nids = alc861_dac_nids,
9732                 .dig_out_nid = ALC861_DIGOUT_NID,
9733                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9734                 .channel_mode = alc861_8ch_modes,
9735                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9736                 .adc_nids = alc861_adc_nids,
9737                 .input_mux = &alc861_capture_source,
9738         },
9739         [ALC660_3ST] = {
9740                 .mixers = { alc861_3ST_mixer },
9741                 .init_verbs = { alc861_threestack_init_verbs },
9742                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
9743                 .dac_nids = alc660_dac_nids,
9744                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9745                 .channel_mode = alc861_threestack_modes,
9746                 .need_dac_fix = 1,
9747                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9748                 .adc_nids = alc861_adc_nids,
9749                 .input_mux = &alc861_capture_source,
9750         },
9751         [ALC861_UNIWILL_M31] = {
9752                 .mixers = { alc861_uniwill_m31_mixer },
9753                 .init_verbs = { alc861_uniwill_m31_init_verbs },
9754                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9755                 .dac_nids = alc861_dac_nids,
9756                 .dig_out_nid = ALC861_DIGOUT_NID,
9757                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9758                 .channel_mode = alc861_uniwill_m31_modes,
9759                 .need_dac_fix = 1,
9760                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9761                 .adc_nids = alc861_adc_nids,
9762                 .input_mux = &alc861_capture_source,
9763         },
9764         [ALC861_TOSHIBA] = {
9765                 .mixers = { alc861_toshiba_mixer },
9766                 .init_verbs = { alc861_base_init_verbs,
9767                                 alc861_toshiba_init_verbs },
9768                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9769                 .dac_nids = alc861_dac_nids,
9770                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9771                 .channel_mode = alc883_3ST_2ch_modes,
9772                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9773                 .adc_nids = alc861_adc_nids,
9774                 .input_mux = &alc861_capture_source,
9775                 .unsol_event = alc861_toshiba_unsol_event,
9776                 .init_hook = alc861_toshiba_automute,
9777         },
9778         [ALC861_ASUS] = {
9779                 .mixers = { alc861_asus_mixer },
9780                 .init_verbs = { alc861_asus_init_verbs },
9781                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9782                 .dac_nids = alc861_dac_nids,
9783                 .dig_out_nid = ALC861_DIGOUT_NID,
9784                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9785                 .channel_mode = alc861_asus_modes,
9786                 .need_dac_fix = 1,
9787                 .hp_nid = 0x06,
9788                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9789                 .adc_nids = alc861_adc_nids,
9790                 .input_mux = &alc861_capture_source,
9791         },
9792         [ALC861_ASUS_LAPTOP] = {
9793                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9794                 .init_verbs = { alc861_asus_init_verbs,
9795                                 alc861_asus_laptop_init_verbs },
9796                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
9797                 .dac_nids = alc861_dac_nids,
9798                 .dig_out_nid = ALC861_DIGOUT_NID,
9799                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9800                 .channel_mode = alc883_3ST_2ch_modes,
9801                 .need_dac_fix = 1,
9802                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9803                 .adc_nids = alc861_adc_nids,
9804                 .input_mux = &alc861_capture_source,
9805         },
9806 };
9807
9808
9809 static int patch_alc861(struct hda_codec *codec)
9810 {
9811         struct alc_spec *spec;
9812         int board_config;
9813         int err;
9814
9815         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9816         if (spec == NULL)
9817                 return -ENOMEM;
9818
9819         codec->spec = spec;
9820
9821         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9822                                                   alc861_models,
9823                                                   alc861_cfg_tbl);
9824
9825         if (board_config < 0) {
9826                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9827                        "trying auto-probe from BIOS...\n");
9828                 board_config = ALC861_AUTO;
9829         }
9830
9831         if (board_config == ALC861_AUTO) {
9832                 /* automatic parse from the BIOS config */
9833                 err = alc861_parse_auto_config(codec);
9834                 if (err < 0) {
9835                         alc_free(codec);
9836                         return err;
9837                 } else if (!err) {
9838                         printk(KERN_INFO
9839                                "hda_codec: Cannot set up configuration "
9840                                "from BIOS.  Using base mode...\n");
9841                    board_config = ALC861_3ST_DIG;
9842                 }
9843         }
9844
9845         if (board_config != ALC861_AUTO)
9846                 setup_preset(spec, &alc861_presets[board_config]);
9847
9848         spec->stream_name_analog = "ALC861 Analog";
9849         spec->stream_analog_playback = &alc861_pcm_analog_playback;
9850         spec->stream_analog_capture = &alc861_pcm_analog_capture;
9851
9852         spec->stream_name_digital = "ALC861 Digital";
9853         spec->stream_digital_playback = &alc861_pcm_digital_playback;
9854         spec->stream_digital_capture = &alc861_pcm_digital_capture;
9855
9856         codec->patch_ops = alc_patch_ops;
9857         if (board_config == ALC861_AUTO)
9858                 spec->init_hook = alc861_auto_init;
9859 #ifdef CONFIG_SND_HDA_POWER_SAVE
9860         if (!spec->loopback.amplist)
9861                 spec->loopback.amplist = alc861_loopbacks;
9862 #endif
9863                 
9864         return 0;
9865 }
9866
9867 /*
9868  * ALC861-VD support
9869  *
9870  * Based on ALC882
9871  *
9872  * In addition, an independent DAC
9873  */
9874 #define ALC861VD_DIGOUT_NID     0x06
9875
9876 static hda_nid_t alc861vd_dac_nids[4] = {
9877         /* front, surr, clfe, side surr */
9878         0x02, 0x03, 0x04, 0x05
9879 };
9880
9881 /* dac_nids for ALC660vd are in a different order - according to
9882  * Realtek's driver.
9883  * This should probably tesult in a different mixer for 6stack models
9884  * of ALC660vd codecs, but for now there is only 3stack mixer
9885  * - and it is the same as in 861vd.
9886  * adc_nids in ALC660vd are (is) the same as in 861vd
9887  */
9888 static hda_nid_t alc660vd_dac_nids[3] = {
9889         /* front, rear, clfe, rear_surr */
9890         0x02, 0x04, 0x03
9891 };
9892
9893 static hda_nid_t alc861vd_adc_nids[1] = {
9894         /* ADC0 */
9895         0x09,
9896 };
9897
9898 /* input MUX */
9899 /* FIXME: should be a matrix-type input source selection */
9900 static struct hda_input_mux alc861vd_capture_source = {
9901         .num_items = 4,
9902         .items = {
9903                 { "Mic", 0x0 },
9904                 { "Front Mic", 0x1 },
9905                 { "Line", 0x2 },
9906                 { "CD", 0x4 },
9907         },
9908 };
9909
9910 static struct hda_input_mux alc861vd_dallas_capture_source = {
9911         .num_items = 3,
9912         .items = {
9913                 { "Front Mic", 0x0 },
9914                 { "ATAPI Mic", 0x1 },
9915                 { "Line In", 0x5 },
9916         },
9917 };
9918
9919 #define alc861vd_mux_enum_info alc_mux_enum_info
9920 #define alc861vd_mux_enum_get alc_mux_enum_get
9921
9922 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9923                                 struct snd_ctl_elem_value *ucontrol)
9924 {
9925         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9926         struct alc_spec *spec = codec->spec;
9927         const struct hda_input_mux *imux = spec->input_mux;
9928         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9929         static hda_nid_t capture_mixers[1] = { 0x22 };
9930         hda_nid_t nid = capture_mixers[adc_idx];
9931         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9932         unsigned int i, idx;
9933
9934         idx = ucontrol->value.enumerated.item[0];
9935         if (idx >= imux->num_items)
9936                 idx = imux->num_items - 1;
9937         if (*cur_val == idx)
9938                 return 0;
9939         for (i = 0; i < imux->num_items; i++) {
9940                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
9941                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
9942                                          imux->items[i].index,
9943                                          HDA_AMP_MUTE, v);
9944         }
9945         *cur_val = idx;
9946         return 1;
9947 }
9948
9949 /*
9950  * 2ch mode
9951  */
9952 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9953         { 2, NULL }
9954 };
9955
9956 /*
9957  * 6ch mode
9958  */
9959 static struct hda_verb alc861vd_6stack_ch6_init[] = {
9960         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9961         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9962         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9963         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9964         { } /* end */
9965 };
9966
9967 /*
9968  * 8ch mode
9969  */
9970 static struct hda_verb alc861vd_6stack_ch8_init[] = {
9971         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9972         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9973         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9974         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9975         { } /* end */
9976 };
9977
9978 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
9979         { 6, alc861vd_6stack_ch6_init },
9980         { 8, alc861vd_6stack_ch8_init },
9981 };
9982
9983 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
9984         {
9985                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9986                 .name = "Channel Mode",
9987                 .info = alc_ch_mode_info,
9988                 .get = alc_ch_mode_get,
9989                 .put = alc_ch_mode_put,
9990         },
9991         { } /* end */
9992 };
9993
9994 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
9995         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9996         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9997
9998         {
9999                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10000                 /* The multiple "Capture Source" controls confuse alsamixer
10001                  * So call somewhat different..
10002                  *FIXME: the controls appear in the "playback" view!
10003                  */
10004                 /* .name = "Capture Source", */
10005                 .name = "Input Source",
10006                 .count = 1,
10007                 .info = alc861vd_mux_enum_info,
10008                 .get = alc861vd_mux_enum_get,
10009                 .put = alc861vd_mux_enum_put,
10010         },
10011         { } /* end */
10012 };
10013
10014 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10015  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10016  */
10017 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
10018         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10019         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10020
10021         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10022         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
10023
10024         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
10025                                 HDA_OUTPUT),
10026         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
10027                                 HDA_OUTPUT),
10028         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10029         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
10030
10031         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
10032         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
10033
10034         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10035
10036         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10037         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10038         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10039
10040         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10041         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10042         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10043
10044         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10045         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10046
10047         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10048         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10049
10050         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10051         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10052
10053         { } /* end */
10054 };
10055
10056 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
10057         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10058         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10059
10060         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10061
10062         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10063         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10064         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10065
10066         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10067         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10068         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10069
10070         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10071         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10072
10073         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10074         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10075
10076         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10077         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10078
10079         { } /* end */
10080 };
10081
10082 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10083         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10084         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10085         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10086
10087         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10088
10089         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10090         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10091         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10092
10093         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10094         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10095         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10096
10097         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10098         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10099
10100         { } /* end */
10101 };
10102
10103 /* Pin assignment: Front=0x14, HP = 0x15,
10104  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10105  */
10106 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10107         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10108         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10109         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10110         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10111         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10112         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10113         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10114         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10115         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10116         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10117         { } /* end */
10118 };
10119
10120 /*
10121  * generic initialization of ADC, input mixers and output mixers
10122  */
10123 static struct hda_verb alc861vd_volume_init_verbs[] = {
10124         /*
10125          * Unmute ADC0 and set the default input to mic-in
10126          */
10127         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10128         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10129
10130         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10131          * the analog-loopback mixer widget
10132          */
10133         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10134         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10135         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10136         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10137         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10138         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10139
10140         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10141         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10142         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10143         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10144         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10145
10146         /*
10147          * Set up output mixers (0x02 - 0x05)
10148          */
10149         /* set vol=0 to output mixers */
10150         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10151         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10152         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10153         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10154
10155         /* set up input amps for analog loopback */
10156         /* Amp Indices: DAC = 0, mixer = 1 */
10157         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10158         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10159         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10160         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10161         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10162         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10163         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10164         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10165
10166         { }
10167 };
10168
10169 /*
10170  * 3-stack pin configuration:
10171  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10172  */
10173 static struct hda_verb alc861vd_3stack_init_verbs[] = {
10174         /*
10175          * Set pin mode and muting
10176          */
10177         /* set front pin widgets 0x14 for output */
10178         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10179         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10180         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10181
10182         /* Mic (rear) pin: input vref at 80% */
10183         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10184         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10185         /* Front Mic pin: input vref at 80% */
10186         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10187         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10188         /* Line In pin: input */
10189         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10190         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10191         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10192         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10193         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10194         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10195         /* CD pin widget for input */
10196         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10197
10198         { }
10199 };
10200
10201 /*
10202  * 6-stack pin configuration:
10203  */
10204 static struct hda_verb alc861vd_6stack_init_verbs[] = {
10205         /*
10206          * Set pin mode and muting
10207          */
10208         /* set front pin widgets 0x14 for output */
10209         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10210         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10211         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10212
10213         /* Rear Pin: output 1 (0x0d) */
10214         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10215         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10216         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10217         /* CLFE Pin: output 2 (0x0e) */
10218         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10219         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10220         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10221         /* Side Pin: output 3 (0x0f) */
10222         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10223         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10224         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10225
10226         /* Mic (rear) pin: input vref at 80% */
10227         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10228         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10229         /* Front Mic pin: input vref at 80% */
10230         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10231         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10232         /* Line In pin: input */
10233         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10234         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10235         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10236         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10237         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10238         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10239         /* CD pin widget for input */
10240         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10241
10242         { }
10243 };
10244
10245 static struct hda_verb alc861vd_eapd_verbs[] = {
10246         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10247         { }
10248 };
10249
10250 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10251         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10252         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10253         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10254         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10255         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
10256         {}
10257 };
10258
10259 /* toggle speaker-output according to the hp-jack state */
10260 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10261 {
10262         unsigned int present;
10263         unsigned char bits;
10264
10265         present = snd_hda_codec_read(codec, 0x1b, 0,
10266                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10267         bits = present ? HDA_AMP_MUTE : 0;
10268         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10269                                  HDA_AMP_MUTE, bits);
10270 }
10271
10272 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10273 {
10274         unsigned int present;
10275         unsigned char bits;
10276
10277         present = snd_hda_codec_read(codec, 0x18, 0,
10278                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10279         bits = present ? HDA_AMP_MUTE : 0;
10280         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
10281                                  HDA_AMP_MUTE, bits);
10282 }
10283
10284 static void alc861vd_lenovo_automute(struct hda_codec *codec)
10285 {
10286         alc861vd_lenovo_hp_automute(codec);
10287         alc861vd_lenovo_mic_automute(codec);
10288 }
10289
10290 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10291                                         unsigned int res)
10292 {
10293         switch (res >> 26) {
10294         case ALC880_HP_EVENT:
10295                 alc861vd_lenovo_hp_automute(codec);
10296                 break;
10297         case ALC880_MIC_EVENT:
10298                 alc861vd_lenovo_mic_automute(codec);
10299                 break;
10300         }
10301 }
10302
10303 static struct hda_verb alc861vd_dallas_verbs[] = {
10304         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10305         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10306         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10307         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10308
10309         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10310         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10311         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10312         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10313         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10314         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10315         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10316         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10317         
10318         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10319         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10320         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10321         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10322         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10323         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10324         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10325         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10326
10327         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10328         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10329         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10330         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10331         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10332         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10333         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10334         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10335
10336         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10337         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10338         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10339         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10340
10341         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10342         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
10343         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10344
10345         { } /* end */
10346 };
10347
10348 /* toggle speaker-output according to the hp-jack state */
10349 static void alc861vd_dallas_automute(struct hda_codec *codec)
10350 {
10351         unsigned int present;
10352
10353         present = snd_hda_codec_read(codec, 0x15, 0,
10354                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10355         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10356                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10357 }
10358
10359 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10360 {
10361         if ((res >> 26) == ALC880_HP_EVENT)
10362                 alc861vd_dallas_automute(codec);
10363 }
10364
10365 #ifdef CONFIG_SND_HDA_POWER_SAVE
10366 #define alc861vd_loopbacks      alc880_loopbacks
10367 #endif
10368
10369 /* pcm configuration: identiacal with ALC880 */
10370 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
10371 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
10372 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
10373 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
10374
10375 /*
10376  * configuration and preset
10377  */
10378 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10379         [ALC660VD_3ST]          = "3stack-660",
10380         [ALC660VD_3ST_DIG]= "3stack-660-digout",
10381         [ALC861VD_3ST]          = "3stack",
10382         [ALC861VD_3ST_DIG]      = "3stack-digout",
10383         [ALC861VD_6ST_DIG]      = "6stack-digout",
10384         [ALC861VD_LENOVO]       = "lenovo",
10385         [ALC861VD_DALLAS]       = "dallas",
10386         [ALC861VD_AUTO]         = "auto",
10387 };
10388
10389 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10390         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10391         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10392         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10393         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10394         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10395
10396         SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10397         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10398         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10399         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10400         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10401         SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
10402         {}
10403 };
10404
10405 static struct alc_config_preset alc861vd_presets[] = {
10406         [ALC660VD_3ST] = {
10407                 .mixers = { alc861vd_3st_mixer },
10408                 .init_verbs = { alc861vd_volume_init_verbs,
10409                                  alc861vd_3stack_init_verbs },
10410                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10411                 .dac_nids = alc660vd_dac_nids,
10412                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10413                 .adc_nids = alc861vd_adc_nids,
10414                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10415                 .channel_mode = alc861vd_3stack_2ch_modes,
10416                 .input_mux = &alc861vd_capture_source,
10417         },
10418         [ALC660VD_3ST_DIG] = {
10419                 .mixers = { alc861vd_3st_mixer },
10420                 .init_verbs = { alc861vd_volume_init_verbs,
10421                                  alc861vd_3stack_init_verbs },
10422                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10423                 .dac_nids = alc660vd_dac_nids,
10424                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10425                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10426                 .adc_nids = alc861vd_adc_nids,
10427                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10428                 .channel_mode = alc861vd_3stack_2ch_modes,
10429                 .input_mux = &alc861vd_capture_source,
10430         },
10431         [ALC861VD_3ST] = {
10432                 .mixers = { alc861vd_3st_mixer },
10433                 .init_verbs = { alc861vd_volume_init_verbs,
10434                                  alc861vd_3stack_init_verbs },
10435                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10436                 .dac_nids = alc861vd_dac_nids,
10437                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10438                 .channel_mode = alc861vd_3stack_2ch_modes,
10439                 .input_mux = &alc861vd_capture_source,
10440         },
10441         [ALC861VD_3ST_DIG] = {
10442                 .mixers = { alc861vd_3st_mixer },
10443                 .init_verbs = { alc861vd_volume_init_verbs,
10444                                  alc861vd_3stack_init_verbs },
10445                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10446                 .dac_nids = alc861vd_dac_nids,
10447                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10448                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10449                 .channel_mode = alc861vd_3stack_2ch_modes,
10450                 .input_mux = &alc861vd_capture_source,
10451         },
10452         [ALC861VD_6ST_DIG] = {
10453                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10454                 .init_verbs = { alc861vd_volume_init_verbs,
10455                                 alc861vd_6stack_init_verbs },
10456                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10457                 .dac_nids = alc861vd_dac_nids,
10458                 .dig_out_nid = ALC861VD_DIGOUT_NID,
10459                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10460                 .channel_mode = alc861vd_6stack_modes,
10461                 .input_mux = &alc861vd_capture_source,
10462         },
10463         [ALC861VD_LENOVO] = {
10464                 .mixers = { alc861vd_lenovo_mixer },
10465                 .init_verbs = { alc861vd_volume_init_verbs,
10466                                 alc861vd_3stack_init_verbs,
10467                                 alc861vd_eapd_verbs,
10468                                 alc861vd_lenovo_unsol_verbs },
10469                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10470                 .dac_nids = alc660vd_dac_nids,
10471                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10472                 .adc_nids = alc861vd_adc_nids,
10473                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10474                 .channel_mode = alc861vd_3stack_2ch_modes,
10475                 .input_mux = &alc861vd_capture_source,
10476                 .unsol_event = alc861vd_lenovo_unsol_event,
10477                 .init_hook = alc861vd_lenovo_automute,
10478         },
10479         [ALC861VD_DALLAS] = {
10480                 .mixers = { alc861vd_dallas_mixer },
10481                 .init_verbs = { alc861vd_dallas_verbs },
10482                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10483                 .dac_nids = alc861vd_dac_nids,
10484                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10485                 .adc_nids = alc861vd_adc_nids,
10486                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10487                 .channel_mode = alc861vd_3stack_2ch_modes,
10488                 .input_mux = &alc861vd_dallas_capture_source,
10489                 .unsol_event = alc861vd_dallas_unsol_event,
10490                 .init_hook = alc861vd_dallas_automute,
10491         },      
10492 };
10493
10494 /*
10495  * BIOS auto configuration
10496  */
10497 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10498                                 hda_nid_t nid, int pin_type, int dac_idx)
10499 {
10500         /* set as output */
10501         snd_hda_codec_write(codec, nid, 0,
10502                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10503         snd_hda_codec_write(codec, nid, 0,
10504                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10505 }
10506
10507 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10508 {
10509         struct alc_spec *spec = codec->spec;
10510         int i;
10511
10512         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10513         for (i = 0; i <= HDA_SIDE; i++) {
10514                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10515                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10516                 if (nid)
10517                         alc861vd_auto_set_output_and_unmute(codec, nid,
10518                                                             pin_type, i);
10519         }
10520 }
10521
10522
10523 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10524 {
10525         struct alc_spec *spec = codec->spec;
10526         hda_nid_t pin;
10527
10528         pin = spec->autocfg.hp_pins[0];
10529         if (pin) /* connect to front and  use dac 0 */
10530                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10531 }
10532
10533 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
10534 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
10535
10536 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10537 {
10538         struct alc_spec *spec = codec->spec;
10539         int i;
10540
10541         for (i = 0; i < AUTO_PIN_LAST; i++) {
10542                 hda_nid_t nid = spec->autocfg.input_pins[i];
10543                 if (alc861vd_is_input_pin(nid)) {
10544                         snd_hda_codec_write(codec, nid, 0,
10545                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
10546                                         i <= AUTO_PIN_FRONT_MIC ?
10547                                                         PIN_VREF80 : PIN_IN);
10548                         if (nid != ALC861VD_PIN_CD_NID)
10549                                 snd_hda_codec_write(codec, nid, 0,
10550                                                 AC_VERB_SET_AMP_GAIN_MUTE,
10551                                                 AMP_OUT_MUTE);
10552                 }
10553         }
10554 }
10555
10556 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
10557 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
10558
10559 /* add playback controls from the parsed DAC table */
10560 /* Based on ALC880 version. But ALC861VD has separate,
10561  * different NIDs for mute/unmute switch and volume control */
10562 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10563                                              const struct auto_pin_cfg *cfg)
10564 {
10565         char name[32];
10566         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10567         hda_nid_t nid_v, nid_s;
10568         int i, err;
10569
10570         for (i = 0; i < cfg->line_outs; i++) {
10571                 if (!spec->multiout.dac_nids[i])
10572                         continue;
10573                 nid_v = alc861vd_idx_to_mixer_vol(
10574                                 alc880_dac_to_idx(
10575                                         spec->multiout.dac_nids[i]));
10576                 nid_s = alc861vd_idx_to_mixer_switch(
10577                                 alc880_dac_to_idx(
10578                                         spec->multiout.dac_nids[i]));
10579
10580                 if (i == 2) {
10581                         /* Center/LFE */
10582                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10583                                           "Center Playback Volume",
10584                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10585                                                               HDA_OUTPUT));
10586                         if (err < 0)
10587                                 return err;
10588                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
10589                                           "LFE Playback Volume",
10590                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10591                                                               HDA_OUTPUT));
10592                         if (err < 0)
10593                                 return err;
10594                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10595                                           "Center Playback Switch",
10596                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10597                                                               HDA_INPUT));
10598                         if (err < 0)
10599                                 return err;
10600                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10601                                           "LFE Playback Switch",
10602                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10603                                                               HDA_INPUT));
10604                         if (err < 0)
10605                                 return err;
10606                 } else {
10607                         sprintf(name, "%s Playback Volume", chname[i]);
10608                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10609                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10610                                                               HDA_OUTPUT));
10611                         if (err < 0)
10612                                 return err;
10613                         sprintf(name, "%s Playback Switch", chname[i]);
10614                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10615                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10616                                                               HDA_INPUT));
10617                         if (err < 0)
10618                                 return err;
10619                 }
10620         }
10621         return 0;
10622 }
10623
10624 /* add playback controls for speaker and HP outputs */
10625 /* Based on ALC880 version. But ALC861VD has separate,
10626  * different NIDs for mute/unmute switch and volume control */
10627 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10628                                         hda_nid_t pin, const char *pfx)
10629 {
10630         hda_nid_t nid_v, nid_s;
10631         int err;
10632         char name[32];
10633
10634         if (!pin)
10635                 return 0;
10636
10637         if (alc880_is_fixed_pin(pin)) {
10638                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10639                 /* specify the DAC as the extra output */
10640                 if (!spec->multiout.hp_nid)
10641                         spec->multiout.hp_nid = nid_v;
10642                 else
10643                         spec->multiout.extra_out_nid[0] = nid_v;
10644                 /* control HP volume/switch on the output mixer amp */
10645                 nid_v = alc861vd_idx_to_mixer_vol(
10646                                 alc880_fixed_pin_idx(pin));
10647                 nid_s = alc861vd_idx_to_mixer_switch(
10648                                 alc880_fixed_pin_idx(pin));
10649
10650                 sprintf(name, "%s Playback Volume", pfx);
10651                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10652                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10653                 if (err < 0)
10654                         return err;
10655                 sprintf(name, "%s Playback Switch", pfx);
10656                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10657                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10658                 if (err < 0)
10659                         return err;
10660         } else if (alc880_is_multi_pin(pin)) {
10661                 /* set manual connection */
10662                 /* we have only a switch on HP-out PIN */
10663                 sprintf(name, "%s Playback Switch", pfx);
10664                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10665                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10666                 if (err < 0)
10667                         return err;
10668         }
10669         return 0;
10670 }
10671
10672 /* parse the BIOS configuration and set up the alc_spec
10673  * return 1 if successful, 0 if the proper config is not found,
10674  * or a negative error code
10675  * Based on ALC880 version - had to change it to override
10676  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10677 static int alc861vd_parse_auto_config(struct hda_codec *codec)
10678 {
10679         struct alc_spec *spec = codec->spec;
10680         int err;
10681         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10682
10683         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10684                                            alc861vd_ignore);
10685         if (err < 0)
10686                 return err;
10687         if (!spec->autocfg.line_outs)
10688                 return 0; /* can't find valid BIOS pin config */
10689
10690         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10691         if (err < 0)
10692                 return err;
10693         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10694         if (err < 0)
10695                 return err;
10696         err = alc861vd_auto_create_extra_out(spec,
10697                                              spec->autocfg.speaker_pins[0],
10698                                              "Speaker");
10699         if (err < 0)
10700                 return err;
10701         err = alc861vd_auto_create_extra_out(spec,
10702                                              spec->autocfg.hp_pins[0],
10703                                              "Headphone");
10704         if (err < 0)
10705                 return err;
10706         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10707         if (err < 0)
10708                 return err;
10709
10710         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10711
10712         if (spec->autocfg.dig_out_pin)
10713                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10714
10715         if (spec->kctl_alloc)
10716                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10717
10718         spec->init_verbs[spec->num_init_verbs++]
10719                 = alc861vd_volume_init_verbs;
10720
10721         spec->num_mux_defs = 1;
10722         spec->input_mux = &spec->private_imux;
10723
10724         return 1;
10725 }
10726
10727 /* additional initialization for auto-configuration model */
10728 static void alc861vd_auto_init(struct hda_codec *codec)
10729 {
10730         alc861vd_auto_init_multi_out(codec);
10731         alc861vd_auto_init_hp_out(codec);
10732         alc861vd_auto_init_analog_input(codec);
10733 }
10734
10735 static int patch_alc861vd(struct hda_codec *codec)
10736 {
10737         struct alc_spec *spec;
10738         int err, board_config;
10739
10740         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10741         if (spec == NULL)
10742                 return -ENOMEM;
10743
10744         codec->spec = spec;
10745
10746         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10747                                                   alc861vd_models,
10748                                                   alc861vd_cfg_tbl);
10749
10750         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10751                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10752                         "ALC861VD, trying auto-probe from BIOS...\n");
10753                 board_config = ALC861VD_AUTO;
10754         }
10755
10756         if (board_config == ALC861VD_AUTO) {
10757                 /* automatic parse from the BIOS config */
10758                 err = alc861vd_parse_auto_config(codec);
10759                 if (err < 0) {
10760                         alc_free(codec);
10761                         return err;
10762                 } else if (!err) {
10763                         printk(KERN_INFO
10764                                "hda_codec: Cannot set up configuration "
10765                                "from BIOS.  Using base mode...\n");
10766                         board_config = ALC861VD_3ST;
10767                 }
10768         }
10769
10770         if (board_config != ALC861VD_AUTO)
10771                 setup_preset(spec, &alc861vd_presets[board_config]);
10772
10773         spec->stream_name_analog = "ALC861VD Analog";
10774         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10775         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10776
10777         spec->stream_name_digital = "ALC861VD Digital";
10778         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10779         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10780
10781         spec->adc_nids = alc861vd_adc_nids;
10782         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10783
10784         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10785         spec->num_mixers++;
10786
10787         codec->patch_ops = alc_patch_ops;
10788
10789         if (board_config == ALC861VD_AUTO)
10790                 spec->init_hook = alc861vd_auto_init;
10791 #ifdef CONFIG_SND_HDA_POWER_SAVE
10792         if (!spec->loopback.amplist)
10793                 spec->loopback.amplist = alc861vd_loopbacks;
10794 #endif
10795
10796         return 0;
10797 }
10798
10799 /*
10800  * ALC662 support
10801  *
10802  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10803  * configuration.  Each pin widget can choose any input DACs and a mixer.
10804  * Each ADC is connected from a mixer of all inputs.  This makes possible
10805  * 6-channel independent captures.
10806  *
10807  * In addition, an independent DAC for the multi-playback (not used in this
10808  * driver yet).
10809  */
10810 #define ALC662_DIGOUT_NID       0x06
10811 #define ALC662_DIGIN_NID        0x0a
10812
10813 static hda_nid_t alc662_dac_nids[4] = {
10814         /* front, rear, clfe, rear_surr */
10815         0x02, 0x03, 0x04
10816 };
10817
10818 static hda_nid_t alc662_adc_nids[1] = {
10819         /* ADC1-2 */
10820         0x09,
10821 };
10822 /* input MUX */
10823 /* FIXME: should be a matrix-type input source selection */
10824
10825 static struct hda_input_mux alc662_capture_source = {
10826         .num_items = 4,
10827         .items = {
10828                 { "Mic", 0x0 },
10829                 { "Front Mic", 0x1 },
10830                 { "Line", 0x2 },
10831                 { "CD", 0x4 },
10832         },
10833 };
10834
10835 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10836         .num_items = 2,
10837         .items = {
10838                 { "Mic", 0x1 },
10839                 { "Line", 0x2 },
10840         },
10841 };
10842 #define alc662_mux_enum_info alc_mux_enum_info
10843 #define alc662_mux_enum_get alc_mux_enum_get
10844
10845 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10846                                struct snd_ctl_elem_value *ucontrol)
10847 {
10848         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10849         struct alc_spec *spec = codec->spec;
10850         const struct hda_input_mux *imux = spec->input_mux;
10851         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10852         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
10853         hda_nid_t nid = capture_mixers[adc_idx];
10854         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10855         unsigned int i, idx;
10856
10857         idx = ucontrol->value.enumerated.item[0];
10858         if (idx >= imux->num_items)
10859                 idx = imux->num_items - 1;
10860         if (*cur_val == idx)
10861                 return 0;
10862         for (i = 0; i < imux->num_items; i++) {
10863                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10864                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10865                                          imux->items[i].index,
10866                                          HDA_AMP_MUTE, v);
10867         }
10868         *cur_val = idx;
10869         return 1;
10870 }
10871 /*
10872  * 2ch mode
10873  */
10874 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10875         { 2, NULL }
10876 };
10877
10878 /*
10879  * 2ch mode
10880  */
10881 static struct hda_verb alc662_3ST_ch2_init[] = {
10882         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10883         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10884         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10885         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10886         { } /* end */
10887 };
10888
10889 /*
10890  * 6ch mode
10891  */
10892 static struct hda_verb alc662_3ST_ch6_init[] = {
10893         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10894         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10895         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10896         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10897         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10898         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10899         { } /* end */
10900 };
10901
10902 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10903         { 2, alc662_3ST_ch2_init },
10904         { 6, alc662_3ST_ch6_init },
10905 };
10906
10907 /*
10908  * 2ch mode
10909  */
10910 static struct hda_verb alc662_sixstack_ch6_init[] = {
10911         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10912         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10913         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10914         { } /* end */
10915 };
10916
10917 /*
10918  * 6ch mode
10919  */
10920 static struct hda_verb alc662_sixstack_ch8_init[] = {
10921         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10922         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10923         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10924         { } /* end */
10925 };
10926
10927 static struct hda_channel_mode alc662_5stack_modes[2] = {
10928         { 2, alc662_sixstack_ch6_init },
10929         { 6, alc662_sixstack_ch8_init },
10930 };
10931
10932 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10933  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10934  */
10935
10936 static struct snd_kcontrol_new alc662_base_mixer[] = {
10937         /* output mixer control */
10938         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10939         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
10940         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10941         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10942         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10943         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10944         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10945         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10946         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10947
10948         /*Input mixer control */
10949         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
10950         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
10951         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
10952         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
10953         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
10954         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
10955         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
10956         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
10957
10958         /* Capture mixer control */
10959         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10960         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10961         {
10962                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10963                 .name = "Capture Source",
10964                 .count = 1,
10965                 .info = alc_mux_enum_info,
10966                 .get = alc_mux_enum_get,
10967                 .put = alc_mux_enum_put,
10968         },
10969         { } /* end */
10970 };
10971
10972 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
10973         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10974         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10975         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10976         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10977         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10978         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10979         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10980         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10981         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10982         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10983         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10984         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10985         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10986         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10987         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10988         {
10989                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10990                 /* .name = "Capture Source", */
10991                 .name = "Input Source",
10992                 .count = 1,
10993                 .info = alc662_mux_enum_info,
10994                 .get = alc662_mux_enum_get,
10995                 .put = alc662_mux_enum_put,
10996         },
10997         { } /* end */
10998 };
10999
11000 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
11001         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11002         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11003         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11004         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
11005         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11006         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11007         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11008         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11009         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11010         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11011         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11012         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11013         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11014         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11015         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11016         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11017         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11018         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11019         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11020         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11021         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11022         {
11023                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11024                 /* .name = "Capture Source", */
11025                 .name = "Input Source",
11026                 .count = 1,
11027                 .info = alc662_mux_enum_info,
11028                 .get = alc662_mux_enum_get,
11029                 .put = alc662_mux_enum_put,
11030         },
11031         { } /* end */
11032 };
11033
11034 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
11035         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11036         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11037         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11038         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
11039         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11040         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11041         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11042         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11043         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11044         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11045         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11046         {
11047                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11048                 /* .name = "Capture Source", */
11049                 .name = "Input Source",
11050                 .count = 1,
11051                 .info = alc662_mux_enum_info,
11052                 .get = alc662_mux_enum_get,
11053                 .put = alc662_mux_enum_put,
11054         },
11055         { } /* end */
11056 };
11057
11058 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11059         {
11060                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11061                 .name = "Channel Mode",
11062                 .info = alc_ch_mode_info,
11063                 .get = alc_ch_mode_get,
11064                 .put = alc_ch_mode_put,
11065         },
11066         { } /* end */
11067 };
11068
11069 static struct hda_verb alc662_init_verbs[] = {
11070         /* ADC: mute amp left and right */
11071         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11072         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11073         /* Front mixer: unmute input/output amp left and right (volume = 0) */
11074
11075         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11076         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11077         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11078         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11079         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11080
11081         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11082         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11083         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11084         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11085         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11086         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11087
11088         /* Front Pin: output 0 (0x0c) */
11089         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11090         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11091
11092         /* Rear Pin: output 1 (0x0d) */
11093         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11094         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11095
11096         /* CLFE Pin: output 2 (0x0e) */
11097         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11098         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11099
11100         /* Mic (rear) pin: input vref at 80% */
11101         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11102         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11103         /* Front Mic pin: input vref at 80% */
11104         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11105         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11106         /* Line In pin: input */
11107         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11108         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11109         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11110         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11111         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11112         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11113         /* CD pin widget for input */
11114         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11115
11116         /* FIXME: use matrix-type input source selection */
11117         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11118         /* Input mixer */
11119         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11120         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11121         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11122         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11123         { }
11124 };
11125
11126 static struct hda_verb alc662_sue_init_verbs[] = {
11127         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11128         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11129         {}
11130 };
11131
11132 /*
11133  * generic initialization of ADC, input mixers and output mixers
11134  */
11135 static struct hda_verb alc662_auto_init_verbs[] = {
11136         /*
11137          * Unmute ADC and set the default input to mic-in
11138          */
11139         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11140         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11141
11142         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11143          * mixer widget
11144          * Note: PASD motherboards uses the Line In 2 as the input for front
11145          * panel mic (mic 2)
11146          */
11147         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11148         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11149         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11150         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11151         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11152         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11153
11154         /*
11155          * Set up output mixers (0x0c - 0x0f)
11156          */
11157         /* set vol=0 to output mixers */
11158         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11159         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11160         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11161
11162         /* set up input amps for analog loopback */
11163         /* Amp Indices: DAC = 0, mixer = 1 */
11164         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11165         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11166         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11167         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11168         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11169         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11170
11171
11172         /* FIXME: use matrix-type input source selection */
11173         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11174         /* Input mixer */
11175         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11176         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11177         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11178         /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
11179         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11180
11181         { }
11182 };
11183
11184 /* capture mixer elements */
11185 static struct snd_kcontrol_new alc662_capture_mixer[] = {
11186         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11187         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11188         {
11189                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11190                 /* The multiple "Capture Source" controls confuse alsamixer
11191                  * So call somewhat different..
11192                  * FIXME: the controls appear in the "playback" view!
11193                  */
11194                 /* .name = "Capture Source", */
11195                 .name = "Input Source",
11196                 .count = 1,
11197                 .info = alc882_mux_enum_info,
11198                 .get = alc882_mux_enum_get,
11199                 .put = alc882_mux_enum_put,
11200         },
11201         { } /* end */
11202 };
11203
11204 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11205 {
11206         unsigned int present;
11207         unsigned char bits;
11208
11209         present = snd_hda_codec_read(codec, 0x14, 0,
11210                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11211         bits = present ? HDA_AMP_MUTE : 0;
11212         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11213                                  HDA_AMP_MUTE, bits);
11214 }
11215
11216 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11217 {
11218         unsigned int present;
11219         unsigned char bits;
11220
11221         present = snd_hda_codec_read(codec, 0x1b, 0,
11222                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11223         bits = present ? HDA_AMP_MUTE : 0;
11224         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11225                                  HDA_AMP_MUTE, bits);
11226         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11227                                  HDA_AMP_MUTE, bits);
11228 }
11229
11230 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11231                                            unsigned int res)
11232 {
11233         if ((res >> 26) == ALC880_HP_EVENT)
11234                 alc662_lenovo_101e_all_automute(codec);
11235         if ((res >> 26) == ALC880_FRONT_EVENT)
11236                 alc662_lenovo_101e_ispeaker_automute(codec);
11237 }
11238
11239 #ifdef CONFIG_SND_HDA_POWER_SAVE
11240 #define alc662_loopbacks        alc880_loopbacks
11241 #endif
11242
11243
11244 /* pcm configuration: identiacal with ALC880 */
11245 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
11246 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
11247 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
11248 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
11249
11250 /*
11251  * configuration and preset
11252  */
11253 static const char *alc662_models[ALC662_MODEL_LAST] = {
11254         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
11255         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
11256         [ALC662_3ST_6ch]        = "3stack-6ch",
11257         [ALC662_5ST_DIG]        = "6stack-dig",
11258         [ALC662_LENOVO_101E]    = "lenovo-101e",
11259         [ALC662_AUTO]           = "auto",
11260 };
11261
11262 static struct snd_pci_quirk alc662_cfg_tbl[] = {
11263         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11264         {}
11265 };
11266
11267 static struct alc_config_preset alc662_presets[] = {
11268         [ALC662_3ST_2ch_DIG] = {
11269                 .mixers = { alc662_3ST_2ch_mixer },
11270                 .init_verbs = { alc662_init_verbs },
11271                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11272                 .dac_nids = alc662_dac_nids,
11273                 .dig_out_nid = ALC662_DIGOUT_NID,
11274                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11275                 .adc_nids = alc662_adc_nids,
11276                 .dig_in_nid = ALC662_DIGIN_NID,
11277                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11278                 .channel_mode = alc662_3ST_2ch_modes,
11279                 .input_mux = &alc662_capture_source,
11280         },
11281         [ALC662_3ST_6ch_DIG] = {
11282                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11283                 .init_verbs = { alc662_init_verbs },
11284                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11285                 .dac_nids = alc662_dac_nids,
11286                 .dig_out_nid = ALC662_DIGOUT_NID,
11287                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11288                 .adc_nids = alc662_adc_nids,
11289                 .dig_in_nid = ALC662_DIGIN_NID,
11290                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11291                 .channel_mode = alc662_3ST_6ch_modes,
11292                 .need_dac_fix = 1,
11293                 .input_mux = &alc662_capture_source,
11294         },
11295         [ALC662_3ST_6ch] = {
11296                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11297                 .init_verbs = { alc662_init_verbs },
11298                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11299                 .dac_nids = alc662_dac_nids,
11300                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11301                 .adc_nids = alc662_adc_nids,
11302                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11303                 .channel_mode = alc662_3ST_6ch_modes,
11304                 .need_dac_fix = 1,
11305                 .input_mux = &alc662_capture_source,
11306         },
11307         [ALC662_5ST_DIG] = {
11308                 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
11309                 .init_verbs = { alc662_init_verbs },
11310                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11311                 .dac_nids = alc662_dac_nids,
11312                 .dig_out_nid = ALC662_DIGOUT_NID,
11313                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11314                 .adc_nids = alc662_adc_nids,
11315                 .dig_in_nid = ALC662_DIGIN_NID,
11316                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11317                 .channel_mode = alc662_5stack_modes,
11318                 .input_mux = &alc662_capture_source,
11319         },
11320         [ALC662_LENOVO_101E] = {
11321                 .mixers = { alc662_lenovo_101e_mixer },
11322                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11323                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
11324                 .dac_nids = alc662_dac_nids,
11325                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11326                 .adc_nids = alc662_adc_nids,
11327                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11328                 .channel_mode = alc662_3ST_2ch_modes,
11329                 .input_mux = &alc662_lenovo_101e_capture_source,
11330                 .unsol_event = alc662_lenovo_101e_unsol_event,
11331                 .init_hook = alc662_lenovo_101e_all_automute,
11332         },
11333
11334 };
11335
11336
11337 /*
11338  * BIOS auto configuration
11339  */
11340
11341 /* add playback controls from the parsed DAC table */
11342 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11343                                              const struct auto_pin_cfg *cfg)
11344 {
11345         char name[32];
11346         static const char *chname[4] = {
11347                 "Front", "Surround", NULL /*CLFE*/, "Side"
11348         };
11349         hda_nid_t nid;
11350         int i, err;
11351
11352         for (i = 0; i < cfg->line_outs; i++) {
11353                 if (!spec->multiout.dac_nids[i])
11354                         continue;
11355                 nid = alc880_idx_to_mixer(i);
11356                 if (i == 2) {
11357                         /* Center/LFE */
11358                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11359                                           "Center Playback Volume",
11360                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11361                                                               HDA_OUTPUT));
11362                         if (err < 0)
11363                                 return err;
11364                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11365                                           "LFE Playback Volume",
11366                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11367                                                               HDA_OUTPUT));
11368                         if (err < 0)
11369                                 return err;
11370                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11371                                           "Center Playback Switch",
11372                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11373                                                               HDA_INPUT));
11374                         if (err < 0)
11375                                 return err;
11376                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11377                                           "LFE Playback Switch",
11378                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11379                                                               HDA_INPUT));
11380                         if (err < 0)
11381                                 return err;
11382                 } else {
11383                         sprintf(name, "%s Playback Volume", chname[i]);
11384                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11385                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11386                                                               HDA_OUTPUT));
11387                         if (err < 0)
11388                                 return err;
11389                         sprintf(name, "%s Playback Switch", chname[i]);
11390                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11391                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11392                                                               HDA_INPUT));
11393                         if (err < 0)
11394                                 return err;
11395                 }
11396         }
11397         return 0;
11398 }
11399
11400 /* add playback controls for speaker and HP outputs */
11401 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11402                                         const char *pfx)
11403 {
11404         hda_nid_t nid;
11405         int err;
11406         char name[32];
11407
11408         if (!pin)
11409                 return 0;
11410
11411         if (alc880_is_fixed_pin(pin)) {
11412                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11413                 /* printk("DAC nid=%x\n",nid); */
11414                 /* specify the DAC as the extra output */
11415                 if (!spec->multiout.hp_nid)
11416                         spec->multiout.hp_nid = nid;
11417                 else
11418                         spec->multiout.extra_out_nid[0] = nid;
11419                 /* control HP volume/switch on the output mixer amp */
11420                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11421                 sprintf(name, "%s Playback Volume", pfx);
11422                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11423                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11424                 if (err < 0)
11425                         return err;
11426                 sprintf(name, "%s Playback Switch", pfx);
11427                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11428                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11429                 if (err < 0)
11430                         return err;
11431         } else if (alc880_is_multi_pin(pin)) {
11432                 /* set manual connection */
11433                 /* we have only a switch on HP-out PIN */
11434                 sprintf(name, "%s Playback Switch", pfx);
11435                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11436                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11437                 if (err < 0)
11438                         return err;
11439         }
11440         return 0;
11441 }
11442
11443 /* create playback/capture controls for input pins */
11444 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11445                                                 const struct auto_pin_cfg *cfg)
11446 {
11447         struct hda_input_mux *imux = &spec->private_imux;
11448         int i, err, idx;
11449
11450         for (i = 0; i < AUTO_PIN_LAST; i++) {
11451                 if (alc880_is_input_pin(cfg->input_pins[i])) {
11452                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
11453                         err = new_analog_input(spec, cfg->input_pins[i],
11454                                                auto_pin_cfg_labels[i],
11455                                                idx, 0x0b);
11456                         if (err < 0)
11457                                 return err;
11458                         imux->items[imux->num_items].label =
11459                                 auto_pin_cfg_labels[i];
11460                         imux->items[imux->num_items].index =
11461                                 alc880_input_pin_idx(cfg->input_pins[i]);
11462                         imux->num_items++;
11463                 }
11464         }
11465         return 0;
11466 }
11467
11468 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11469                                               hda_nid_t nid, int pin_type,
11470                                               int dac_idx)
11471 {
11472         /* set as output */
11473         snd_hda_codec_write(codec, nid, 0,
11474                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11475         snd_hda_codec_write(codec, nid, 0,
11476                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11477         /* need the manual connection? */
11478         if (alc880_is_multi_pin(nid)) {
11479                 struct alc_spec *spec = codec->spec;
11480                 int idx = alc880_multi_pin_idx(nid);
11481                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11482                                     AC_VERB_SET_CONNECT_SEL,
11483                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11484         }
11485 }
11486
11487 static void alc662_auto_init_multi_out(struct hda_codec *codec)
11488 {
11489         struct alc_spec *spec = codec->spec;
11490         int i;
11491
11492         for (i = 0; i <= HDA_SIDE; i++) {
11493                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11494                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11495                 if (nid)
11496                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11497                                                           i);
11498         }
11499 }
11500
11501 static void alc662_auto_init_hp_out(struct hda_codec *codec)
11502 {
11503         struct alc_spec *spec = codec->spec;
11504         hda_nid_t pin;
11505
11506         pin = spec->autocfg.hp_pins[0];
11507         if (pin) /* connect to front */
11508                 /* use dac 0 */
11509                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11510 }
11511
11512 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
11513 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
11514
11515 static void alc662_auto_init_analog_input(struct hda_codec *codec)
11516 {
11517         struct alc_spec *spec = codec->spec;
11518         int i;
11519
11520         for (i = 0; i < AUTO_PIN_LAST; i++) {
11521                 hda_nid_t nid = spec->autocfg.input_pins[i];
11522                 if (alc662_is_input_pin(nid)) {
11523                         snd_hda_codec_write(codec, nid, 0,
11524                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
11525                                             (i <= AUTO_PIN_FRONT_MIC ?
11526                                              PIN_VREF80 : PIN_IN));
11527                         if (nid != ALC662_PIN_CD_NID)
11528                                 snd_hda_codec_write(codec, nid, 0,
11529                                                     AC_VERB_SET_AMP_GAIN_MUTE,
11530                                                     AMP_OUT_MUTE);
11531                 }
11532         }
11533 }
11534
11535 static int alc662_parse_auto_config(struct hda_codec *codec)
11536 {
11537         struct alc_spec *spec = codec->spec;
11538         int err;
11539         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11540
11541         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11542                                            alc662_ignore);
11543         if (err < 0)
11544                 return err;
11545         if (!spec->autocfg.line_outs)
11546                 return 0; /* can't find valid BIOS pin config */
11547
11548         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11549         if (err < 0)
11550                 return err;
11551         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11552         if (err < 0)
11553                 return err;
11554         err = alc662_auto_create_extra_out(spec,
11555                                            spec->autocfg.speaker_pins[0],
11556                                            "Speaker");
11557         if (err < 0)
11558                 return err;
11559         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11560                                            "Headphone");
11561         if (err < 0)
11562                 return err;
11563         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11564         if (err < 0)
11565                 return err;
11566
11567         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11568
11569         if (spec->autocfg.dig_out_pin)
11570                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11571
11572         if (spec->kctl_alloc)
11573                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11574
11575         spec->num_mux_defs = 1;
11576         spec->input_mux = &spec->private_imux;
11577         
11578         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11579         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11580         spec->num_mixers++;
11581         return 1;
11582 }
11583
11584 /* additional initialization for auto-configuration model */
11585 static void alc662_auto_init(struct hda_codec *codec)
11586 {
11587         alc662_auto_init_multi_out(codec);
11588         alc662_auto_init_hp_out(codec);
11589         alc662_auto_init_analog_input(codec);
11590 }
11591
11592 static int patch_alc662(struct hda_codec *codec)
11593 {
11594         struct alc_spec *spec;
11595         int err, board_config;
11596
11597         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11598         if (!spec)
11599                 return -ENOMEM;
11600
11601         codec->spec = spec;
11602
11603         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11604                                                   alc662_models,
11605                                                   alc662_cfg_tbl);
11606         if (board_config < 0) {
11607                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11608                        "trying auto-probe from BIOS...\n");
11609                 board_config = ALC662_AUTO;
11610         }
11611
11612         if (board_config == ALC662_AUTO) {
11613                 /* automatic parse from the BIOS config */
11614                 err = alc662_parse_auto_config(codec);
11615                 if (err < 0) {
11616                         alc_free(codec);
11617                         return err;
11618                 } else if (!err) {
11619                         printk(KERN_INFO
11620                                "hda_codec: Cannot set up configuration "
11621                                "from BIOS.  Using base mode...\n");
11622                         board_config = ALC662_3ST_2ch_DIG;
11623                 }
11624         }
11625
11626         if (board_config != ALC662_AUTO)
11627                 setup_preset(spec, &alc662_presets[board_config]);
11628
11629         spec->stream_name_analog = "ALC662 Analog";
11630         spec->stream_analog_playback = &alc662_pcm_analog_playback;
11631         spec->stream_analog_capture = &alc662_pcm_analog_capture;
11632
11633         spec->stream_name_digital = "ALC662 Digital";
11634         spec->stream_digital_playback = &alc662_pcm_digital_playback;
11635         spec->stream_digital_capture = &alc662_pcm_digital_capture;
11636
11637         if (!spec->adc_nids && spec->input_mux) {
11638                 spec->adc_nids = alc662_adc_nids;
11639                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11640         }
11641
11642         codec->patch_ops = alc_patch_ops;
11643         if (board_config == ALC662_AUTO)
11644                 spec->init_hook = alc662_auto_init;
11645 #ifdef CONFIG_SND_HDA_POWER_SAVE
11646         if (!spec->loopback.amplist)
11647                 spec->loopback.amplist = alc662_loopbacks;
11648 #endif
11649
11650         return 0;
11651 }
11652
11653 /*
11654  * patch entries
11655  */
11656 struct hda_codec_preset snd_hda_preset_realtek[] = {
11657         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11658         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11659         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11660         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11661           .patch = patch_alc861 },
11662         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11663         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11664         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11665         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11666           .patch = patch_alc883 },
11667         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11668           .patch = patch_alc662 },
11669         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11670         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11671         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11672         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11673         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11674         {} /* terminator */
11675 };