]> git.karo-electronics.de Git - mv-sheeva.git/blob - sound/pci/hda/patch_realtek.c
[ALSA] hda-codec - Add ALC889/ALC267/ALC269 support
[mv-sheeva.git] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_HP_TC_T5735,
96         ALC262_BENQ_ED8,
97         ALC262_SONY_ASSAMD,
98         ALC262_BENQ_T31,
99         ALC262_ULTRA,
100         ALC262_AUTO,
101         ALC262_MODEL_LAST /* last tag */
102 };
103
104 /* ALC268 models */
105 enum {
106         ALC268_3ST,
107         ALC268_TOSHIBA,
108         ALC268_ACER,
109         ALC268_AUTO,
110         ALC268_MODEL_LAST /* last tag */
111 };
112
113 /* ALC269 models */
114 enum {
115         ALC269_BASIC,
116         ALC269_AUTO,
117         ALC269_MODEL_LAST /* last tag */
118 };
119
120 /* ALC861 models */
121 enum {
122         ALC861_3ST,
123         ALC660_3ST,
124         ALC861_3ST_DIG,
125         ALC861_6ST_DIG,
126         ALC861_UNIWILL_M31,
127         ALC861_TOSHIBA,
128         ALC861_ASUS,
129         ALC861_ASUS_LAPTOP,
130         ALC861_AUTO,
131         ALC861_MODEL_LAST,
132 };
133
134 /* ALC861-VD models */
135 enum {
136         ALC660VD_3ST,
137         ALC660VD_3ST_DIG,
138         ALC861VD_3ST,
139         ALC861VD_3ST_DIG,
140         ALC861VD_6ST_DIG,
141         ALC861VD_LENOVO,
142         ALC861VD_DALLAS,
143         ALC861VD_HP,
144         ALC861VD_AUTO,
145         ALC861VD_MODEL_LAST,
146 };
147
148 /* ALC662 models */
149 enum {
150         ALC662_3ST_2ch_DIG,
151         ALC662_3ST_6ch_DIG,
152         ALC662_3ST_6ch,
153         ALC662_5ST_DIG,
154         ALC662_LENOVO_101E,
155         ALC662_ASUS_EEEPC_P701,
156         ALC662_AUTO,
157         ALC662_MODEL_LAST,
158 };
159
160 /* ALC882 models */
161 enum {
162         ALC882_3ST_DIG,
163         ALC882_6ST_DIG,
164         ALC882_ARIMA,
165         ALC882_W2JC,
166         ALC882_TARGA,
167         ALC882_ASUS_A7J,
168         ALC882_ASUS_A7M,
169         ALC885_MACPRO,
170         ALC885_MBP3,
171         ALC885_IMAC24,
172         ALC882_AUTO,
173         ALC882_MODEL_LAST,
174 };
175
176 /* ALC883 models */
177 enum {
178         ALC883_3ST_2ch_DIG,
179         ALC883_3ST_6ch_DIG,
180         ALC883_3ST_6ch,
181         ALC883_6ST_DIG,
182         ALC883_TARGA_DIG,
183         ALC883_TARGA_2ch_DIG,
184         ALC883_ACER,
185         ALC883_ACER_ASPIRE,
186         ALC883_MEDION,
187         ALC883_MEDION_MD2,      
188         ALC883_LAPTOP_EAPD,
189         ALC883_LENOVO_101E_2ch,
190         ALC883_LENOVO_NB0763,
191         ALC888_LENOVO_MS7195_DIG,
192         ALC883_HAIER_W66,               
193         ALC888_6ST_HP,
194         ALC888_3ST_HP,
195         ALC883_AUTO,
196         ALC883_MODEL_LAST,
197 };
198
199 /* for GPIO Poll */
200 #define GPIO_MASK       0x03
201
202 struct alc_spec {
203         /* codec parameterization */
204         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
205         unsigned int num_mixers;
206
207         const struct hda_verb *init_verbs[5];   /* initialization verbs
208                                                  * don't forget NULL
209                                                  * termination!
210                                                  */
211         unsigned int num_init_verbs;
212
213         char *stream_name_analog;       /* analog PCM stream */
214         struct hda_pcm_stream *stream_analog_playback;
215         struct hda_pcm_stream *stream_analog_capture;
216
217         char *stream_name_digital;      /* digital PCM stream */
218         struct hda_pcm_stream *stream_digital_playback;
219         struct hda_pcm_stream *stream_digital_capture;
220
221         /* playback */
222         struct hda_multi_out multiout;  /* playback set-up
223                                          * max_channels, dacs must be set
224                                          * dig_out_nid and hp_nid are optional
225                                          */
226
227         /* capture */
228         unsigned int num_adc_nids;
229         hda_nid_t *adc_nids;
230         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
231
232         /* capture source */
233         unsigned int num_mux_defs;
234         const struct hda_input_mux *input_mux;
235         unsigned int cur_mux[3];
236
237         /* channel model */
238         const struct hda_channel_mode *channel_mode;
239         int num_channel_mode;
240         int need_dac_fix;
241
242         /* PCM information */
243         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
244
245         /* dynamic controls, init_verbs and input_mux */
246         struct auto_pin_cfg autocfg;
247         unsigned int num_kctl_alloc, num_kctl_used;
248         struct snd_kcontrol_new *kctl_alloc;
249         struct hda_input_mux private_imux;
250         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
251
252         /* hooks */
253         void (*init_hook)(struct hda_codec *codec);
254         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
255
256         /* for pin sensing */
257         unsigned int sense_updated: 1;
258         unsigned int jack_present: 1;
259
260 #ifdef CONFIG_SND_HDA_POWER_SAVE
261         struct hda_loopback_check loopback;
262 #endif
263 };
264
265 /*
266  * configuration template - to be copied to the spec instance
267  */
268 struct alc_config_preset {
269         struct snd_kcontrol_new *mixers[5]; /* should be identical size
270                                              * with spec
271                                              */
272         const struct hda_verb *init_verbs[5];
273         unsigned int num_dacs;
274         hda_nid_t *dac_nids;
275         hda_nid_t dig_out_nid;          /* optional */
276         hda_nid_t hp_nid;               /* optional */
277         unsigned int num_adc_nids;
278         hda_nid_t *adc_nids;
279         hda_nid_t dig_in_nid;
280         unsigned int num_channel_mode;
281         const struct hda_channel_mode *channel_mode;
282         int need_dac_fix;
283         unsigned int num_mux_defs;
284         const struct hda_input_mux *input_mux;
285         void (*unsol_event)(struct hda_codec *, unsigned int);
286         void (*init_hook)(struct hda_codec *);
287 #ifdef CONFIG_SND_HDA_POWER_SAVE
288         struct hda_amp_list *loopbacks;
289 #endif
290 };
291
292
293 /*
294  * input MUX handling
295  */
296 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
297                              struct snd_ctl_elem_info *uinfo)
298 {
299         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
300         struct alc_spec *spec = codec->spec;
301         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
302         if (mux_idx >= spec->num_mux_defs)
303                 mux_idx = 0;
304         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
305 }
306
307 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
308                             struct snd_ctl_elem_value *ucontrol)
309 {
310         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
311         struct alc_spec *spec = codec->spec;
312         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
313
314         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
315         return 0;
316 }
317
318 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
319                             struct snd_ctl_elem_value *ucontrol)
320 {
321         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
322         struct alc_spec *spec = codec->spec;
323         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
324         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
325         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
326                                      spec->adc_nids[adc_idx],
327                                      &spec->cur_mux[adc_idx]);
328 }
329
330
331 /*
332  * channel mode setting
333  */
334 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
335                             struct snd_ctl_elem_info *uinfo)
336 {
337         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
338         struct alc_spec *spec = codec->spec;
339         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
340                                     spec->num_channel_mode);
341 }
342
343 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
344                            struct snd_ctl_elem_value *ucontrol)
345 {
346         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347         struct alc_spec *spec = codec->spec;
348         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
349                                    spec->num_channel_mode,
350                                    spec->multiout.max_channels);
351 }
352
353 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
354                            struct snd_ctl_elem_value *ucontrol)
355 {
356         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
357         struct alc_spec *spec = codec->spec;
358         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
359                                       spec->num_channel_mode,
360                                       &spec->multiout.max_channels);
361         if (err >= 0 && spec->need_dac_fix)
362                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
363         return err;
364 }
365
366 /*
367  * Control the mode of pin widget settings via the mixer.  "pc" is used
368  * instead of "%" to avoid consequences of accidently treating the % as 
369  * being part of a format specifier.  Maximum allowed length of a value is
370  * 63 characters plus NULL terminator.
371  *
372  * Note: some retasking pin complexes seem to ignore requests for input
373  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
374  * are requested.  Therefore order this list so that this behaviour will not
375  * cause problems when mixer clients move through the enum sequentially.
376  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
377  * March 2006.
378  */
379 static char *alc_pin_mode_names[] = {
380         "Mic 50pc bias", "Mic 80pc bias",
381         "Line in", "Line out", "Headphone out",
382 };
383 static unsigned char alc_pin_mode_values[] = {
384         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
385 };
386 /* The control can present all 5 options, or it can limit the options based
387  * in the pin being assumed to be exclusively an input or an output pin.  In
388  * addition, "input" pins may or may not process the mic bias option
389  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
390  * accept requests for bias as of chip versions up to March 2006) and/or
391  * wiring in the computer.
392  */
393 #define ALC_PIN_DIR_IN              0x00
394 #define ALC_PIN_DIR_OUT             0x01
395 #define ALC_PIN_DIR_INOUT           0x02
396 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
397 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
398
399 /* Info about the pin modes supported by the different pin direction modes. 
400  * For each direction the minimum and maximum values are given.
401  */
402 static signed char alc_pin_mode_dir_info[5][2] = {
403         { 0, 2 },    /* ALC_PIN_DIR_IN */
404         { 3, 4 },    /* ALC_PIN_DIR_OUT */
405         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
406         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
407         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
408 };
409 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
410 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
411 #define alc_pin_mode_n_items(_dir) \
412         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
413
414 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
415                              struct snd_ctl_elem_info *uinfo)
416 {
417         unsigned int item_num = uinfo->value.enumerated.item;
418         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
419
420         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
421         uinfo->count = 1;
422         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
423
424         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
425                 item_num = alc_pin_mode_min(dir);
426         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
427         return 0;
428 }
429
430 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
431                             struct snd_ctl_elem_value *ucontrol)
432 {
433         unsigned int i;
434         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
435         hda_nid_t nid = kcontrol->private_value & 0xffff;
436         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
437         long *valp = ucontrol->value.integer.value;
438         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
439                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
440                                                  0x00);
441
442         /* Find enumerated value for current pinctl setting */
443         i = alc_pin_mode_min(dir);
444         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
445                 i++;
446         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
447         return 0;
448 }
449
450 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
451                             struct snd_ctl_elem_value *ucontrol)
452 {
453         signed int change;
454         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
455         hda_nid_t nid = kcontrol->private_value & 0xffff;
456         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
457         long val = *ucontrol->value.integer.value;
458         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
459                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
460                                                  0x00);
461
462         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
463                 val = alc_pin_mode_min(dir);
464
465         change = pinctl != alc_pin_mode_values[val];
466         if (change) {
467                 /* Set pin mode to that requested */
468                 snd_hda_codec_write_cache(codec, nid, 0,
469                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
470                                           alc_pin_mode_values[val]);
471
472                 /* Also enable the retasking pin's input/output as required 
473                  * for the requested pin mode.  Enum values of 2 or less are
474                  * input modes.
475                  *
476                  * Dynamically switching the input/output buffers probably
477                  * reduces noise slightly (particularly on input) so we'll
478                  * do it.  However, having both input and output buffers
479                  * enabled simultaneously doesn't seem to be problematic if
480                  * this turns out to be necessary in the future.
481                  */
482                 if (val <= 2) {
483                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
484                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
485                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
486                                                  HDA_AMP_MUTE, 0);
487                 } else {
488                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
489                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
490                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
491                                                  HDA_AMP_MUTE, 0);
492                 }
493         }
494         return change;
495 }
496
497 #define ALC_PIN_MODE(xname, nid, dir) \
498         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
499           .info = alc_pin_mode_info, \
500           .get = alc_pin_mode_get, \
501           .put = alc_pin_mode_put, \
502           .private_value = nid | (dir<<16) }
503
504 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
505  * together using a mask with more than one bit set.  This control is
506  * currently used only by the ALC260 test model.  At this stage they are not
507  * needed for any "production" models.
508  */
509 #ifdef CONFIG_SND_DEBUG
510 #define alc_gpio_data_info      snd_ctl_boolean_mono_info
511
512 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
513                              struct snd_ctl_elem_value *ucontrol)
514 {
515         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
516         hda_nid_t nid = kcontrol->private_value & 0xffff;
517         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
518         long *valp = ucontrol->value.integer.value;
519         unsigned int val = snd_hda_codec_read(codec, nid, 0,
520                                               AC_VERB_GET_GPIO_DATA, 0x00);
521
522         *valp = (val & mask) != 0;
523         return 0;
524 }
525 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
526                              struct snd_ctl_elem_value *ucontrol)
527 {
528         signed int change;
529         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
530         hda_nid_t nid = kcontrol->private_value & 0xffff;
531         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
532         long val = *ucontrol->value.integer.value;
533         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
534                                                     AC_VERB_GET_GPIO_DATA,
535                                                     0x00);
536
537         /* Set/unset the masked GPIO bit(s) as needed */
538         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
539         if (val == 0)
540                 gpio_data &= ~mask;
541         else
542                 gpio_data |= mask;
543         snd_hda_codec_write_cache(codec, nid, 0,
544                                   AC_VERB_SET_GPIO_DATA, gpio_data);
545
546         return change;
547 }
548 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
549         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
550           .info = alc_gpio_data_info, \
551           .get = alc_gpio_data_get, \
552           .put = alc_gpio_data_put, \
553           .private_value = nid | (mask<<16) }
554 #endif   /* CONFIG_SND_DEBUG */
555
556 /* A switch control to allow the enabling of the digital IO pins on the
557  * ALC260.  This is incredibly simplistic; the intention of this control is
558  * to provide something in the test model allowing digital outputs to be
559  * identified if present.  If models are found which can utilise these
560  * outputs a more complete mixer control can be devised for those models if
561  * necessary.
562  */
563 #ifdef CONFIG_SND_DEBUG
564 #define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
565
566 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
567                               struct snd_ctl_elem_value *ucontrol)
568 {
569         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
570         hda_nid_t nid = kcontrol->private_value & 0xffff;
571         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
572         long *valp = ucontrol->value.integer.value;
573         unsigned int val = snd_hda_codec_read(codec, nid, 0,
574                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
575
576         *valp = (val & mask) != 0;
577         return 0;
578 }
579 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
580                               struct snd_ctl_elem_value *ucontrol)
581 {
582         signed int change;
583         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
584         hda_nid_t nid = kcontrol->private_value & 0xffff;
585         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
586         long val = *ucontrol->value.integer.value;
587         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
588                                                     AC_VERB_GET_DIGI_CONVERT,
589                                                     0x00);
590
591         /* Set/unset the masked control bit(s) as needed */
592         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
593         if (val==0)
594                 ctrl_data &= ~mask;
595         else
596                 ctrl_data |= mask;
597         snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
598                                   ctrl_data);
599
600         return change;
601 }
602 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
603         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
604           .info = alc_spdif_ctrl_info, \
605           .get = alc_spdif_ctrl_get, \
606           .put = alc_spdif_ctrl_put, \
607           .private_value = nid | (mask<<16) }
608 #endif   /* CONFIG_SND_DEBUG */
609
610 /*
611  * set up from the preset table
612  */
613 static void setup_preset(struct alc_spec *spec,
614                          const struct alc_config_preset *preset)
615 {
616         int i;
617
618         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
619                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
620         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
621              i++)
622                 spec->init_verbs[spec->num_init_verbs++] =
623                         preset->init_verbs[i];
624         
625         spec->channel_mode = preset->channel_mode;
626         spec->num_channel_mode = preset->num_channel_mode;
627         spec->need_dac_fix = preset->need_dac_fix;
628
629         spec->multiout.max_channels = spec->channel_mode[0].channels;
630
631         spec->multiout.num_dacs = preset->num_dacs;
632         spec->multiout.dac_nids = preset->dac_nids;
633         spec->multiout.dig_out_nid = preset->dig_out_nid;
634         spec->multiout.hp_nid = preset->hp_nid;
635         
636         spec->num_mux_defs = preset->num_mux_defs;
637         if (!spec->num_mux_defs)
638                 spec->num_mux_defs = 1;
639         spec->input_mux = preset->input_mux;
640
641         spec->num_adc_nids = preset->num_adc_nids;
642         spec->adc_nids = preset->adc_nids;
643         spec->dig_in_nid = preset->dig_in_nid;
644
645         spec->unsol_event = preset->unsol_event;
646         spec->init_hook = preset->init_hook;
647 #ifdef CONFIG_SND_HDA_POWER_SAVE
648         spec->loopback.amplist = preset->loopbacks;
649 #endif
650 }
651
652 /* Enable GPIO mask and set output */
653 static struct hda_verb alc_gpio1_init_verbs[] = {
654         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
655         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
656         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
657         { }
658 };
659
660 static struct hda_verb alc_gpio2_init_verbs[] = {
661         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
662         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
663         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
664         { }
665 };
666
667 static struct hda_verb alc_gpio3_init_verbs[] = {
668         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
669         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
670         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
671         { }
672 };
673
674 static void alc_sku_automute(struct hda_codec *codec)
675 {
676         struct alc_spec *spec = codec->spec;
677         unsigned int mute;
678         unsigned int present;
679         unsigned int hp_nid = spec->autocfg.hp_pins[0];
680         unsigned int sp_nid = spec->autocfg.speaker_pins[0];
681
682         /* need to execute and sync at first */
683         snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
684         present = snd_hda_codec_read(codec, hp_nid, 0,
685                                      AC_VERB_GET_PIN_SENSE, 0);
686         spec->jack_present = (present & 0x80000000) != 0;
687         if (spec->jack_present) {
688                 /* mute internal speaker */
689                 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
690                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
691         } else {
692                 /* unmute internal speaker if necessary */
693                 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
694                 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
695                                          HDA_AMP_MUTE, mute);
696         }
697 }
698
699 /* unsolicited event for HP jack sensing */
700 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
701 {
702         if (codec->vendor_id == 0x10ec0880)
703                 res >>= 28;
704         else
705                 res >>= 26;
706         if (res != ALC880_HP_EVENT)
707                 return;
708
709         alc_sku_automute(codec);
710 }
711
712 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
713  *      31 ~ 16 :       Manufacture ID
714  *      15 ~ 8  :       SKU ID
715  *      7  ~ 0  :       Assembly ID
716  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
717  */
718 static void alc_subsystem_id(struct hda_codec *codec,
719                              unsigned int porta, unsigned int porte,
720                              unsigned int portd)
721 {
722         unsigned int ass, tmp, i;
723         unsigned nid;
724         struct alc_spec *spec = codec->spec;
725
726         ass = codec->subsystem_id & 0xffff;
727         if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
728                 goto do_sku;
729
730         /*      
731          * 31~30        : port conetcivity
732          * 29~21        : reserve
733          * 20           : PCBEEP input
734          * 19~16        : Check sum (15:1)
735          * 15~1         : Custom
736          * 0            : override
737         */
738         nid = 0x1d;
739         if (codec->vendor_id == 0x10ec0260)
740                 nid = 0x17;
741         ass = snd_hda_codec_read(codec, nid, 0,
742                                  AC_VERB_GET_CONFIG_DEFAULT, 0);
743         if (!(ass & 1) && !(ass & 0x100000))
744                 return;
745         if ((ass >> 30) != 1)   /* no physical connection */
746                 return;
747
748         /* check sum */
749         tmp = 0;
750         for (i = 1; i < 16; i++) {
751                 if ((ass >> i) && 1)
752                         tmp++;
753         }
754         if (((ass >> 16) & 0xf) != tmp)
755                 return;
756 do_sku:
757         /*
758          * 0 : override
759          * 1 :  Swap Jack
760          * 2 : 0 --> Desktop, 1 --> Laptop
761          * 3~5 : External Amplifier control
762          * 7~6 : Reserved
763         */
764         tmp = (ass & 0x38) >> 3;        /* external Amp control */
765         switch (tmp) {
766         case 1:
767                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
768                 break;
769         case 3:
770                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
771                 break;
772         case 7:
773                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
774                 break;
775         case 5: /* set EAPD output high */
776                 switch (codec->vendor_id) {
777                 case 0x10ec0260:
778                         snd_hda_codec_write(codec, 0x0f, 0,
779                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
780                         snd_hda_codec_write(codec, 0x10, 0,
781                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
782                         break;
783                 case 0x10ec0262:
784                 case 0x10ec0267:
785                 case 0x10ec0268:
786                 case 0x10ec0269:
787                 case 0x10ec0862:
788                 case 0x10ec0662:        
789                         snd_hda_codec_write(codec, 0x14, 0,
790                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
791                         snd_hda_codec_write(codec, 0x15, 0,
792                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
793                         break;
794                 }
795                 switch (codec->vendor_id) {
796                 case 0x10ec0260:
797                         snd_hda_codec_write(codec, 0x1a, 0,
798                                             AC_VERB_SET_COEF_INDEX, 7);
799                         tmp = snd_hda_codec_read(codec, 0x1a, 0,
800                                                  AC_VERB_GET_PROC_COEF, 0);
801                         snd_hda_codec_write(codec, 0x1a, 0,
802                                             AC_VERB_SET_COEF_INDEX, 7);
803                         snd_hda_codec_write(codec, 0x1a, 0,
804                                             AC_VERB_SET_PROC_COEF,
805                                             tmp | 0x2010);
806                         break;
807                 case 0x10ec0262:
808                 case 0x10ec0880:
809                 case 0x10ec0882:
810                 case 0x10ec0883:
811                 case 0x10ec0885:
812                 case 0x10ec0888:
813                         snd_hda_codec_write(codec, 0x20, 0,
814                                             AC_VERB_SET_COEF_INDEX, 7);
815                         tmp = snd_hda_codec_read(codec, 0x20, 0,
816                                                  AC_VERB_GET_PROC_COEF, 0);
817                         snd_hda_codec_write(codec, 0x20, 0,
818                                             AC_VERB_SET_COEF_INDEX, 7); 
819                         snd_hda_codec_write(codec, 0x20, 0,
820                                             AC_VERB_SET_PROC_COEF,
821                                             tmp | 0x2010);
822                         break;
823                 case 0x10ec0267:
824                 case 0x10ec0268:
825                         snd_hda_codec_write(codec, 0x20, 0,
826                                             AC_VERB_SET_COEF_INDEX, 7);
827                         tmp = snd_hda_codec_read(codec, 0x20, 0,
828                                                  AC_VERB_GET_PROC_COEF, 0);
829                         snd_hda_codec_write(codec, 0x20, 0,
830                                             AC_VERB_SET_COEF_INDEX, 7); 
831                         snd_hda_codec_write(codec, 0x20, 0,
832                                             AC_VERB_SET_PROC_COEF,
833                                             tmp | 0x3000);
834                         break;
835                 }
836         default:
837                 break;
838         }
839         
840         /* is laptop and enable the function "Mute internal speaker
841          * when the external headphone out jack is plugged"
842          */
843         if (!(ass & 0x4) || !(ass & 0x8000))
844                 return;
845         /*
846          * 10~8 : Jack location
847          * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
848          * 14~13: Resvered
849          * 15   : 1 --> enable the function "Mute internal speaker
850          *              when the external headphone out jack is plugged"
851          */
852         if (!spec->autocfg.speaker_pins[0]) {
853                 if (spec->multiout.dac_nids[0])
854                         spec->autocfg.speaker_pins[0] =
855                                 spec->multiout.dac_nids[0];
856                 else
857                         return;
858         }
859
860         if (!spec->autocfg.hp_pins[0]) {
861                 tmp = (ass >> 11) & 0x3;        /* HP to chassis */
862                 if (tmp == 0)
863                         spec->autocfg.hp_pins[0] = porta;
864                 else if (tmp == 1)
865                         spec->autocfg.hp_pins[0] = porte;
866                 else if (tmp == 2)
867                         spec->autocfg.hp_pins[0] = portd;
868                 else
869                         return;
870         }
871
872         snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
873                             AC_VERB_SET_UNSOLICITED_ENABLE,
874                             AC_USRSP_EN | ALC880_HP_EVENT);
875         spec->unsol_event = alc_sku_unsol_event;
876         spec->init_hook = alc_sku_automute;     
877 }
878
879 /*
880  * Fix-up pin default configurations
881  */
882
883 struct alc_pincfg {
884         hda_nid_t nid;
885         u32 val;
886 };
887
888 static void alc_fix_pincfg(struct hda_codec *codec,
889                            const struct snd_pci_quirk *quirk,
890                            const struct alc_pincfg **pinfix)
891 {
892         const struct alc_pincfg *cfg;
893
894         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
895         if (!quirk)
896                 return;
897
898         cfg = pinfix[quirk->value];
899         for (; cfg->nid; cfg++) {
900                 int i;
901                 u32 val = cfg->val;
902                 for (i = 0; i < 4; i++) {
903                         snd_hda_codec_write(codec, cfg->nid, 0,
904                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
905                                     val & 0xff);
906                         val >>= 8;
907                 }
908         }
909 }
910
911 /*
912  * ALC880 3-stack model
913  *
914  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
915  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
916  *                 F-Mic = 0x1b, HP = 0x19
917  */
918
919 static hda_nid_t alc880_dac_nids[4] = {
920         /* front, rear, clfe, rear_surr */
921         0x02, 0x05, 0x04, 0x03
922 };
923
924 static hda_nid_t alc880_adc_nids[3] = {
925         /* ADC0-2 */
926         0x07, 0x08, 0x09,
927 };
928
929 /* The datasheet says the node 0x07 is connected from inputs,
930  * but it shows zero connection in the real implementation on some devices.
931  * Note: this is a 915GAV bug, fixed on 915GLV
932  */
933 static hda_nid_t alc880_adc_nids_alt[2] = {
934         /* ADC1-2 */
935         0x08, 0x09,
936 };
937
938 #define ALC880_DIGOUT_NID       0x06
939 #define ALC880_DIGIN_NID        0x0a
940
941 static struct hda_input_mux alc880_capture_source = {
942         .num_items = 4,
943         .items = {
944                 { "Mic", 0x0 },
945                 { "Front Mic", 0x3 },
946                 { "Line", 0x2 },
947                 { "CD", 0x4 },
948         },
949 };
950
951 /* channel source setting (2/6 channel selection for 3-stack) */
952 /* 2ch mode */
953 static struct hda_verb alc880_threestack_ch2_init[] = {
954         /* set line-in to input, mute it */
955         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
956         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
957         /* set mic-in to input vref 80%, mute it */
958         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
959         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
960         { } /* end */
961 };
962
963 /* 6ch mode */
964 static struct hda_verb alc880_threestack_ch6_init[] = {
965         /* set line-in to output, unmute it */
966         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
967         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
968         /* set mic-in to output, unmute it */
969         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
970         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
971         { } /* end */
972 };
973
974 static struct hda_channel_mode alc880_threestack_modes[2] = {
975         { 2, alc880_threestack_ch2_init },
976         { 6, alc880_threestack_ch6_init },
977 };
978
979 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
980         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
981         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
982         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
983         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
984         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
985         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
986         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
987         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
988         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
989         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
990         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
991         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
992         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
993         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
994         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
995         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
996         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
997         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
998         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
999         {
1000                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1001                 .name = "Channel Mode",
1002                 .info = alc_ch_mode_info,
1003                 .get = alc_ch_mode_get,
1004                 .put = alc_ch_mode_put,
1005         },
1006         { } /* end */
1007 };
1008
1009 /* capture mixer elements */
1010 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1011         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1012         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1013         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1014         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1015         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1016         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1017         {
1018                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1019                 /* The multiple "Capture Source" controls confuse alsamixer
1020                  * So call somewhat different..
1021                  * FIXME: the controls appear in the "playback" view!
1022                  */
1023                 /* .name = "Capture Source", */
1024                 .name = "Input Source",
1025                 .count = 3,
1026                 .info = alc_mux_enum_info,
1027                 .get = alc_mux_enum_get,
1028                 .put = alc_mux_enum_put,
1029         },
1030         { } /* end */
1031 };
1032
1033 /* capture mixer elements (in case NID 0x07 not available) */
1034 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1035         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1036         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1037         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1038         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1039         {
1040                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1041                 /* The multiple "Capture Source" controls confuse alsamixer
1042                  * So call somewhat different..
1043                  * FIXME: the controls appear in the "playback" view!
1044                  */
1045                 /* .name = "Capture Source", */
1046                 .name = "Input Source",
1047                 .count = 2,
1048                 .info = alc_mux_enum_info,
1049                 .get = alc_mux_enum_get,
1050                 .put = alc_mux_enum_put,
1051         },
1052         { } /* end */
1053 };
1054
1055
1056
1057 /*
1058  * ALC880 5-stack model
1059  *
1060  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1061  *      Side = 0x02 (0xd)
1062  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1063  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1064  */
1065
1066 /* additional mixers to alc880_three_stack_mixer */
1067 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1068         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1069         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1070         { } /* end */
1071 };
1072
1073 /* channel source setting (6/8 channel selection for 5-stack) */
1074 /* 6ch mode */
1075 static struct hda_verb alc880_fivestack_ch6_init[] = {
1076         /* set line-in to input, mute it */
1077         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1078         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1079         { } /* end */
1080 };
1081
1082 /* 8ch mode */
1083 static struct hda_verb alc880_fivestack_ch8_init[] = {
1084         /* set line-in to output, unmute it */
1085         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1086         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1087         { } /* end */
1088 };
1089
1090 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1091         { 6, alc880_fivestack_ch6_init },
1092         { 8, alc880_fivestack_ch8_init },
1093 };
1094
1095
1096 /*
1097  * ALC880 6-stack model
1098  *
1099  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1100  *      Side = 0x05 (0x0f)
1101  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1102  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1103  */
1104
1105 static hda_nid_t alc880_6st_dac_nids[4] = {
1106         /* front, rear, clfe, rear_surr */
1107         0x02, 0x03, 0x04, 0x05
1108 };
1109
1110 static struct hda_input_mux alc880_6stack_capture_source = {
1111         .num_items = 4,
1112         .items = {
1113                 { "Mic", 0x0 },
1114                 { "Front Mic", 0x1 },
1115                 { "Line", 0x2 },
1116                 { "CD", 0x4 },
1117         },
1118 };
1119
1120 /* fixed 8-channels */
1121 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1122         { 8, NULL },
1123 };
1124
1125 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1126         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1127         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1128         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1129         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1130         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1131         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1132         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1133         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1134         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1135         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1136         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1137         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1138         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1139         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1140         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1141         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1142         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1143         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1144         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1145         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1146         {
1147                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1148                 .name = "Channel Mode",
1149                 .info = alc_ch_mode_info,
1150                 .get = alc_ch_mode_get,
1151                 .put = alc_ch_mode_put,
1152         },
1153         { } /* end */
1154 };
1155
1156
1157 /*
1158  * ALC880 W810 model
1159  *
1160  * W810 has rear IO for:
1161  * Front (DAC 02)
1162  * Surround (DAC 03)
1163  * Center/LFE (DAC 04)
1164  * Digital out (06)
1165  *
1166  * The system also has a pair of internal speakers, and a headphone jack.
1167  * These are both connected to Line2 on the codec, hence to DAC 02.
1168  * 
1169  * There is a variable resistor to control the speaker or headphone
1170  * volume. This is a hardware-only device without a software API.
1171  *
1172  * Plugging headphones in will disable the internal speakers. This is
1173  * implemented in hardware, not via the driver using jack sense. In
1174  * a similar fashion, plugging into the rear socket marked "front" will
1175  * disable both the speakers and headphones.
1176  *
1177  * For input, there's a microphone jack, and an "audio in" jack.
1178  * These may not do anything useful with this driver yet, because I
1179  * haven't setup any initialization verbs for these yet...
1180  */
1181
1182 static hda_nid_t alc880_w810_dac_nids[3] = {
1183         /* front, rear/surround, clfe */
1184         0x02, 0x03, 0x04
1185 };
1186
1187 /* fixed 6 channels */
1188 static struct hda_channel_mode alc880_w810_modes[1] = {
1189         { 6, NULL }
1190 };
1191
1192 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1193 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1194         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1195         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1196         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1197         HDA_BIND_MUTE("Surround 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_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1203         { } /* end */
1204 };
1205
1206
1207 /*
1208  * Z710V model
1209  *
1210  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1211  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1212  *                 Line = 0x1a
1213  */
1214
1215 static hda_nid_t alc880_z71v_dac_nids[1] = {
1216         0x02
1217 };
1218 #define ALC880_Z71V_HP_DAC      0x03
1219
1220 /* fixed 2 channels */
1221 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1222         { 2, NULL }
1223 };
1224
1225 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1226         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1227         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1228         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1229         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1230         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1231         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1232         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1233         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1234         { } /* end */
1235 };
1236
1237
1238 /* FIXME! */
1239 /*
1240  * ALC880 F1734 model
1241  *
1242  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1243  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1244  */
1245
1246 static hda_nid_t alc880_f1734_dac_nids[1] = {
1247         0x03
1248 };
1249 #define ALC880_F1734_HP_DAC     0x02
1250
1251 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1252         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1253         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1254         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1255         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1256         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1257         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1258         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1259         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1260         { } /* end */
1261 };
1262
1263
1264 /* FIXME! */
1265 /*
1266  * ALC880 ASUS model
1267  *
1268  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1269  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1270  *  Mic = 0x18, Line = 0x1a
1271  */
1272
1273 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1274 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1275
1276 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1277         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1278         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1279         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1280         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1281         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1282         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1283         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1284         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1285         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1286         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1287         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1288         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1289         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1290         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1291         {
1292                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1293                 .name = "Channel Mode",
1294                 .info = alc_ch_mode_info,
1295                 .get = alc_ch_mode_get,
1296                 .put = alc_ch_mode_put,
1297         },
1298         { } /* end */
1299 };
1300
1301 /* FIXME! */
1302 /*
1303  * ALC880 ASUS W1V model
1304  *
1305  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1306  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1307  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1308  */
1309
1310 /* additional mixers to alc880_asus_mixer */
1311 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1312         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1313         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1314         { } /* end */
1315 };
1316
1317 /* additional mixers to alc880_asus_mixer */
1318 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1319         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1320         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1321         { } /* end */
1322 };
1323
1324 /* TCL S700 */
1325 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1326         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1327         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1328         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1329         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1330         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1331         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1332         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1333         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1334         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1335         {
1336                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1337                 /* The multiple "Capture Source" controls confuse alsamixer
1338                  * So call somewhat different..
1339                  * FIXME: the controls appear in the "playback" view!
1340                  */
1341                 /* .name = "Capture Source", */
1342                 .name = "Input Source",
1343                 .count = 1,
1344                 .info = alc_mux_enum_info,
1345                 .get = alc_mux_enum_get,
1346                 .put = alc_mux_enum_put,
1347         },
1348         { } /* end */
1349 };
1350
1351 /* Uniwill */
1352 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1353         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1354         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1355         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1356         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1357         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1358         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1359         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1360         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1361         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1362         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1363         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1364         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1365         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1366         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1367         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1368         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1369         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1370         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1371         {
1372                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1373                 .name = "Channel Mode",
1374                 .info = alc_ch_mode_info,
1375                 .get = alc_ch_mode_get,
1376                 .put = alc_ch_mode_put,
1377         },
1378         { } /* end */
1379 };
1380
1381 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1382         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1383         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1384         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1385         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1386         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1387         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1388         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1389         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1390         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1391         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1392         { } /* end */
1393 };
1394
1395 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1396         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1397         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1398         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1399         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1400         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1401         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1402         { } /* end */
1403 };
1404
1405 /*
1406  * build control elements
1407  */
1408 static int alc_build_controls(struct hda_codec *codec)
1409 {
1410         struct alc_spec *spec = codec->spec;
1411         int err;
1412         int i;
1413
1414         for (i = 0; i < spec->num_mixers; i++) {
1415                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1416                 if (err < 0)
1417                         return err;
1418         }
1419
1420         if (spec->multiout.dig_out_nid) {
1421                 err = snd_hda_create_spdif_out_ctls(codec,
1422                                                     spec->multiout.dig_out_nid);
1423                 if (err < 0)
1424                         return err;
1425         }
1426         if (spec->dig_in_nid) {
1427                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1428                 if (err < 0)
1429                         return err;
1430         }
1431         return 0;
1432 }
1433
1434
1435 /*
1436  * initialize the codec volumes, etc
1437  */
1438
1439 /*
1440  * generic initialization of ADC, input mixers and output mixers
1441  */
1442 static struct hda_verb alc880_volume_init_verbs[] = {
1443         /*
1444          * Unmute ADC0-2 and set the default input to mic-in
1445          */
1446         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1447         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1448         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1449         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1450         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1451         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1452
1453         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1454          * mixer widget
1455          * Note: PASD motherboards uses the Line In 2 as the input for front
1456          * panel mic (mic 2)
1457          */
1458         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1459         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1460         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1461         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1462         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1463         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1464         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1465         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1466
1467         /*
1468          * Set up output mixers (0x0c - 0x0f)
1469          */
1470         /* set vol=0 to output mixers */
1471         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1472         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1473         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1474         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1475         /* set up input amps for analog loopback */
1476         /* Amp Indices: DAC = 0, mixer = 1 */
1477         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1478         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1479         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1480         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1481         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1482         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1483         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1484         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1485
1486         { }
1487 };
1488
1489 /*
1490  * 3-stack pin configuration:
1491  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1492  */
1493 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1494         /*
1495          * preset connection lists of input pins
1496          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1497          */
1498         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1499         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1500         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1501
1502         /*
1503          * Set pin mode and muting
1504          */
1505         /* set front pin widgets 0x14 for output */
1506         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1507         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1508         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1509         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1510         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1511         /* Mic2 (as headphone out) for HP output */
1512         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1513         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1514         /* Line In pin widget for input */
1515         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1516         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1517         /* Line2 (as front mic) pin widget for input and vref at 80% */
1518         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1519         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1520         /* CD pin widget for input */
1521         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1522
1523         { }
1524 };
1525
1526 /*
1527  * 5-stack pin configuration:
1528  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1529  * line-in/side = 0x1a, f-mic = 0x1b
1530  */
1531 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1532         /*
1533          * preset connection lists of input pins
1534          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1535          */
1536         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1537         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1538
1539         /*
1540          * Set pin mode and muting
1541          */
1542         /* set pin widgets 0x14-0x17 for output */
1543         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1544         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1545         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1546         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1547         /* unmute pins for output (no gain on this amp) */
1548         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1549         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1550         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1551         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1552
1553         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1554         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1555         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1556         /* Mic2 (as headphone out) for HP output */
1557         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1558         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1559         /* Line In pin widget for input */
1560         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1561         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1562         /* Line2 (as front mic) pin widget for input and vref at 80% */
1563         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1564         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1565         /* CD pin widget for input */
1566         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1567
1568         { }
1569 };
1570
1571 /*
1572  * W810 pin configuration:
1573  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1574  */
1575 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1576         /* hphone/speaker input selector: front DAC */
1577         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1578
1579         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1580         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1581         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1582         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1583         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1584         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1585
1586         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1587         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1588
1589         { }
1590 };
1591
1592 /*
1593  * Z71V pin configuration:
1594  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1595  */
1596 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1597         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1598         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1599         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1600         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1601
1602         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1603         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1604         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1605         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1606
1607         { }
1608 };
1609
1610 /*
1611  * 6-stack pin configuration:
1612  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1613  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1614  */
1615 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1616         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1617
1618         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1619         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1620         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1621         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1622         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1623         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1624         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1625         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1626
1627         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1628         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1629         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1630         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1631         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1632         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1633         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1634         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1635         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1636         
1637         { }
1638 };
1639
1640 /*
1641  * Uniwill pin configuration:
1642  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1643  * line = 0x1a
1644  */
1645 static struct hda_verb alc880_uniwill_init_verbs[] = {
1646         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1647
1648         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1649         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1650         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1651         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1652         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1653         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1654         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1655         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1656         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1657         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1658         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1659         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1660         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1661         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1662
1663         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1664         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1665         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1666         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1667         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1668         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1669         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1670         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1671         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1672
1673         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1674         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1675
1676         { }
1677 };
1678
1679 /*
1680 * Uniwill P53
1681 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1682  */
1683 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1684         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1685
1686         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1687         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1688         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1689         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1691         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1692         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1693         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1694         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1695         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1696         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1697         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1698
1699         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1700         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1701         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1702         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1703         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1704         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1705
1706         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1707         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1708
1709         { }
1710 };
1711
1712 static struct hda_verb alc880_beep_init_verbs[] = {
1713         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1714         { }
1715 };
1716
1717 /* toggle speaker-output according to the hp-jack state */
1718 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1719 {
1720         unsigned int present;
1721         unsigned char bits;
1722
1723         present = snd_hda_codec_read(codec, 0x14, 0,
1724                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1725         bits = present ? HDA_AMP_MUTE : 0;
1726         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1727                                  HDA_AMP_MUTE, bits);
1728         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1729                                  HDA_AMP_MUTE, bits);
1730 }
1731
1732 /* auto-toggle front mic */
1733 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1734 {
1735         unsigned int present;
1736         unsigned char bits;
1737
1738         present = snd_hda_codec_read(codec, 0x18, 0,
1739                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1740         bits = present ? HDA_AMP_MUTE : 0;
1741         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1742 }
1743
1744 static void alc880_uniwill_automute(struct hda_codec *codec)
1745 {
1746         alc880_uniwill_hp_automute(codec);
1747         alc880_uniwill_mic_automute(codec);
1748 }
1749
1750 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1751                                        unsigned int res)
1752 {
1753         /* Looks like the unsol event is incompatible with the standard
1754          * definition.  4bit tag is placed at 28 bit!
1755          */
1756         switch (res >> 28) {
1757         case ALC880_HP_EVENT:
1758                 alc880_uniwill_hp_automute(codec);
1759                 break;
1760         case ALC880_MIC_EVENT:
1761                 alc880_uniwill_mic_automute(codec);
1762                 break;
1763         }
1764 }
1765
1766 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1767 {
1768         unsigned int present;
1769         unsigned char bits;
1770
1771         present = snd_hda_codec_read(codec, 0x14, 0,
1772                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1773         bits = present ? HDA_AMP_MUTE : 0;
1774         snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1775 }
1776
1777 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1778 {
1779         unsigned int present;
1780         
1781         present = snd_hda_codec_read(codec, 0x21, 0,
1782                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1783         present &= HDA_AMP_VOLMASK;
1784         snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1785                                  HDA_AMP_VOLMASK, present);
1786         snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1787                                  HDA_AMP_VOLMASK, present);
1788 }
1789
1790 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1791                                            unsigned int res)
1792 {
1793         /* Looks like the unsol event is incompatible with the standard
1794          * definition.  4bit tag is placed at 28 bit!
1795          */
1796         if ((res >> 28) == ALC880_HP_EVENT)
1797                 alc880_uniwill_p53_hp_automute(codec);
1798         if ((res >> 28) == ALC880_DCVOL_EVENT)
1799                 alc880_uniwill_p53_dcvol_automute(codec);
1800 }
1801
1802 /* FIXME! */
1803 /*
1804  * F1734 pin configuration:
1805  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1806  */
1807 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1808         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1809         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1810         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1811         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1812
1813         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1814         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1815         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1816         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1817
1818         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1819         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1820         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1821         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1822         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1823         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1825         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1826         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1827
1828         { }
1829 };
1830
1831 /* FIXME! */
1832 /*
1833  * ASUS pin configuration:
1834  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1835  */
1836 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1837         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1838         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1839         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1840         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1841
1842         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1843         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1844         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1845         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1846         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1847         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1848         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1849         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1850
1851         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1852         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1853         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1854         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1855         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1856         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1857         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1858         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1860         
1861         { }
1862 };
1863
1864 /* Enable GPIO mask and set output */
1865 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1866 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1867
1868 /* Clevo m520g init */
1869 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1870         /* headphone output */
1871         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1872         /* line-out */
1873         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1874         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1875         /* Line-in */
1876         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1877         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1878         /* CD */
1879         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1880         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1881         /* Mic1 (rear panel) */
1882         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1883         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1884         /* Mic2 (front panel) */
1885         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1886         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1887         /* headphone */
1888         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1889         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1890         /* change to EAPD mode */
1891         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1892         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1893
1894         { }
1895 };
1896
1897 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1898         /* change to EAPD mode */
1899         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1900         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1901
1902         /* Headphone output */
1903         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1904         /* Front output*/
1905         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1906         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1907
1908         /* Line In pin widget for input */
1909         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1910         /* CD pin widget for input */
1911         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1912         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1913         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1914
1915         /* change to EAPD mode */
1916         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1917         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1918
1919         { }
1920 };
1921
1922 /*
1923  * LG m1 express dual
1924  *
1925  * Pin assignment:
1926  *   Rear Line-In/Out (blue): 0x14
1927  *   Build-in Mic-In: 0x15
1928  *   Speaker-out: 0x17
1929  *   HP-Out (green): 0x1b
1930  *   Mic-In/Out (red): 0x19
1931  *   SPDIF-Out: 0x1e
1932  */
1933
1934 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1935 static hda_nid_t alc880_lg_dac_nids[3] = {
1936         0x05, 0x02, 0x03
1937 };
1938
1939 /* seems analog CD is not working */
1940 static struct hda_input_mux alc880_lg_capture_source = {
1941         .num_items = 3,
1942         .items = {
1943                 { "Mic", 0x1 },
1944                 { "Line", 0x5 },
1945                 { "Internal Mic", 0x6 },
1946         },
1947 };
1948
1949 /* 2,4,6 channel modes */
1950 static struct hda_verb alc880_lg_ch2_init[] = {
1951         /* set line-in and mic-in to input */
1952         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1953         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1954         { }
1955 };
1956
1957 static struct hda_verb alc880_lg_ch4_init[] = {
1958         /* set line-in to out and mic-in to input */
1959         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1960         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1961         { }
1962 };
1963
1964 static struct hda_verb alc880_lg_ch6_init[] = {
1965         /* set line-in and mic-in to output */
1966         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1967         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1968         { }
1969 };
1970
1971 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1972         { 2, alc880_lg_ch2_init },
1973         { 4, alc880_lg_ch4_init },
1974         { 6, alc880_lg_ch6_init },
1975 };
1976
1977 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1978         /* FIXME: it's not really "master" but front channels */
1979         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1980         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1981         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1982         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1983         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1984         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1985         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1986         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1987         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1988         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1989         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1990         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1991         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1992         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1993         {
1994                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1995                 .name = "Channel Mode",
1996                 .info = alc_ch_mode_info,
1997                 .get = alc_ch_mode_get,
1998                 .put = alc_ch_mode_put,
1999         },
2000         { } /* end */
2001 };
2002
2003 static struct hda_verb alc880_lg_init_verbs[] = {
2004         /* set capture source to mic-in */
2005         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2006         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2007         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2008         /* mute all amp mixer inputs */
2009         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2010         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2011         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2012         /* line-in to input */
2013         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2014         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2015         /* built-in mic */
2016         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2017         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2018         /* speaker-out */
2019         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2020         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2021         /* mic-in to input */
2022         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2023         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2024         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2025         /* HP-out */
2026         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2027         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2028         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2029         /* jack sense */
2030         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2031         { }
2032 };
2033
2034 /* toggle speaker-output according to the hp-jack state */
2035 static void alc880_lg_automute(struct hda_codec *codec)
2036 {
2037         unsigned int present;
2038         unsigned char bits;
2039
2040         present = snd_hda_codec_read(codec, 0x1b, 0,
2041                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2042         bits = present ? HDA_AMP_MUTE : 0;
2043         snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2044                                  HDA_AMP_MUTE, bits);
2045 }
2046
2047 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2048 {
2049         /* Looks like the unsol event is incompatible with the standard
2050          * definition.  4bit tag is placed at 28 bit!
2051          */
2052         if ((res >> 28) == 0x01)
2053                 alc880_lg_automute(codec);
2054 }
2055
2056 /*
2057  * LG LW20
2058  *
2059  * Pin assignment:
2060  *   Speaker-out: 0x14
2061  *   Mic-In: 0x18
2062  *   Built-in Mic-In: 0x19
2063  *   Line-In: 0x1b
2064  *   HP-Out: 0x1a
2065  *   SPDIF-Out: 0x1e
2066  */
2067
2068 static struct hda_input_mux alc880_lg_lw_capture_source = {
2069         .num_items = 3,
2070         .items = {
2071                 { "Mic", 0x0 },
2072                 { "Internal Mic", 0x1 },
2073                 { "Line In", 0x2 },
2074         },
2075 };
2076
2077 #define alc880_lg_lw_modes alc880_threestack_modes
2078
2079 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2080         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2081         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2082         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2083         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2084         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2085         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2086         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2087         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2088         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2089         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2090         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2091         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2092         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2093         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2094         {
2095                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2096                 .name = "Channel Mode",
2097                 .info = alc_ch_mode_info,
2098                 .get = alc_ch_mode_get,
2099                 .put = alc_ch_mode_put,
2100         },
2101         { } /* end */
2102 };
2103
2104 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2105         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2106         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2107         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2108
2109         /* set capture source to mic-in */
2110         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2111         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2112         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2113         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2114         /* speaker-out */
2115         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2116         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2117         /* HP-out */
2118         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2119         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2120         /* mic-in to input */
2121         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2122         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2123         /* built-in mic */
2124         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2125         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2126         /* jack sense */
2127         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2128         { }
2129 };
2130
2131 /* toggle speaker-output according to the hp-jack state */
2132 static void alc880_lg_lw_automute(struct hda_codec *codec)
2133 {
2134         unsigned int present;
2135         unsigned char bits;
2136
2137         present = snd_hda_codec_read(codec, 0x1b, 0,
2138                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2139         bits = present ? HDA_AMP_MUTE : 0;
2140         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2141                                  HDA_AMP_MUTE, bits);
2142 }
2143
2144 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2145 {
2146         /* Looks like the unsol event is incompatible with the standard
2147          * definition.  4bit tag is placed at 28 bit!
2148          */
2149         if ((res >> 28) == 0x01)
2150                 alc880_lg_lw_automute(codec);
2151 }
2152
2153 #ifdef CONFIG_SND_HDA_POWER_SAVE
2154 static struct hda_amp_list alc880_loopbacks[] = {
2155         { 0x0b, HDA_INPUT, 0 },
2156         { 0x0b, HDA_INPUT, 1 },
2157         { 0x0b, HDA_INPUT, 2 },
2158         { 0x0b, HDA_INPUT, 3 },
2159         { 0x0b, HDA_INPUT, 4 },
2160         { } /* end */
2161 };
2162
2163 static struct hda_amp_list alc880_lg_loopbacks[] = {
2164         { 0x0b, HDA_INPUT, 1 },
2165         { 0x0b, HDA_INPUT, 6 },
2166         { 0x0b, HDA_INPUT, 7 },
2167         { } /* end */
2168 };
2169 #endif
2170
2171 /*
2172  * Common callbacks
2173  */
2174
2175 static int alc_init(struct hda_codec *codec)
2176 {
2177         struct alc_spec *spec = codec->spec;
2178         unsigned int i;
2179
2180         for (i = 0; i < spec->num_init_verbs; i++)
2181                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2182
2183         if (spec->init_hook)
2184                 spec->init_hook(codec);
2185
2186         return 0;
2187 }
2188
2189 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2190 {
2191         struct alc_spec *spec = codec->spec;
2192
2193         if (spec->unsol_event)
2194                 spec->unsol_event(codec, res);
2195 }
2196
2197 #ifdef CONFIG_SND_HDA_POWER_SAVE
2198 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2199 {
2200         struct alc_spec *spec = codec->spec;
2201         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2202 }
2203 #endif
2204
2205 /*
2206  * Analog playback callbacks
2207  */
2208 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2209                                     struct hda_codec *codec,
2210                                     struct snd_pcm_substream *substream)
2211 {
2212         struct alc_spec *spec = codec->spec;
2213         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2214 }
2215
2216 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2217                                        struct hda_codec *codec,
2218                                        unsigned int stream_tag,
2219                                        unsigned int format,
2220                                        struct snd_pcm_substream *substream)
2221 {
2222         struct alc_spec *spec = codec->spec;
2223         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2224                                                 stream_tag, format, substream);
2225 }
2226
2227 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2228                                        struct hda_codec *codec,
2229                                        struct snd_pcm_substream *substream)
2230 {
2231         struct alc_spec *spec = codec->spec;
2232         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2233 }
2234
2235 /*
2236  * Digital out
2237  */
2238 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2239                                         struct hda_codec *codec,
2240                                         struct snd_pcm_substream *substream)
2241 {
2242         struct alc_spec *spec = codec->spec;
2243         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2244 }
2245
2246 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2247                                            struct hda_codec *codec,
2248                                            unsigned int stream_tag,
2249                                            unsigned int format,
2250                                            struct snd_pcm_substream *substream)
2251 {
2252         struct alc_spec *spec = codec->spec;
2253         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2254                                              stream_tag, format, substream);
2255 }
2256
2257 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2258                                          struct hda_codec *codec,
2259                                          struct snd_pcm_substream *substream)
2260 {
2261         struct alc_spec *spec = codec->spec;
2262         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2263 }
2264
2265 /*
2266  * Analog capture
2267  */
2268 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2269                                       struct hda_codec *codec,
2270                                       unsigned int stream_tag,
2271                                       unsigned int format,
2272                                       struct snd_pcm_substream *substream)
2273 {
2274         struct alc_spec *spec = codec->spec;
2275
2276         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2277                                    stream_tag, 0, format);
2278         return 0;
2279 }
2280
2281 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2282                                       struct hda_codec *codec,
2283                                       struct snd_pcm_substream *substream)
2284 {
2285         struct alc_spec *spec = codec->spec;
2286
2287         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2288                                    0, 0, 0);
2289         return 0;
2290 }
2291
2292
2293 /*
2294  */
2295 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2296         .substreams = 1,
2297         .channels_min = 2,
2298         .channels_max = 8,
2299         /* NID is set in alc_build_pcms */
2300         .ops = {
2301                 .open = alc880_playback_pcm_open,
2302                 .prepare = alc880_playback_pcm_prepare,
2303                 .cleanup = alc880_playback_pcm_cleanup
2304         },
2305 };
2306
2307 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2308         .substreams = 2,
2309         .channels_min = 2,
2310         .channels_max = 2,
2311         /* NID is set in alc_build_pcms */
2312         .ops = {
2313                 .prepare = alc880_capture_pcm_prepare,
2314                 .cleanup = alc880_capture_pcm_cleanup
2315         },
2316 };
2317
2318 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2319         .substreams = 1,
2320         .channels_min = 2,
2321         .channels_max = 2,
2322         /* NID is set in alc_build_pcms */
2323         .ops = {
2324                 .open = alc880_dig_playback_pcm_open,
2325                 .close = alc880_dig_playback_pcm_close,
2326                 .prepare = alc880_dig_playback_pcm_prepare
2327         },
2328 };
2329
2330 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2331         .substreams = 1,
2332         .channels_min = 2,
2333         .channels_max = 2,
2334         /* NID is set in alc_build_pcms */
2335 };
2336
2337 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2338 static struct hda_pcm_stream alc_pcm_null_playback = {
2339         .substreams = 0,
2340         .channels_min = 0,
2341         .channels_max = 0,
2342 };
2343
2344 static int alc_build_pcms(struct hda_codec *codec)
2345 {
2346         struct alc_spec *spec = codec->spec;
2347         struct hda_pcm *info = spec->pcm_rec;
2348         int i;
2349
2350         codec->num_pcms = 1;
2351         codec->pcm_info = info;
2352
2353         info->name = spec->stream_name_analog;
2354         if (spec->stream_analog_playback) {
2355                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2356                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2357                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2358         }
2359         if (spec->stream_analog_capture) {
2360                 snd_assert(spec->adc_nids, return -EINVAL);
2361                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2362                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2363         }
2364
2365         if (spec->channel_mode) {
2366                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2367                 for (i = 0; i < spec->num_channel_mode; i++) {
2368                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2369                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2370                         }
2371                 }
2372         }
2373
2374         /* SPDIF for stream index #1 */
2375         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2376                 codec->num_pcms = 2;
2377                 info = spec->pcm_rec + 1;
2378                 info->name = spec->stream_name_digital;
2379                 if (spec->multiout.dig_out_nid &&
2380                     spec->stream_digital_playback) {
2381                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2382                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2383                 }
2384                 if (spec->dig_in_nid &&
2385                     spec->stream_digital_capture) {
2386                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2387                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2388                 }
2389         }
2390
2391         /* If the use of more than one ADC is requested for the current
2392          * model, configure a second analog capture-only PCM.
2393          */
2394         /* Additional Analaog capture for index #2 */
2395         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2396             spec->adc_nids) {
2397                 codec->num_pcms = 3;
2398                 info = spec->pcm_rec + 2;
2399                 info->name = spec->stream_name_analog;
2400                 /* No playback stream for second PCM */
2401                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2402                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2403                 if (spec->stream_analog_capture) {
2404                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2405                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2406                 }
2407         }
2408
2409         return 0;
2410 }
2411
2412 static void alc_free(struct hda_codec *codec)
2413 {
2414         struct alc_spec *spec = codec->spec;
2415         unsigned int i;
2416
2417         if (!spec)
2418                 return;
2419
2420         if (spec->kctl_alloc) {
2421                 for (i = 0; i < spec->num_kctl_used; i++)
2422                         kfree(spec->kctl_alloc[i].name);
2423                 kfree(spec->kctl_alloc);
2424         }
2425         kfree(spec);
2426 }
2427
2428 /*
2429  */
2430 static struct hda_codec_ops alc_patch_ops = {
2431         .build_controls = alc_build_controls,
2432         .build_pcms = alc_build_pcms,
2433         .init = alc_init,
2434         .free = alc_free,
2435         .unsol_event = alc_unsol_event,
2436 #ifdef CONFIG_SND_HDA_POWER_SAVE
2437         .check_power_status = alc_check_power_status,
2438 #endif
2439 };
2440
2441
2442 /*
2443  * Test configuration for debugging
2444  *
2445  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2446  * enum controls.
2447  */
2448 #ifdef CONFIG_SND_DEBUG
2449 static hda_nid_t alc880_test_dac_nids[4] = {
2450         0x02, 0x03, 0x04, 0x05
2451 };
2452
2453 static struct hda_input_mux alc880_test_capture_source = {
2454         .num_items = 7,
2455         .items = {
2456                 { "In-1", 0x0 },
2457                 { "In-2", 0x1 },
2458                 { "In-3", 0x2 },
2459                 { "In-4", 0x3 },
2460                 { "CD", 0x4 },
2461                 { "Front", 0x5 },
2462                 { "Surround", 0x6 },
2463         },
2464 };
2465
2466 static struct hda_channel_mode alc880_test_modes[4] = {
2467         { 2, NULL },
2468         { 4, NULL },
2469         { 6, NULL },
2470         { 8, NULL },
2471 };
2472
2473 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2474                                  struct snd_ctl_elem_info *uinfo)
2475 {
2476         static char *texts[] = {
2477                 "N/A", "Line Out", "HP Out",
2478                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2479         };
2480         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2481         uinfo->count = 1;
2482         uinfo->value.enumerated.items = 8;
2483         if (uinfo->value.enumerated.item >= 8)
2484                 uinfo->value.enumerated.item = 7;
2485         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2486         return 0;
2487 }
2488
2489 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2490                                 struct snd_ctl_elem_value *ucontrol)
2491 {
2492         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2493         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2494         unsigned int pin_ctl, item = 0;
2495
2496         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2497                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2498         if (pin_ctl & AC_PINCTL_OUT_EN) {
2499                 if (pin_ctl & AC_PINCTL_HP_EN)
2500                         item = 2;
2501                 else
2502                         item = 1;
2503         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2504                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2505                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2506                 case AC_PINCTL_VREF_50:  item = 4; break;
2507                 case AC_PINCTL_VREF_GRD: item = 5; break;
2508                 case AC_PINCTL_VREF_80:  item = 6; break;
2509                 case AC_PINCTL_VREF_100: item = 7; break;
2510                 }
2511         }
2512         ucontrol->value.enumerated.item[0] = item;
2513         return 0;
2514 }
2515
2516 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2517                                 struct snd_ctl_elem_value *ucontrol)
2518 {
2519         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2520         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2521         static unsigned int ctls[] = {
2522                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2523                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2524                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2525                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2526                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2527                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2528         };
2529         unsigned int old_ctl, new_ctl;
2530
2531         old_ctl = snd_hda_codec_read(codec, nid, 0,
2532                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2533         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2534         if (old_ctl != new_ctl) {
2535                 int val;
2536                 snd_hda_codec_write_cache(codec, nid, 0,
2537                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
2538                                           new_ctl);
2539                 val = ucontrol->value.enumerated.item[0] >= 3 ?
2540                         HDA_AMP_MUTE : 0;
2541                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2542                                          HDA_AMP_MUTE, val);
2543                 return 1;
2544         }
2545         return 0;
2546 }
2547
2548 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2549                                  struct snd_ctl_elem_info *uinfo)
2550 {
2551         static char *texts[] = {
2552                 "Front", "Surround", "CLFE", "Side"
2553         };
2554         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2555         uinfo->count = 1;
2556         uinfo->value.enumerated.items = 4;
2557         if (uinfo->value.enumerated.item >= 4)
2558                 uinfo->value.enumerated.item = 3;
2559         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2560         return 0;
2561 }
2562
2563 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2564                                 struct snd_ctl_elem_value *ucontrol)
2565 {
2566         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2567         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2568         unsigned int sel;
2569
2570         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2571         ucontrol->value.enumerated.item[0] = sel & 3;
2572         return 0;
2573 }
2574
2575 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2576                                 struct snd_ctl_elem_value *ucontrol)
2577 {
2578         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2579         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2580         unsigned int sel;
2581
2582         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2583         if (ucontrol->value.enumerated.item[0] != sel) {
2584                 sel = ucontrol->value.enumerated.item[0] & 3;
2585                 snd_hda_codec_write_cache(codec, nid, 0,
2586                                           AC_VERB_SET_CONNECT_SEL, sel);
2587                 return 1;
2588         }
2589         return 0;
2590 }
2591
2592 #define PIN_CTL_TEST(xname,nid) {                       \
2593                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2594                         .name = xname,                 \
2595                         .info = alc_test_pin_ctl_info, \
2596                         .get = alc_test_pin_ctl_get,   \
2597                         .put = alc_test_pin_ctl_put,   \
2598                         .private_value = nid           \
2599                         }
2600
2601 #define PIN_SRC_TEST(xname,nid) {                       \
2602                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2603                         .name = xname,                 \
2604                         .info = alc_test_pin_src_info, \
2605                         .get = alc_test_pin_src_get,   \
2606                         .put = alc_test_pin_src_put,   \
2607                         .private_value = nid           \
2608                         }
2609
2610 static struct snd_kcontrol_new alc880_test_mixer[] = {
2611         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2612         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2613         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2614         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2615         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2616         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2617         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2618         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2619         PIN_CTL_TEST("Front Pin Mode", 0x14),
2620         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2621         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2622         PIN_CTL_TEST("Side Pin Mode", 0x17),
2623         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2624         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2625         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2626         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2627         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2628         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2629         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2630         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2631         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2632         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2633         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2634         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2635         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2636         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2637         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2638         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2639         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2640         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2641         {
2642                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2643                 .name = "Channel Mode",
2644                 .info = alc_ch_mode_info,
2645                 .get = alc_ch_mode_get,
2646                 .put = alc_ch_mode_put,
2647         },
2648         { } /* end */
2649 };
2650
2651 static struct hda_verb alc880_test_init_verbs[] = {
2652         /* Unmute inputs of 0x0c - 0x0f */
2653         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2654         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2655         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2656         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2657         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2658         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2659         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2660         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2661         /* Vol output for 0x0c-0x0f */
2662         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2663         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2664         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2665         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2666         /* Set output pins 0x14-0x17 */
2667         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2668         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2669         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2670         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2671         /* Unmute output pins 0x14-0x17 */
2672         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2673         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2674         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2675         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2676         /* Set input pins 0x18-0x1c */
2677         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2678         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2679         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2680         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2681         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2682         /* Mute input pins 0x18-0x1b */
2683         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2684         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2685         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2686         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2687         /* ADC set up */
2688         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2689         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2690         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2691         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2692         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2693         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2694         /* Analog input/passthru */
2695         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2696         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2697         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2698         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2699         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2700         { }
2701 };
2702 #endif
2703
2704 /*
2705  */
2706
2707 static const char *alc880_models[ALC880_MODEL_LAST] = {
2708         [ALC880_3ST]            = "3stack",
2709         [ALC880_TCL_S700]       = "tcl",
2710         [ALC880_3ST_DIG]        = "3stack-digout",
2711         [ALC880_CLEVO]          = "clevo",
2712         [ALC880_5ST]            = "5stack",
2713         [ALC880_5ST_DIG]        = "5stack-digout",
2714         [ALC880_W810]           = "w810",
2715         [ALC880_Z71V]           = "z71v",
2716         [ALC880_6ST]            = "6stack",
2717         [ALC880_6ST_DIG]        = "6stack-digout",
2718         [ALC880_ASUS]           = "asus",
2719         [ALC880_ASUS_W1V]       = "asus-w1v",
2720         [ALC880_ASUS_DIG]       = "asus-dig",
2721         [ALC880_ASUS_DIG2]      = "asus-dig2",
2722         [ALC880_UNIWILL_DIG]    = "uniwill",
2723         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2724         [ALC880_FUJITSU]        = "fujitsu",
2725         [ALC880_F1734]          = "F1734",
2726         [ALC880_LG]             = "lg",
2727         [ALC880_LG_LW]          = "lg-lw",
2728 #ifdef CONFIG_SND_DEBUG
2729         [ALC880_TEST]           = "test",
2730 #endif
2731         [ALC880_AUTO]           = "auto",
2732 };
2733
2734 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2735         /* Broken BIOS configuration */
2736         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2737         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2738
2739         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2740         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2741         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2742         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2743         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2744         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2745         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2746         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2747         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2748
2749         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2750         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2751
2752         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2753         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2754         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2755         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2756         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2757         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2758         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2759         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2760         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2761         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2762         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2763         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2764         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2765         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2766         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2767
2768         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2769         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2770         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2771         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2772         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2773         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2774         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2775         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2776         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2777         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2778         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2779         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2780         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2781         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2782         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2783         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2784         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2785         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2786
2787         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2788         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2789         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2790         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2791
2792         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2793         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2794         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2795         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2796
2797         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2798         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2799         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2800         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2801
2802         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2803         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2804         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2805         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2806         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2807         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2808         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2809         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2810         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2811         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2812         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2813
2814         {}
2815 };
2816
2817 /*
2818  * ALC880 codec presets
2819  */
2820 static struct alc_config_preset alc880_presets[] = {
2821         [ALC880_3ST] = {
2822                 .mixers = { alc880_three_stack_mixer },
2823                 .init_verbs = { alc880_volume_init_verbs,
2824                                 alc880_pin_3stack_init_verbs },
2825                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2826                 .dac_nids = alc880_dac_nids,
2827                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2828                 .channel_mode = alc880_threestack_modes,
2829                 .need_dac_fix = 1,
2830                 .input_mux = &alc880_capture_source,
2831         },
2832         [ALC880_3ST_DIG] = {
2833                 .mixers = { alc880_three_stack_mixer },
2834                 .init_verbs = { alc880_volume_init_verbs,
2835                                 alc880_pin_3stack_init_verbs },
2836                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2837                 .dac_nids = alc880_dac_nids,
2838                 .dig_out_nid = ALC880_DIGOUT_NID,
2839                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2840                 .channel_mode = alc880_threestack_modes,
2841                 .need_dac_fix = 1,
2842                 .input_mux = &alc880_capture_source,
2843         },
2844         [ALC880_TCL_S700] = {
2845                 .mixers = { alc880_tcl_s700_mixer },
2846                 .init_verbs = { alc880_volume_init_verbs,
2847                                 alc880_pin_tcl_S700_init_verbs,
2848                                 alc880_gpio2_init_verbs },
2849                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2850                 .dac_nids = alc880_dac_nids,
2851                 .hp_nid = 0x03,
2852                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2853                 .channel_mode = alc880_2_jack_modes,
2854                 .input_mux = &alc880_capture_source,
2855         },
2856         [ALC880_5ST] = {
2857                 .mixers = { alc880_three_stack_mixer,
2858                             alc880_five_stack_mixer},
2859                 .init_verbs = { alc880_volume_init_verbs,
2860                                 alc880_pin_5stack_init_verbs },
2861                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2862                 .dac_nids = alc880_dac_nids,
2863                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2864                 .channel_mode = alc880_fivestack_modes,
2865                 .input_mux = &alc880_capture_source,
2866         },
2867         [ALC880_5ST_DIG] = {
2868                 .mixers = { alc880_three_stack_mixer,
2869                             alc880_five_stack_mixer },
2870                 .init_verbs = { alc880_volume_init_verbs,
2871                                 alc880_pin_5stack_init_verbs },
2872                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2873                 .dac_nids = alc880_dac_nids,
2874                 .dig_out_nid = ALC880_DIGOUT_NID,
2875                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2876                 .channel_mode = alc880_fivestack_modes,
2877                 .input_mux = &alc880_capture_source,
2878         },
2879         [ALC880_6ST] = {
2880                 .mixers = { alc880_six_stack_mixer },
2881                 .init_verbs = { alc880_volume_init_verbs,
2882                                 alc880_pin_6stack_init_verbs },
2883                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2884                 .dac_nids = alc880_6st_dac_nids,
2885                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2886                 .channel_mode = alc880_sixstack_modes,
2887                 .input_mux = &alc880_6stack_capture_source,
2888         },
2889         [ALC880_6ST_DIG] = {
2890                 .mixers = { alc880_six_stack_mixer },
2891                 .init_verbs = { alc880_volume_init_verbs,
2892                                 alc880_pin_6stack_init_verbs },
2893                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2894                 .dac_nids = alc880_6st_dac_nids,
2895                 .dig_out_nid = ALC880_DIGOUT_NID,
2896                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2897                 .channel_mode = alc880_sixstack_modes,
2898                 .input_mux = &alc880_6stack_capture_source,
2899         },
2900         [ALC880_W810] = {
2901                 .mixers = { alc880_w810_base_mixer },
2902                 .init_verbs = { alc880_volume_init_verbs,
2903                                 alc880_pin_w810_init_verbs,
2904                                 alc880_gpio2_init_verbs },
2905                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2906                 .dac_nids = alc880_w810_dac_nids,
2907                 .dig_out_nid = ALC880_DIGOUT_NID,
2908                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2909                 .channel_mode = alc880_w810_modes,
2910                 .input_mux = &alc880_capture_source,
2911         },
2912         [ALC880_Z71V] = {
2913                 .mixers = { alc880_z71v_mixer },
2914                 .init_verbs = { alc880_volume_init_verbs,
2915                                 alc880_pin_z71v_init_verbs },
2916                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2917                 .dac_nids = alc880_z71v_dac_nids,
2918                 .dig_out_nid = ALC880_DIGOUT_NID,
2919                 .hp_nid = 0x03,
2920                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2921                 .channel_mode = alc880_2_jack_modes,
2922                 .input_mux = &alc880_capture_source,
2923         },
2924         [ALC880_F1734] = {
2925                 .mixers = { alc880_f1734_mixer },
2926                 .init_verbs = { alc880_volume_init_verbs,
2927                                 alc880_pin_f1734_init_verbs },
2928                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2929                 .dac_nids = alc880_f1734_dac_nids,
2930                 .hp_nid = 0x02,
2931                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2932                 .channel_mode = alc880_2_jack_modes,
2933                 .input_mux = &alc880_capture_source,
2934         },
2935         [ALC880_ASUS] = {
2936                 .mixers = { alc880_asus_mixer },
2937                 .init_verbs = { alc880_volume_init_verbs,
2938                                 alc880_pin_asus_init_verbs,
2939                                 alc880_gpio1_init_verbs },
2940                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2941                 .dac_nids = alc880_asus_dac_nids,
2942                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2943                 .channel_mode = alc880_asus_modes,
2944                 .need_dac_fix = 1,
2945                 .input_mux = &alc880_capture_source,
2946         },
2947         [ALC880_ASUS_DIG] = {
2948                 .mixers = { alc880_asus_mixer },
2949                 .init_verbs = { alc880_volume_init_verbs,
2950                                 alc880_pin_asus_init_verbs,
2951                                 alc880_gpio1_init_verbs },
2952                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2953                 .dac_nids = alc880_asus_dac_nids,
2954                 .dig_out_nid = ALC880_DIGOUT_NID,
2955                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2956                 .channel_mode = alc880_asus_modes,
2957                 .need_dac_fix = 1,
2958                 .input_mux = &alc880_capture_source,
2959         },
2960         [ALC880_ASUS_DIG2] = {
2961                 .mixers = { alc880_asus_mixer },
2962                 .init_verbs = { alc880_volume_init_verbs,
2963                                 alc880_pin_asus_init_verbs,
2964                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2965                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2966                 .dac_nids = alc880_asus_dac_nids,
2967                 .dig_out_nid = ALC880_DIGOUT_NID,
2968                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2969                 .channel_mode = alc880_asus_modes,
2970                 .need_dac_fix = 1,
2971                 .input_mux = &alc880_capture_source,
2972         },
2973         [ALC880_ASUS_W1V] = {
2974                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2975                 .init_verbs = { alc880_volume_init_verbs,
2976                                 alc880_pin_asus_init_verbs,
2977                                 alc880_gpio1_init_verbs },
2978                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2979                 .dac_nids = alc880_asus_dac_nids,
2980                 .dig_out_nid = ALC880_DIGOUT_NID,
2981                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2982                 .channel_mode = alc880_asus_modes,
2983                 .need_dac_fix = 1,
2984                 .input_mux = &alc880_capture_source,
2985         },
2986         [ALC880_UNIWILL_DIG] = {
2987                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2988                 .init_verbs = { alc880_volume_init_verbs,
2989                                 alc880_pin_asus_init_verbs },
2990                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2991                 .dac_nids = alc880_asus_dac_nids,
2992                 .dig_out_nid = ALC880_DIGOUT_NID,
2993                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2994                 .channel_mode = alc880_asus_modes,
2995                 .need_dac_fix = 1,
2996                 .input_mux = &alc880_capture_source,
2997         },
2998         [ALC880_UNIWILL] = {
2999                 .mixers = { alc880_uniwill_mixer },
3000                 .init_verbs = { alc880_volume_init_verbs,
3001                                 alc880_uniwill_init_verbs },
3002                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3003                 .dac_nids = alc880_asus_dac_nids,
3004                 .dig_out_nid = ALC880_DIGOUT_NID,
3005                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3006                 .channel_mode = alc880_threestack_modes,
3007                 .need_dac_fix = 1,
3008                 .input_mux = &alc880_capture_source,
3009                 .unsol_event = alc880_uniwill_unsol_event,
3010                 .init_hook = alc880_uniwill_automute,
3011         },
3012         [ALC880_UNIWILL_P53] = {
3013                 .mixers = { alc880_uniwill_p53_mixer },
3014                 .init_verbs = { alc880_volume_init_verbs,
3015                                 alc880_uniwill_p53_init_verbs },
3016                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3017                 .dac_nids = alc880_asus_dac_nids,
3018                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3019                 .channel_mode = alc880_threestack_modes,
3020                 .input_mux = &alc880_capture_source,
3021                 .unsol_event = alc880_uniwill_p53_unsol_event,
3022                 .init_hook = alc880_uniwill_p53_hp_automute,
3023         },
3024         [ALC880_FUJITSU] = {
3025                 .mixers = { alc880_fujitsu_mixer,
3026                             alc880_pcbeep_mixer, },
3027                 .init_verbs = { alc880_volume_init_verbs,
3028                                 alc880_uniwill_p53_init_verbs,
3029                                 alc880_beep_init_verbs },
3030                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3031                 .dac_nids = alc880_dac_nids,
3032                 .dig_out_nid = ALC880_DIGOUT_NID,
3033                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3034                 .channel_mode = alc880_2_jack_modes,
3035                 .input_mux = &alc880_capture_source,
3036                 .unsol_event = alc880_uniwill_p53_unsol_event,
3037                 .init_hook = alc880_uniwill_p53_hp_automute,
3038         },
3039         [ALC880_CLEVO] = {
3040                 .mixers = { alc880_three_stack_mixer },
3041                 .init_verbs = { alc880_volume_init_verbs,
3042                                 alc880_pin_clevo_init_verbs },
3043                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3044                 .dac_nids = alc880_dac_nids,
3045                 .hp_nid = 0x03,
3046                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3047                 .channel_mode = alc880_threestack_modes,
3048                 .need_dac_fix = 1,
3049                 .input_mux = &alc880_capture_source,
3050         },
3051         [ALC880_LG] = {
3052                 .mixers = { alc880_lg_mixer },
3053                 .init_verbs = { alc880_volume_init_verbs,
3054                                 alc880_lg_init_verbs },
3055                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3056                 .dac_nids = alc880_lg_dac_nids,
3057                 .dig_out_nid = ALC880_DIGOUT_NID,
3058                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3059                 .channel_mode = alc880_lg_ch_modes,
3060                 .need_dac_fix = 1,
3061                 .input_mux = &alc880_lg_capture_source,
3062                 .unsol_event = alc880_lg_unsol_event,
3063                 .init_hook = alc880_lg_automute,
3064 #ifdef CONFIG_SND_HDA_POWER_SAVE
3065                 .loopbacks = alc880_lg_loopbacks,
3066 #endif
3067         },
3068         [ALC880_LG_LW] = {
3069                 .mixers = { alc880_lg_lw_mixer },
3070                 .init_verbs = { alc880_volume_init_verbs,
3071                                 alc880_lg_lw_init_verbs },
3072                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3073                 .dac_nids = alc880_dac_nids,
3074                 .dig_out_nid = ALC880_DIGOUT_NID,
3075                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3076                 .channel_mode = alc880_lg_lw_modes,
3077                 .input_mux = &alc880_lg_lw_capture_source,
3078                 .unsol_event = alc880_lg_lw_unsol_event,
3079                 .init_hook = alc880_lg_lw_automute,
3080         },
3081 #ifdef CONFIG_SND_DEBUG
3082         [ALC880_TEST] = {
3083                 .mixers = { alc880_test_mixer },
3084                 .init_verbs = { alc880_test_init_verbs },
3085                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3086                 .dac_nids = alc880_test_dac_nids,
3087                 .dig_out_nid = ALC880_DIGOUT_NID,
3088                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3089                 .channel_mode = alc880_test_modes,
3090                 .input_mux = &alc880_test_capture_source,
3091         },
3092 #endif
3093 };
3094
3095 /*
3096  * Automatic parse of I/O pins from the BIOS configuration
3097  */
3098
3099 #define NUM_CONTROL_ALLOC       32
3100 #define NUM_VERB_ALLOC          32
3101
3102 enum {
3103         ALC_CTL_WIDGET_VOL,
3104         ALC_CTL_WIDGET_MUTE,
3105         ALC_CTL_BIND_MUTE,
3106 };
3107 static struct snd_kcontrol_new alc880_control_templates[] = {
3108         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3109         HDA_CODEC_MUTE(NULL, 0, 0, 0),
3110         HDA_BIND_MUTE(NULL, 0, 0, 0),
3111 };
3112
3113 /* add dynamic controls */
3114 static int add_control(struct alc_spec *spec, int type, const char *name,
3115                        unsigned long val)
3116 {
3117         struct snd_kcontrol_new *knew;
3118
3119         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3120                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3121
3122                 /* array + terminator */
3123                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3124                 if (!knew)
3125                         return -ENOMEM;
3126                 if (spec->kctl_alloc) {
3127                         memcpy(knew, spec->kctl_alloc,
3128                                sizeof(*knew) * spec->num_kctl_alloc);
3129                         kfree(spec->kctl_alloc);
3130                 }
3131                 spec->kctl_alloc = knew;
3132                 spec->num_kctl_alloc = num;
3133         }
3134
3135         knew = &spec->kctl_alloc[spec->num_kctl_used];
3136         *knew = alc880_control_templates[type];
3137         knew->name = kstrdup(name, GFP_KERNEL);
3138         if (!knew->name)
3139                 return -ENOMEM;
3140         knew->private_value = val;
3141         spec->num_kctl_used++;
3142         return 0;
3143 }
3144
3145 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
3146 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
3147 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
3148 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
3149 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
3150 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
3151 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
3152 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
3153 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
3154 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
3155 #define ALC880_PIN_CD_NID               0x1c
3156
3157 /* fill in the dac_nids table from the parsed pin configuration */
3158 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3159                                      const struct auto_pin_cfg *cfg)
3160 {
3161         hda_nid_t nid;
3162         int assigned[4];
3163         int i, j;
3164
3165         memset(assigned, 0, sizeof(assigned));
3166         spec->multiout.dac_nids = spec->private_dac_nids;
3167
3168         /* check the pins hardwired to audio widget */
3169         for (i = 0; i < cfg->line_outs; i++) {
3170                 nid = cfg->line_out_pins[i];
3171                 if (alc880_is_fixed_pin(nid)) {
3172                         int idx = alc880_fixed_pin_idx(nid);
3173                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3174                         assigned[idx] = 1;
3175                 }
3176         }
3177         /* left pins can be connect to any audio widget */
3178         for (i = 0; i < cfg->line_outs; i++) {
3179                 nid = cfg->line_out_pins[i];
3180                 if (alc880_is_fixed_pin(nid))
3181                         continue;
3182                 /* search for an empty channel */
3183                 for (j = 0; j < cfg->line_outs; j++) {
3184                         if (!assigned[j]) {
3185                                 spec->multiout.dac_nids[i] =
3186                                         alc880_idx_to_dac(j);
3187                                 assigned[j] = 1;
3188                                 break;
3189                         }
3190                 }
3191         }
3192         spec->multiout.num_dacs = cfg->line_outs;
3193         return 0;
3194 }
3195
3196 /* add playback controls from the parsed DAC table */
3197 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3198                                              const struct auto_pin_cfg *cfg)
3199 {
3200         char name[32];
3201         static const char *chname[4] = {
3202                 "Front", "Surround", NULL /*CLFE*/, "Side"
3203         };
3204         hda_nid_t nid;
3205         int i, err;
3206
3207         for (i = 0; i < cfg->line_outs; i++) {
3208                 if (!spec->multiout.dac_nids[i])
3209                         continue;
3210                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3211                 if (i == 2) {
3212                         /* Center/LFE */
3213                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3214                                           "Center Playback Volume",
3215                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3216                                                               HDA_OUTPUT));
3217                         if (err < 0)
3218                                 return err;
3219                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3220                                           "LFE Playback Volume",
3221                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3222                                                               HDA_OUTPUT));
3223                         if (err < 0)
3224                                 return err;
3225                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3226                                           "Center Playback Switch",
3227                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3228                                                               HDA_INPUT));
3229                         if (err < 0)
3230                                 return err;
3231                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3232                                           "LFE Playback Switch",
3233                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3234                                                               HDA_INPUT));
3235                         if (err < 0)
3236                                 return err;
3237                 } else {
3238                         sprintf(name, "%s Playback Volume", chname[i]);
3239                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3240                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3241                                                               HDA_OUTPUT));
3242                         if (err < 0)
3243                                 return err;
3244                         sprintf(name, "%s Playback Switch", chname[i]);
3245                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3246                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3247                                                               HDA_INPUT));
3248                         if (err < 0)
3249                                 return err;
3250                 }
3251         }
3252         return 0;
3253 }
3254
3255 /* add playback controls for speaker and HP outputs */
3256 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3257                                         const char *pfx)
3258 {
3259         hda_nid_t nid;
3260         int err;
3261         char name[32];
3262
3263         if (!pin)
3264                 return 0;
3265
3266         if (alc880_is_fixed_pin(pin)) {
3267                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3268                 /* specify the DAC as the extra output */
3269                 if (!spec->multiout.hp_nid)
3270                         spec->multiout.hp_nid = nid;
3271                 else
3272                         spec->multiout.extra_out_nid[0] = nid;
3273                 /* control HP volume/switch on the output mixer amp */
3274                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3275                 sprintf(name, "%s Playback Volume", pfx);
3276                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3277                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3278                 if (err < 0)
3279                         return err;
3280                 sprintf(name, "%s Playback Switch", pfx);
3281                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3282                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3283                 if (err < 0)
3284                         return err;
3285         } else if (alc880_is_multi_pin(pin)) {
3286                 /* set manual connection */
3287                 /* we have only a switch on HP-out PIN */
3288                 sprintf(name, "%s Playback Switch", pfx);
3289                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3290                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3291                 if (err < 0)
3292                         return err;
3293         }
3294         return 0;
3295 }
3296
3297 /* create input playback/capture controls for the given pin */
3298 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3299                             const char *ctlname,
3300                             int idx, hda_nid_t mix_nid)
3301 {
3302         char name[32];
3303         int err;
3304
3305         sprintf(name, "%s Playback Volume", ctlname);
3306         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3307                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3308         if (err < 0)
3309                 return err;
3310         sprintf(name, "%s Playback Switch", ctlname);
3311         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3312                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3313         if (err < 0)
3314                 return err;
3315         return 0;
3316 }
3317
3318 /* create playback/capture controls for input pins */
3319 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3320                                                 const struct auto_pin_cfg *cfg)
3321 {
3322         struct hda_input_mux *imux = &spec->private_imux;
3323         int i, err, idx;
3324
3325         for (i = 0; i < AUTO_PIN_LAST; i++) {
3326                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3327                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3328                         err = new_analog_input(spec, cfg->input_pins[i],
3329                                                auto_pin_cfg_labels[i],
3330                                                idx, 0x0b);
3331                         if (err < 0)
3332                                 return err;
3333                         imux->items[imux->num_items].label =
3334                                 auto_pin_cfg_labels[i];
3335                         imux->items[imux->num_items].index =
3336                                 alc880_input_pin_idx(cfg->input_pins[i]);
3337                         imux->num_items++;
3338                 }
3339         }
3340         return 0;
3341 }
3342
3343 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3344                                               hda_nid_t nid, int pin_type,
3345                                               int dac_idx)
3346 {
3347         /* set as output */
3348         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3349                             pin_type);
3350         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3351                             AMP_OUT_UNMUTE);
3352         /* need the manual connection? */
3353         if (alc880_is_multi_pin(nid)) {
3354                 struct alc_spec *spec = codec->spec;
3355                 int idx = alc880_multi_pin_idx(nid);
3356                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3357                                     AC_VERB_SET_CONNECT_SEL,
3358                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3359         }
3360 }
3361
3362 static int get_pin_type(int line_out_type)
3363 {
3364         if (line_out_type == AUTO_PIN_HP_OUT)
3365                 return PIN_HP;
3366         else
3367                 return PIN_OUT;
3368 }
3369
3370 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3371 {
3372         struct alc_spec *spec = codec->spec;
3373         int i;
3374         
3375         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3376         for (i = 0; i < spec->autocfg.line_outs; i++) {
3377                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3378                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3379                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3380         }
3381 }
3382
3383 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3384 {
3385         struct alc_spec *spec = codec->spec;
3386         hda_nid_t pin;
3387
3388         pin = spec->autocfg.speaker_pins[0];
3389         if (pin) /* connect to front */
3390                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3391         pin = spec->autocfg.hp_pins[0];
3392         if (pin) /* connect to front */
3393                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3394 }
3395
3396 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3397 {
3398         struct alc_spec *spec = codec->spec;
3399         int i;
3400
3401         for (i = 0; i < AUTO_PIN_LAST; i++) {
3402                 hda_nid_t nid = spec->autocfg.input_pins[i];
3403                 if (alc880_is_input_pin(nid)) {
3404                         snd_hda_codec_write(codec, nid, 0,
3405                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3406                                             i <= AUTO_PIN_FRONT_MIC ?
3407                                             PIN_VREF80 : PIN_IN);
3408                         if (nid != ALC880_PIN_CD_NID)
3409                                 snd_hda_codec_write(codec, nid, 0,
3410                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3411                                                     AMP_OUT_MUTE);
3412                 }
3413         }
3414 }
3415
3416 /* parse the BIOS configuration and set up the alc_spec */
3417 /* return 1 if successful, 0 if the proper config is not found,
3418  * or a negative error code
3419  */
3420 static int alc880_parse_auto_config(struct hda_codec *codec)
3421 {
3422         struct alc_spec *spec = codec->spec;
3423         int err;
3424         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3425
3426         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3427                                            alc880_ignore);
3428         if (err < 0)
3429                 return err;
3430         if (!spec->autocfg.line_outs)
3431                 return 0; /* can't find valid BIOS pin config */
3432
3433         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3434         if (err < 0)
3435                 return err;
3436         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3437         if (err < 0)
3438                 return err;
3439         err = alc880_auto_create_extra_out(spec,
3440                                            spec->autocfg.speaker_pins[0],
3441                                            "Speaker");
3442         if (err < 0)
3443                 return err;
3444         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3445                                            "Headphone");
3446         if (err < 0)
3447                 return err;
3448         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3449         if (err < 0)
3450                 return err;
3451
3452         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3453
3454         if (spec->autocfg.dig_out_pin)
3455                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3456         if (spec->autocfg.dig_in_pin)
3457                 spec->dig_in_nid = ALC880_DIGIN_NID;
3458
3459         if (spec->kctl_alloc)
3460                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3461
3462         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3463
3464         spec->num_mux_defs = 1;
3465         spec->input_mux = &spec->private_imux;
3466
3467         return 1;
3468 }
3469
3470 /* additional initialization for auto-configuration model */
3471 static void alc880_auto_init(struct hda_codec *codec)
3472 {
3473         alc880_auto_init_multi_out(codec);
3474         alc880_auto_init_extra_out(codec);
3475         alc880_auto_init_analog_input(codec);
3476 }
3477
3478 /*
3479  * OK, here we have finally the patch for ALC880
3480  */
3481
3482 static int patch_alc880(struct hda_codec *codec)
3483 {
3484         struct alc_spec *spec;
3485         int board_config;
3486         int err;
3487
3488         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3489         if (spec == NULL)
3490                 return -ENOMEM;
3491
3492         codec->spec = spec;
3493
3494         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3495                                                   alc880_models,
3496                                                   alc880_cfg_tbl);
3497         if (board_config < 0) {
3498                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3499                        "trying auto-probe from BIOS...\n");
3500                 board_config = ALC880_AUTO;
3501         }
3502
3503         if (board_config == ALC880_AUTO) {
3504                 /* automatic parse from the BIOS config */
3505                 err = alc880_parse_auto_config(codec);
3506                 if (err < 0) {
3507                         alc_free(codec);
3508                         return err;
3509                 } else if (!err) {
3510                         printk(KERN_INFO
3511                                "hda_codec: Cannot set up configuration "
3512                                "from BIOS.  Using 3-stack mode...\n");
3513                         board_config = ALC880_3ST;
3514                 }
3515         }
3516
3517         if (board_config != ALC880_AUTO)
3518                 setup_preset(spec, &alc880_presets[board_config]);
3519
3520         spec->stream_name_analog = "ALC880 Analog";
3521         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3522         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3523
3524         spec->stream_name_digital = "ALC880 Digital";
3525         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3526         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3527
3528         if (!spec->adc_nids && spec->input_mux) {
3529                 /* check whether NID 0x07 is valid */
3530                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3531                 /* get type */
3532                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3533                 if (wcap != AC_WID_AUD_IN) {
3534                         spec->adc_nids = alc880_adc_nids_alt;
3535                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3536                         spec->mixers[spec->num_mixers] =
3537                                 alc880_capture_alt_mixer;
3538                         spec->num_mixers++;
3539                 } else {
3540                         spec->adc_nids = alc880_adc_nids;
3541                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3542                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3543                         spec->num_mixers++;
3544                 }
3545         }
3546
3547         codec->patch_ops = alc_patch_ops;
3548         if (board_config == ALC880_AUTO)
3549                 spec->init_hook = alc880_auto_init;
3550 #ifdef CONFIG_SND_HDA_POWER_SAVE
3551         if (!spec->loopback.amplist)
3552                 spec->loopback.amplist = alc880_loopbacks;
3553 #endif
3554
3555         return 0;
3556 }
3557
3558
3559 /*
3560  * ALC260 support
3561  */
3562
3563 static hda_nid_t alc260_dac_nids[1] = {
3564         /* front */
3565         0x02,
3566 };
3567
3568 static hda_nid_t alc260_adc_nids[1] = {
3569         /* ADC0 */
3570         0x04,
3571 };
3572
3573 static hda_nid_t alc260_adc_nids_alt[1] = {
3574         /* ADC1 */
3575         0x05,
3576 };
3577
3578 static hda_nid_t alc260_hp_adc_nids[2] = {
3579         /* ADC1, 0 */
3580         0x05, 0x04
3581 };
3582
3583 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3584  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3585  */
3586 static hda_nid_t alc260_dual_adc_nids[2] = {
3587         /* ADC0, ADC1 */
3588         0x04, 0x05
3589 };
3590
3591 #define ALC260_DIGOUT_NID       0x03
3592 #define ALC260_DIGIN_NID        0x06
3593
3594 static struct hda_input_mux alc260_capture_source = {
3595         .num_items = 4,
3596         .items = {
3597                 { "Mic", 0x0 },
3598                 { "Front Mic", 0x1 },
3599                 { "Line", 0x2 },
3600                 { "CD", 0x4 },
3601         },
3602 };
3603
3604 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3605  * headphone jack and the internal CD lines since these are the only pins at
3606  * which audio can appear.  For flexibility, also allow the option of
3607  * recording the mixer output on the second ADC (ADC0 doesn't have a
3608  * connection to the mixer output).
3609  */
3610 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3611         {
3612                 .num_items = 3,
3613                 .items = {
3614                         { "Mic/Line", 0x0 },
3615                         { "CD", 0x4 },
3616                         { "Headphone", 0x2 },
3617                 },
3618         },
3619         {
3620                 .num_items = 4,
3621                 .items = {
3622                         { "Mic/Line", 0x0 },
3623                         { "CD", 0x4 },
3624                         { "Headphone", 0x2 },
3625                         { "Mixer", 0x5 },
3626                 },
3627         },
3628
3629 };
3630
3631 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3632  * the Fujitsu S702x, but jacks are marked differently.
3633  */
3634 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3635         {
3636                 .num_items = 4,
3637                 .items = {
3638                         { "Mic", 0x0 },
3639                         { "Line", 0x2 },
3640                         { "CD", 0x4 },
3641                         { "Headphone", 0x5 },
3642                 },
3643         },
3644         {
3645                 .num_items = 5,
3646                 .items = {
3647                         { "Mic", 0x0 },
3648                         { "Line", 0x2 },
3649                         { "CD", 0x4 },
3650                         { "Headphone", 0x6 },
3651                         { "Mixer", 0x5 },
3652                 },
3653         },
3654 };
3655 /*
3656  * This is just place-holder, so there's something for alc_build_pcms to look
3657  * at when it calculates the maximum number of channels. ALC260 has no mixer
3658  * element which allows changing the channel mode, so the verb list is
3659  * never used.
3660  */
3661 static struct hda_channel_mode alc260_modes[1] = {
3662         { 2, NULL },
3663 };
3664
3665
3666 /* Mixer combinations
3667  *
3668  * basic: base_output + input + pc_beep + capture
3669  * HP: base_output + input + capture_alt
3670  * HP_3013: hp_3013 + input + capture
3671  * fujitsu: fujitsu + capture
3672  * acer: acer + capture
3673  */
3674
3675 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3676         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3677         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3678         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3679         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3680         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3681         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3682         { } /* end */
3683 };
3684
3685 static struct snd_kcontrol_new alc260_input_mixer[] = {
3686         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3687         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3688         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3689         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3690         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3691         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3692         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3693         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3694         { } /* end */
3695 };
3696
3697 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3698         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3699         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3700         { } /* end */
3701 };
3702
3703 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3704         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3705         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3706         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3707         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3708         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3709         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3710         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3711         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3712         { } /* end */
3713 };
3714
3715 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3716  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3717  */
3718 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3719         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3720         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3721         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3722         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3723         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3724         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3725         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3726         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3727         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3728         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3729         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3730         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3731         { } /* end */
3732 };
3733
3734 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3735  * versions of the ALC260 don't act on requests to enable mic bias from NID
3736  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3737  * datasheet doesn't mention this restriction.  At this stage it's not clear
3738  * whether this behaviour is intentional or is a hardware bug in chip
3739  * revisions available in early 2006.  Therefore for now allow the
3740  * "Headphone Jack Mode" control to span all choices, but if it turns out
3741  * that the lack of mic bias for this NID is intentional we could change the
3742  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3743  *
3744  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3745  * don't appear to make the mic bias available from the "line" jack, even
3746  * though the NID used for this jack (0x14) can supply it.  The theory is
3747  * that perhaps Acer have included blocking capacitors between the ALC260
3748  * and the output jack.  If this turns out to be the case for all such
3749  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3750  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3751  *
3752  * The C20x Tablet series have a mono internal speaker which is controlled
3753  * via the chip's Mono sum widget and pin complex, so include the necessary
3754  * controls for such models.  On models without a "mono speaker" the control
3755  * won't do anything.
3756  */
3757 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3758         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3759         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3760         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3761         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3762                               HDA_OUTPUT),
3763         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3764                            HDA_INPUT),
3765         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3766         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3767         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3768         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3769         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3770         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3771         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3772         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3773         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3774         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3775         { } /* end */
3776 };
3777
3778 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3779  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3780  */
3781 static struct snd_kcontrol_new alc260_will_mixer[] = {
3782         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3783         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3784         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3785         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3786         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3787         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3788         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3789         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3790         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3791         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3792         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3793         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3794         { } /* end */
3795 };
3796
3797 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3798  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3799  */
3800 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3801         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3802         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3803         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3804         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3805         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3806         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3807         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3808         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3809         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3810         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3811         { } /* end */
3812 };
3813
3814 /* capture mixer elements */
3815 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3816         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3817         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3818         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3819         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3820         {
3821                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3822                 /* The multiple "Capture Source" controls confuse alsamixer
3823                  * So call somewhat different..
3824                  * FIXME: the controls appear in the "playback" view!
3825                  */
3826                 /* .name = "Capture Source", */
3827                 .name = "Input Source",
3828                 .count = 2,
3829                 .info = alc_mux_enum_info,
3830                 .get = alc_mux_enum_get,
3831                 .put = alc_mux_enum_put,
3832         },
3833         { } /* end */
3834 };
3835
3836 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3837         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3838         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3839         {
3840                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3841                 /* The multiple "Capture Source" controls confuse alsamixer
3842                  * So call somewhat different..
3843                  * FIXME: the controls appear in the "playback" view!
3844                  */
3845                 /* .name = "Capture Source", */
3846                 .name = "Input Source",
3847                 .count = 1,
3848                 .info = alc_mux_enum_info,
3849                 .get = alc_mux_enum_get,
3850                 .put = alc_mux_enum_put,
3851         },
3852         { } /* end */
3853 };
3854
3855 /*
3856  * initialization verbs
3857  */
3858 static struct hda_verb alc260_init_verbs[] = {
3859         /* Line In pin widget for input */
3860         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3861         /* CD pin widget for input */
3862         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3863         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3864         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3865         /* Mic2 (front panel) pin widget for input and vref at 80% */
3866         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3867         /* LINE-2 is used for line-out in rear */
3868         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3869         /* select line-out */
3870         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3871         /* LINE-OUT pin */
3872         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3873         /* enable HP */
3874         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3875         /* enable Mono */
3876         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3877         /* mute capture amp left and right */
3878         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3879         /* set connection select to line in (default select for this ADC) */
3880         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3881         /* mute capture amp left and right */
3882         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3883         /* set connection select to line in (default select for this ADC) */
3884         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3885         /* set vol=0 Line-Out mixer amp left and right */
3886         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3887         /* unmute pin widget amp left and right (no gain on this amp) */
3888         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3889         /* set vol=0 HP mixer amp left and right */
3890         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3891         /* unmute pin widget amp left and right (no gain on this amp) */
3892         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3893         /* set vol=0 Mono mixer amp left and right */
3894         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3895         /* unmute pin widget amp left and right (no gain on this amp) */
3896         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3897         /* unmute LINE-2 out pin */
3898         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3899         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3900          * Line In 2 = 0x03
3901          */
3902         /* mute analog inputs */
3903         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3904         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3905         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3906         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3907         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3908         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3909         /* mute Front out path */
3910         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3911         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3912         /* mute Headphone out path */
3913         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3914         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3915         /* mute Mono out path */
3916         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3917         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3918         { }
3919 };
3920
3921 #if 0 /* should be identical with alc260_init_verbs? */
3922 static struct hda_verb alc260_hp_init_verbs[] = {
3923         /* Headphone and output */
3924         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3925         /* mono output */
3926         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3927         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3928         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3929         /* Mic2 (front panel) pin widget for input and vref at 80% */
3930         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3931         /* Line In pin widget for input */
3932         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3933         /* Line-2 pin widget for output */
3934         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3935         /* CD pin widget for input */
3936         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3937         /* unmute amp left and right */
3938         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3939         /* set connection select to line in (default select for this ADC) */
3940         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3941         /* unmute Line-Out mixer amp left and right (volume = 0) */
3942         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3943         /* mute pin widget amp left and right (no gain on this amp) */
3944         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3945         /* unmute HP mixer amp left and right (volume = 0) */
3946         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3947         /* mute pin widget amp left and right (no gain on this amp) */
3948         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3949         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3950          * Line In 2 = 0x03
3951          */
3952         /* mute analog inputs */
3953         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3954         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3955         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3956         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3957         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3958         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3959         /* Unmute Front out path */
3960         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3961         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3962         /* Unmute Headphone out path */
3963         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3964         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3965         /* Unmute Mono out path */
3966         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3967         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3968         { }
3969 };
3970 #endif
3971
3972 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3973         /* Line out and output */
3974         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3975         /* mono output */
3976         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3977         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3978         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3979         /* Mic2 (front panel) pin widget for input and vref at 80% */
3980         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3981         /* Line In pin widget for input */
3982         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3983         /* Headphone pin widget for output */
3984         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3985         /* CD pin widget for input */
3986         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3987         /* unmute amp left and right */
3988         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3989         /* set connection select to line in (default select for this ADC) */
3990         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3991         /* unmute Line-Out mixer amp left and right (volume = 0) */
3992         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3993         /* mute pin widget amp left and right (no gain on this amp) */
3994         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3995         /* unmute HP mixer amp left and right (volume = 0) */
3996         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3997         /* mute pin widget amp left and right (no gain on this amp) */
3998         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3999         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4000          * Line In 2 = 0x03
4001          */
4002         /* mute analog inputs */
4003         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4004         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4005         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4006         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4007         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4008         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4009         /* Unmute Front out path */
4010         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4011         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4012         /* Unmute Headphone out path */
4013         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4014         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4015         /* Unmute Mono out path */
4016         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4017         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4018         { }
4019 };
4020
4021 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4022  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4023  * audio = 0x16, internal speaker = 0x10.
4024  */
4025 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4026         /* Disable all GPIOs */
4027         {0x01, AC_VERB_SET_GPIO_MASK, 0},
4028         /* Internal speaker is connected to headphone pin */
4029         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4030         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4031         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4032         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4033         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4034         /* Ensure all other unused pins are disabled and muted. */
4035         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4036         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4037         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4038         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4039         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4040         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4041         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4042         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4043
4044         /* Disable digital (SPDIF) pins */
4045         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4046         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4047
4048         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
4049          * when acting as an output.
4050          */
4051         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4052
4053         /* Start with output sum widgets muted and their output gains at min */
4054         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4055         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4056         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4057         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4058         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4059         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4060         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4061         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4062         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4063
4064         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4065         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4066         /* Unmute Line1 pin widget output buffer since it starts as an output.
4067          * If the pin mode is changed by the user the pin mode control will
4068          * take care of enabling the pin's input/output buffers as needed.
4069          * Therefore there's no need to enable the input buffer at this
4070          * stage.
4071          */
4072         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4073         /* Unmute input buffer of pin widget used for Line-in (no equiv 
4074          * mixer ctrl)
4075          */
4076         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4077
4078         /* Mute capture amp left and right */
4079         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4080         /* Set ADC connection select to match default mixer setting - line 
4081          * in (on mic1 pin)
4082          */
4083         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4084
4085         /* Do the same for the second ADC: mute capture input amp and
4086          * set ADC connection to line in (on mic1 pin)
4087          */
4088         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4089         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4090
4091         /* Mute all inputs to mixer widget (even unconnected ones) */
4092         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4093         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4094         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4095         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4096         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4097         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4098         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4099         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4100
4101         { }
4102 };
4103
4104 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4105  * similar laptops (adapted from Fujitsu init verbs).
4106  */
4107 static struct hda_verb alc260_acer_init_verbs[] = {
4108         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4109          * the headphone jack.  Turn this on and rely on the standard mute
4110          * methods whenever the user wants to turn these outputs off.
4111          */
4112         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4113         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4114         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4115         /* Internal speaker/Headphone jack is connected to Line-out pin */
4116         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4117         /* Internal microphone/Mic jack is connected to Mic1 pin */
4118         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4119         /* Line In jack is connected to Line1 pin */
4120         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4121         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4122         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4123         /* Ensure all other unused pins are disabled and muted. */
4124         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4125         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4126         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4127         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4128         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4129         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4130         /* Disable digital (SPDIF) pins */
4131         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4132         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4133
4134         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
4135          * bus when acting as outputs.
4136          */
4137         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4138         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4139
4140         /* Start with output sum widgets muted and their output gains at min */
4141         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4142         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4143         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4144         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4145         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4146         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4147         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4148         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4149         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4150
4151         /* Unmute Line-out pin widget amp left and right
4152          * (no equiv mixer ctrl)
4153          */
4154         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4155         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4156         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4157         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4158          * inputs. If the pin mode is changed by the user the pin mode control
4159          * will take care of enabling the pin's input/output buffers as needed.
4160          * Therefore there's no need to enable the input buffer at this
4161          * stage.
4162          */
4163         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4164         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4165
4166         /* Mute capture amp left and right */
4167         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4168         /* Set ADC connection select to match default mixer setting - mic
4169          * (on mic1 pin)
4170          */
4171         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4172
4173         /* Do similar with the second ADC: mute capture input amp and
4174          * set ADC connection to mic to match ALSA's default state.
4175          */
4176         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4177         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4178
4179         /* Mute all inputs to mixer widget (even unconnected ones) */
4180         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4181         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4182         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4183         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4184         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4185         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4186         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4187         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4188
4189         { }
4190 };
4191
4192 static struct hda_verb alc260_will_verbs[] = {
4193         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4194         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4195         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4196         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4197         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4198         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4199         {}
4200 };
4201
4202 static struct hda_verb alc260_replacer_672v_verbs[] = {
4203         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4204         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4205         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4206
4207         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4208         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4209         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4210
4211         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4212         {}
4213 };
4214
4215 /* toggle speaker-output according to the hp-jack state */
4216 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4217 {
4218         unsigned int present;
4219
4220         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4221         present = snd_hda_codec_read(codec, 0x0f, 0,
4222                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4223         if (present) {
4224                 snd_hda_codec_write_cache(codec, 0x01, 0,
4225                                           AC_VERB_SET_GPIO_DATA, 1);
4226                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4227                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4228                                           PIN_HP);
4229         } else {
4230                 snd_hda_codec_write_cache(codec, 0x01, 0,
4231                                           AC_VERB_SET_GPIO_DATA, 0);
4232                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4233                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4234                                           PIN_OUT);
4235         }
4236 }
4237
4238 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4239                                        unsigned int res)
4240 {
4241         if ((res >> 26) == ALC880_HP_EVENT)
4242                 alc260_replacer_672v_automute(codec);
4243 }
4244
4245 /* Test configuration for debugging, modelled after the ALC880 test
4246  * configuration.
4247  */
4248 #ifdef CONFIG_SND_DEBUG
4249 static hda_nid_t alc260_test_dac_nids[1] = {
4250         0x02,
4251 };
4252 static hda_nid_t alc260_test_adc_nids[2] = {
4253         0x04, 0x05,
4254 };
4255 /* For testing the ALC260, each input MUX needs its own definition since
4256  * the signal assignments are different.  This assumes that the first ADC 
4257  * is NID 0x04.
4258  */
4259 static struct hda_input_mux alc260_test_capture_sources[2] = {
4260         {
4261                 .num_items = 7,
4262                 .items = {
4263                         { "MIC1 pin", 0x0 },
4264                         { "MIC2 pin", 0x1 },
4265                         { "LINE1 pin", 0x2 },
4266                         { "LINE2 pin", 0x3 },
4267                         { "CD pin", 0x4 },
4268                         { "LINE-OUT pin", 0x5 },
4269                         { "HP-OUT pin", 0x6 },
4270                 },
4271         },
4272         {
4273                 .num_items = 8,
4274                 .items = {
4275                         { "MIC1 pin", 0x0 },
4276                         { "MIC2 pin", 0x1 },
4277                         { "LINE1 pin", 0x2 },
4278                         { "LINE2 pin", 0x3 },
4279                         { "CD pin", 0x4 },
4280                         { "Mixer", 0x5 },
4281                         { "LINE-OUT pin", 0x6 },
4282                         { "HP-OUT pin", 0x7 },
4283                 },
4284         },
4285 };
4286 static struct snd_kcontrol_new alc260_test_mixer[] = {
4287         /* Output driver widgets */
4288         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4289         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4290         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4291         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4292         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4293         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4294
4295         /* Modes for retasking pin widgets
4296          * Note: the ALC260 doesn't seem to act on requests to enable mic
4297          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4298          * mention this restriction.  At this stage it's not clear whether
4299          * this behaviour is intentional or is a hardware bug in chip
4300          * revisions available at least up until early 2006.  Therefore for
4301          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4302          * choices, but if it turns out that the lack of mic bias for these
4303          * NIDs is intentional we could change their modes from
4304          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4305          */
4306         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4307         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4308         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4309         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4310         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4311         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4312
4313         /* Loopback mixer controls */
4314         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4315         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4316         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4317         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4318         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4319         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4320         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4321         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4322         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4323         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4324         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4325         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4326         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4327         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4328         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4329         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4330
4331         /* Controls for GPIO pins, assuming they are configured as outputs */
4332         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4333         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4334         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4335         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4336
4337         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4338          * is ambigious as to which NID is which; testing on laptops which
4339          * make this output available should provide clarification. 
4340          */
4341         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4342         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4343
4344         { } /* end */
4345 };
4346 static struct hda_verb alc260_test_init_verbs[] = {
4347         /* Enable all GPIOs as outputs with an initial value of 0 */
4348         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4349         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4350         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4351
4352         /* Enable retasking pins as output, initially without power amp */
4353         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4354         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4355         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4356         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4357         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4358         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4359
4360         /* Disable digital (SPDIF) pins initially, but users can enable
4361          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4362          * payload also sets the generation to 0, output to be in "consumer"
4363          * PCM format, copyright asserted, no pre-emphasis and no validity
4364          * control.
4365          */
4366         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4367         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4368
4369         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4370          * OUT1 sum bus when acting as an output.
4371          */
4372         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4373         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4374         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4375         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4376
4377         /* Start with output sum widgets muted and their output gains at min */
4378         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4379         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4380         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4381         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4382         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4383         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4384         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4385         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4386         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4387
4388         /* Unmute retasking pin widget output buffers since the default
4389          * state appears to be output.  As the pin mode is changed by the
4390          * user the pin mode control will take care of enabling the pin's
4391          * input/output buffers as needed.
4392          */
4393         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4394         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4395         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4396         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4397         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4398         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4399         /* Also unmute the mono-out pin widget */
4400         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4401
4402         /* Mute capture amp left and right */
4403         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4404         /* Set ADC connection select to match default mixer setting (mic1
4405          * pin)
4406          */
4407         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4408
4409         /* Do the same for the second ADC: mute capture input amp and
4410          * set ADC connection to mic1 pin
4411          */
4412         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4413         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4414
4415         /* Mute all inputs to mixer widget (even unconnected ones) */
4416         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4417         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4418         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4419         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4420         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4421         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4422         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4423         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4424
4425         { }
4426 };
4427 #endif
4428
4429 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4430         .substreams = 1,
4431         .channels_min = 2,
4432         .channels_max = 2,
4433 };
4434
4435 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4436         .substreams = 1,
4437         .channels_min = 2,
4438         .channels_max = 2,
4439 };
4440
4441 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4442 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4443
4444 /*
4445  * for BIOS auto-configuration
4446  */
4447
4448 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4449                                         const char *pfx)
4450 {
4451         hda_nid_t nid_vol;
4452         unsigned long vol_val, sw_val;
4453         char name[32];
4454         int err;
4455
4456         if (nid >= 0x0f && nid < 0x11) {
4457                 nid_vol = nid - 0x7;
4458                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4459                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4460         } else if (nid == 0x11) {
4461                 nid_vol = nid - 0x7;
4462                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4463                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4464         } else if (nid >= 0x12 && nid <= 0x15) {
4465                 nid_vol = 0x08;
4466                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4467                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4468         } else
4469                 return 0; /* N/A */
4470         
4471         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4472         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4473         if (err < 0)
4474                 return err;
4475         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4476         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4477         if (err < 0)
4478                 return err;
4479         return 1;
4480 }
4481
4482 /* add playback controls from the parsed DAC table */
4483 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4484                                              const struct auto_pin_cfg *cfg)
4485 {
4486         hda_nid_t nid;
4487         int err;
4488
4489         spec->multiout.num_dacs = 1;
4490         spec->multiout.dac_nids = spec->private_dac_nids;
4491         spec->multiout.dac_nids[0] = 0x02;
4492
4493         nid = cfg->line_out_pins[0];
4494         if (nid) {
4495                 err = alc260_add_playback_controls(spec, nid, "Front");
4496                 if (err < 0)
4497                         return err;
4498         }
4499
4500         nid = cfg->speaker_pins[0];
4501         if (nid) {
4502                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4503                 if (err < 0)
4504                         return err;
4505         }
4506
4507         nid = cfg->hp_pins[0];
4508         if (nid) {
4509                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4510                 if (err < 0)
4511                         return err;
4512         }
4513         return 0;
4514 }
4515
4516 /* create playback/capture controls for input pins */
4517 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4518                                                 const struct auto_pin_cfg *cfg)
4519 {
4520         struct hda_input_mux *imux = &spec->private_imux;
4521         int i, err, idx;
4522
4523         for (i = 0; i < AUTO_PIN_LAST; i++) {
4524                 if (cfg->input_pins[i] >= 0x12) {
4525                         idx = cfg->input_pins[i] - 0x12;
4526                         err = new_analog_input(spec, cfg->input_pins[i],
4527                                                auto_pin_cfg_labels[i], idx,
4528                                                0x07);
4529                         if (err < 0)
4530                                 return err;
4531                         imux->items[imux->num_items].label =
4532                                 auto_pin_cfg_labels[i];
4533                         imux->items[imux->num_items].index = idx;
4534                         imux->num_items++;
4535                 }
4536                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4537                         idx = cfg->input_pins[i] - 0x09;
4538                         err = new_analog_input(spec, cfg->input_pins[i],
4539                                                auto_pin_cfg_labels[i], idx,
4540                                                0x07);
4541                         if (err < 0)
4542                                 return err;
4543                         imux->items[imux->num_items].label =
4544                                 auto_pin_cfg_labels[i];
4545                         imux->items[imux->num_items].index = idx;
4546                         imux->num_items++;
4547                 }
4548         }
4549         return 0;
4550 }
4551
4552 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4553                                               hda_nid_t nid, int pin_type,
4554                                               int sel_idx)
4555 {
4556         /* set as output */
4557         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4558                             pin_type);
4559         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4560                             AMP_OUT_UNMUTE);
4561         /* need the manual connection? */
4562         if (nid >= 0x12) {
4563                 int idx = nid - 0x12;
4564                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4565                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4566         }
4567 }
4568
4569 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4570 {
4571         struct alc_spec *spec = codec->spec;
4572         hda_nid_t nid;
4573
4574         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4575         nid = spec->autocfg.line_out_pins[0];
4576         if (nid) {
4577                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4578                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4579         }
4580         
4581         nid = spec->autocfg.speaker_pins[0];
4582         if (nid)
4583                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4584
4585         nid = spec->autocfg.hp_pins[0];
4586         if (nid)
4587                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4588 }
4589
4590 #define ALC260_PIN_CD_NID               0x16
4591 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4592 {
4593         struct alc_spec *spec = codec->spec;
4594         int i;
4595
4596         for (i = 0; i < AUTO_PIN_LAST; i++) {
4597                 hda_nid_t nid = spec->autocfg.input_pins[i];
4598                 if (nid >= 0x12) {
4599                         snd_hda_codec_write(codec, nid, 0,
4600                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4601                                             i <= AUTO_PIN_FRONT_MIC ?
4602                                             PIN_VREF80 : PIN_IN);
4603                         if (nid != ALC260_PIN_CD_NID)
4604                                 snd_hda_codec_write(codec, nid, 0,
4605                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4606                                                     AMP_OUT_MUTE);
4607                 }
4608         }
4609 }
4610
4611 /*
4612  * generic initialization of ADC, input mixers and output mixers
4613  */
4614 static struct hda_verb alc260_volume_init_verbs[] = {
4615         /*
4616          * Unmute ADC0-1 and set the default input to mic-in
4617          */
4618         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4619         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4620         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4621         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4622         
4623         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4624          * mixer widget
4625          * Note: PASD motherboards uses the Line In 2 as the input for
4626          * front panel mic (mic 2)
4627          */
4628         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4629         /* mute analog inputs */
4630         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4631         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4632         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4633         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4634         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4635
4636         /*
4637          * Set up output mixers (0x08 - 0x0a)
4638          */
4639         /* set vol=0 to output mixers */
4640         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4641         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4642         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4643         /* set up input amps for analog loopback */
4644         /* Amp Indices: DAC = 0, mixer = 1 */
4645         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4646         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4647         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4648         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4649         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4650         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4651         
4652         { }
4653 };
4654
4655 static int alc260_parse_auto_config(struct hda_codec *codec)
4656 {
4657         struct alc_spec *spec = codec->spec;
4658         unsigned int wcap;
4659         int err;
4660         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4661
4662         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4663                                            alc260_ignore);
4664         if (err < 0)
4665                 return err;
4666         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4667         if (err < 0)
4668                 return err;
4669         if (!spec->kctl_alloc)
4670                 return 0; /* can't find valid BIOS pin config */
4671         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4672         if (err < 0)
4673                 return err;
4674
4675         spec->multiout.max_channels = 2;
4676
4677         if (spec->autocfg.dig_out_pin)
4678                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4679         if (spec->kctl_alloc)
4680                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4681
4682         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4683
4684         spec->num_mux_defs = 1;
4685         spec->input_mux = &spec->private_imux;
4686
4687         /* check whether NID 0x04 is valid */
4688         wcap = get_wcaps(codec, 0x04);
4689         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4690         if (wcap != AC_WID_AUD_IN) {
4691                 spec->adc_nids = alc260_adc_nids_alt;
4692                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4693                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4694         } else {
4695                 spec->adc_nids = alc260_adc_nids;
4696                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4697                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4698         }
4699         spec->num_mixers++;
4700
4701         return 1;
4702 }
4703
4704 /* additional initialization for auto-configuration model */
4705 static void alc260_auto_init(struct hda_codec *codec)
4706 {
4707         alc260_auto_init_multi_out(codec);
4708         alc260_auto_init_analog_input(codec);
4709 }
4710
4711 #ifdef CONFIG_SND_HDA_POWER_SAVE
4712 static struct hda_amp_list alc260_loopbacks[] = {
4713         { 0x07, HDA_INPUT, 0 },
4714         { 0x07, HDA_INPUT, 1 },
4715         { 0x07, HDA_INPUT, 2 },
4716         { 0x07, HDA_INPUT, 3 },
4717         { 0x07, HDA_INPUT, 4 },
4718         { } /* end */
4719 };
4720 #endif
4721
4722 /*
4723  * ALC260 configurations
4724  */
4725 static const char *alc260_models[ALC260_MODEL_LAST] = {
4726         [ALC260_BASIC]          = "basic",
4727         [ALC260_HP]             = "hp",
4728         [ALC260_HP_3013]        = "hp-3013",
4729         [ALC260_FUJITSU_S702X]  = "fujitsu",
4730         [ALC260_ACER]           = "acer",
4731         [ALC260_WILL]           = "will",
4732         [ALC260_REPLACER_672V]  = "replacer",
4733 #ifdef CONFIG_SND_DEBUG
4734         [ALC260_TEST]           = "test",
4735 #endif
4736         [ALC260_AUTO]           = "auto",
4737 };
4738
4739 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4740         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4741         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4742         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4743         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4744         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4745         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4746         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4747         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4748         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4749         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4750         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4751         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4752         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4753         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4754         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4755         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4756         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4757         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4758         {}
4759 };
4760
4761 static struct alc_config_preset alc260_presets[] = {
4762         [ALC260_BASIC] = {
4763                 .mixers = { alc260_base_output_mixer,
4764                             alc260_input_mixer,
4765                             alc260_pc_beep_mixer,
4766                             alc260_capture_mixer },
4767                 .init_verbs = { alc260_init_verbs },
4768                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4769                 .dac_nids = alc260_dac_nids,
4770                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4771                 .adc_nids = alc260_adc_nids,
4772                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4773                 .channel_mode = alc260_modes,
4774                 .input_mux = &alc260_capture_source,
4775         },
4776         [ALC260_HP] = {
4777                 .mixers = { alc260_base_output_mixer,
4778                             alc260_input_mixer,
4779                             alc260_capture_alt_mixer },
4780                 .init_verbs = { alc260_init_verbs },
4781                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4782                 .dac_nids = alc260_dac_nids,
4783                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4784                 .adc_nids = alc260_hp_adc_nids,
4785                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4786                 .channel_mode = alc260_modes,
4787                 .input_mux = &alc260_capture_source,
4788         },
4789         [ALC260_HP_3013] = {
4790                 .mixers = { alc260_hp_3013_mixer,
4791                             alc260_input_mixer,
4792                             alc260_capture_alt_mixer },
4793                 .init_verbs = { alc260_hp_3013_init_verbs },
4794                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4795                 .dac_nids = alc260_dac_nids,
4796                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4797                 .adc_nids = alc260_hp_adc_nids,
4798                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4799                 .channel_mode = alc260_modes,
4800                 .input_mux = &alc260_capture_source,
4801         },
4802         [ALC260_FUJITSU_S702X] = {
4803                 .mixers = { alc260_fujitsu_mixer,
4804                             alc260_capture_mixer },
4805                 .init_verbs = { alc260_fujitsu_init_verbs },
4806                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4807                 .dac_nids = alc260_dac_nids,
4808                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4809                 .adc_nids = alc260_dual_adc_nids,
4810                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4811                 .channel_mode = alc260_modes,
4812                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4813                 .input_mux = alc260_fujitsu_capture_sources,
4814         },
4815         [ALC260_ACER] = {
4816                 .mixers = { alc260_acer_mixer,
4817                             alc260_capture_mixer },
4818                 .init_verbs = { alc260_acer_init_verbs },
4819                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4820                 .dac_nids = alc260_dac_nids,
4821                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4822                 .adc_nids = alc260_dual_adc_nids,
4823                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4824                 .channel_mode = alc260_modes,
4825                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4826                 .input_mux = alc260_acer_capture_sources,
4827         },
4828         [ALC260_WILL] = {
4829                 .mixers = { alc260_will_mixer,
4830                             alc260_capture_mixer },
4831                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4832                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4833                 .dac_nids = alc260_dac_nids,
4834                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4835                 .adc_nids = alc260_adc_nids,
4836                 .dig_out_nid = ALC260_DIGOUT_NID,
4837                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4838                 .channel_mode = alc260_modes,
4839                 .input_mux = &alc260_capture_source,
4840         },
4841         [ALC260_REPLACER_672V] = {
4842                 .mixers = { alc260_replacer_672v_mixer,
4843                             alc260_capture_mixer },
4844                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4845                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4846                 .dac_nids = alc260_dac_nids,
4847                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4848                 .adc_nids = alc260_adc_nids,
4849                 .dig_out_nid = ALC260_DIGOUT_NID,
4850                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4851                 .channel_mode = alc260_modes,
4852                 .input_mux = &alc260_capture_source,
4853                 .unsol_event = alc260_replacer_672v_unsol_event,
4854                 .init_hook = alc260_replacer_672v_automute,
4855         },
4856 #ifdef CONFIG_SND_DEBUG
4857         [ALC260_TEST] = {
4858                 .mixers = { alc260_test_mixer,
4859                             alc260_capture_mixer },
4860                 .init_verbs = { alc260_test_init_verbs },
4861                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4862                 .dac_nids = alc260_test_dac_nids,
4863                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4864                 .adc_nids = alc260_test_adc_nids,
4865                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4866                 .channel_mode = alc260_modes,
4867                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4868                 .input_mux = alc260_test_capture_sources,
4869         },
4870 #endif
4871 };
4872
4873 static int patch_alc260(struct hda_codec *codec)
4874 {
4875         struct alc_spec *spec;
4876         int err, board_config;
4877
4878         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4879         if (spec == NULL)
4880                 return -ENOMEM;
4881
4882         codec->spec = spec;
4883
4884         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4885                                                   alc260_models,
4886                                                   alc260_cfg_tbl);
4887         if (board_config < 0) {
4888                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4889                            "trying auto-probe from BIOS...\n");
4890                 board_config = ALC260_AUTO;
4891         }
4892
4893         if (board_config == ALC260_AUTO) {
4894                 /* automatic parse from the BIOS config */
4895                 err = alc260_parse_auto_config(codec);
4896                 if (err < 0) {
4897                         alc_free(codec);
4898                         return err;
4899                 } else if (!err) {
4900                         printk(KERN_INFO
4901                                "hda_codec: Cannot set up configuration "
4902                                "from BIOS.  Using base mode...\n");
4903                         board_config = ALC260_BASIC;
4904                 }
4905         }
4906
4907         if (board_config != ALC260_AUTO)
4908                 setup_preset(spec, &alc260_presets[board_config]);
4909
4910         spec->stream_name_analog = "ALC260 Analog";
4911         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4912         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4913
4914         spec->stream_name_digital = "ALC260 Digital";
4915         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4916         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4917
4918         codec->patch_ops = alc_patch_ops;
4919         if (board_config == ALC260_AUTO)
4920                 spec->init_hook = alc260_auto_init;
4921 #ifdef CONFIG_SND_HDA_POWER_SAVE
4922         if (!spec->loopback.amplist)
4923                 spec->loopback.amplist = alc260_loopbacks;
4924 #endif
4925
4926         return 0;
4927 }
4928
4929
4930 /*
4931  * ALC882 support
4932  *
4933  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4934  * configuration.  Each pin widget can choose any input DACs and a mixer.
4935  * Each ADC is connected from a mixer of all inputs.  This makes possible
4936  * 6-channel independent captures.
4937  *
4938  * In addition, an independent DAC for the multi-playback (not used in this
4939  * driver yet).
4940  */
4941 #define ALC882_DIGOUT_NID       0x06
4942 #define ALC882_DIGIN_NID        0x0a
4943
4944 static struct hda_channel_mode alc882_ch_modes[1] = {
4945         { 8, NULL }
4946 };
4947
4948 static hda_nid_t alc882_dac_nids[4] = {
4949         /* front, rear, clfe, rear_surr */
4950         0x02, 0x03, 0x04, 0x05
4951 };
4952
4953 /* identical with ALC880 */
4954 #define alc882_adc_nids         alc880_adc_nids
4955 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4956
4957 /* input MUX */
4958 /* FIXME: should be a matrix-type input source selection */
4959
4960 static struct hda_input_mux alc882_capture_source = {
4961         .num_items = 4,
4962         .items = {
4963                 { "Mic", 0x0 },
4964                 { "Front Mic", 0x1 },
4965                 { "Line", 0x2 },
4966                 { "CD", 0x4 },
4967         },
4968 };
4969 #define alc882_mux_enum_info alc_mux_enum_info
4970 #define alc882_mux_enum_get alc_mux_enum_get
4971
4972 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4973                                struct snd_ctl_elem_value *ucontrol)
4974 {
4975         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4976         struct alc_spec *spec = codec->spec;
4977         const struct hda_input_mux *imux = spec->input_mux;
4978         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4979         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4980         hda_nid_t nid = capture_mixers[adc_idx];
4981         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4982         unsigned int i, idx;
4983
4984         idx = ucontrol->value.enumerated.item[0];
4985         if (idx >= imux->num_items)
4986                 idx = imux->num_items - 1;
4987         if (*cur_val == idx)
4988                 return 0;
4989         for (i = 0; i < imux->num_items; i++) {
4990                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4991                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4992                                          imux->items[i].index,
4993                                          HDA_AMP_MUTE, v);
4994         }
4995         *cur_val = idx;
4996         return 1;
4997 }
4998
4999 /*
5000  * 2ch mode
5001  */
5002 static struct hda_verb alc882_3ST_ch2_init[] = {
5003         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5004         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5005         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5006         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5007         { } /* end */
5008 };
5009
5010 /*
5011  * 6ch mode
5012  */
5013 static struct hda_verb alc882_3ST_ch6_init[] = {
5014         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5015         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5016         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5017         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5018         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5019         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5020         { } /* end */
5021 };
5022
5023 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5024         { 2, alc882_3ST_ch2_init },
5025         { 6, alc882_3ST_ch6_init },
5026 };
5027
5028 /*
5029  * 6ch mode
5030  */
5031 static struct hda_verb alc882_sixstack_ch6_init[] = {
5032         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5033         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5034         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5035         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5036         { } /* end */
5037 };
5038
5039 /*
5040  * 8ch mode
5041  */
5042 static struct hda_verb alc882_sixstack_ch8_init[] = {
5043         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5044         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5045         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5046         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5047         { } /* end */
5048 };
5049
5050 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5051         { 6, alc882_sixstack_ch6_init },
5052         { 8, alc882_sixstack_ch8_init },
5053 };
5054
5055 /*
5056  * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5057  */
5058
5059 /*
5060  * 2ch mode
5061  */
5062 static struct hda_verb alc885_mbp_ch2_init[] = {
5063         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5064         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5065         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5066         { } /* end */
5067 };
5068
5069 /*
5070  * 6ch mode
5071  */
5072 static struct hda_verb alc885_mbp_ch6_init[] = {
5073         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5074         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5075         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5076         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5077         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5078         { } /* end */
5079 };
5080
5081 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5082         { 2, alc885_mbp_ch2_init },
5083         { 6, alc885_mbp_ch6_init },
5084 };
5085
5086
5087 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5088  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5089  */
5090 static struct snd_kcontrol_new alc882_base_mixer[] = {
5091         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5092         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5093         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5094         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5095         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5096         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5097         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5098         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5099         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5100         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5101         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5102         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5103         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5104         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5105         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5106         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5107         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5108         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5109         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5110         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5111         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5112         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5113         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5114         { } /* end */
5115 };
5116
5117 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5118         HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5119         HDA_BIND_MUTE   ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5120         HDA_CODEC_MUTE  ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5121         HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5122         HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5123         HDA_CODEC_MUTE  ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5124         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5125         HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5126         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5127         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5128         { } /* end */
5129 };
5130 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5131         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5132         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5133         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5134         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5135         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5136         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5137         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5138         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5139         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5140         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5141         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5142         { } /* end */
5143 };
5144
5145 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5146         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5147         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5148         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5149         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5150         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5151         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5152         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5153         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5154         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5155         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5156         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5157         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5158         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5159         { } /* end */
5160 };
5161
5162 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5163  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5164  */
5165 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5166         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5167         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5168         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5169         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5170         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5171         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5172         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5173         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5174         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5175         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5176         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5177         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5178         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5179         { } /* end */
5180 };
5181
5182 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5183         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5184         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5185         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5186         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5187         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5188         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5189         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5190         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5191         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5192         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5193         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5194         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5195         { } /* end */
5196 };
5197
5198 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5199         {
5200                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5201                 .name = "Channel Mode",
5202                 .info = alc_ch_mode_info,
5203                 .get = alc_ch_mode_get,
5204                 .put = alc_ch_mode_put,
5205         },
5206         { } /* end */
5207 };
5208
5209 static struct hda_verb alc882_init_verbs[] = {
5210         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5211         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5212         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5213         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5214         /* Rear mixer */
5215         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5216         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5217         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5218         /* CLFE mixer */
5219         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5220         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5221         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5222         /* Side mixer */
5223         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5224         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5225         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5226
5227         /* Front Pin: output 0 (0x0c) */
5228         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5229         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5230         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5231         /* Rear Pin: output 1 (0x0d) */
5232         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5233         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5234         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5235         /* CLFE Pin: output 2 (0x0e) */
5236         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5237         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5238         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5239         /* Side Pin: output 3 (0x0f) */
5240         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5241         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5242         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5243         /* Mic (rear) pin: input vref at 80% */
5244         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5245         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5246         /* Front Mic pin: input vref at 80% */
5247         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5248         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5249         /* Line In pin: input */
5250         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5251         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5252         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5253         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5254         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5255         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5256         /* CD pin widget for input */
5257         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5258
5259         /* FIXME: use matrix-type input source selection */
5260         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5261         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5262         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5263         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5264         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5265         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5266         /* Input mixer2 */
5267         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5268         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5269         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5270         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5271         /* Input mixer3 */
5272         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5273         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5274         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5275         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5276         /* ADC1: mute amp left and right */
5277         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5278         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5279         /* ADC2: mute amp left and right */
5280         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5281         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5282         /* ADC3: mute amp left and right */
5283         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5284         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5285
5286         { }
5287 };
5288
5289 static struct hda_verb alc882_eapd_verbs[] = {
5290         /* change to EAPD mode */
5291         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5292         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5293         { }
5294 };
5295
5296 /* Mac Pro test */
5297 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5298         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5299         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5300         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5301         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5302         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5303         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5304         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5305         { } /* end */
5306 };
5307
5308 static struct hda_verb alc882_macpro_init_verbs[] = {
5309         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5310         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5311         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5312         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5313         /* Front Pin: output 0 (0x0c) */
5314         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5315         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5316         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5317         /* Front Mic pin: input vref at 80% */
5318         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5319         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5320         /* Speaker:  output */
5321         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5322         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5323         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5324         /* Headphone output (output 0 - 0x0c) */
5325         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5326         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5327         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5328
5329         /* FIXME: use matrix-type input source selection */
5330         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5331         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5332         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5333         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5334         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5335         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5336         /* Input mixer2 */
5337         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5338         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5339         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5340         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5341         /* Input mixer3 */
5342         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5343         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5344         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5345         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5346         /* ADC1: mute amp left and right */
5347         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5348         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5349         /* ADC2: mute amp left and right */
5350         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5351         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5352         /* ADC3: mute amp left and right */
5353         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5354         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5355
5356         { }
5357 };
5358
5359 /* Macbook Pro rev3 */
5360 static struct hda_verb alc885_mbp3_init_verbs[] = {
5361         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5362         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5363         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5364         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5365         /* Rear mixer */
5366         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5367         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5368         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5369         /* Front Pin: output 0 (0x0c) */
5370         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5371         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5372         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5373         /* HP Pin: output 0 (0x0d) */
5374         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5375         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5376         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5377         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5378         /* Mic (rear) pin: input vref at 80% */
5379         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5380         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5381         /* Front Mic pin: input vref at 80% */
5382         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5383         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5384         /* Line In pin: use output 1 when in LineOut mode */
5385         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5386         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5387         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5388
5389         /* FIXME: use matrix-type input source selection */
5390         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5391         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5392         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5393         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5394         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5395         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5396         /* Input mixer2 */
5397         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5398         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5399         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5400         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5401         /* Input mixer3 */
5402         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5403         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5404         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5405         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5406         /* ADC1: mute amp left and right */
5407         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5408         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5409         /* ADC2: mute amp left and right */
5410         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5411         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5412         /* ADC3: mute amp left and right */
5413         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5414         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5415
5416         { }
5417 };
5418
5419 /* iMac 24 mixer. */
5420 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5421         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5422         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5423         { } /* end */
5424 };
5425
5426 /* iMac 24 init verbs. */
5427 static struct hda_verb alc885_imac24_init_verbs[] = {
5428         /* Internal speakers: output 0 (0x0c) */
5429         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5430         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5431         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5432         /* Internal speakers: output 0 (0x0c) */
5433         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5434         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5435         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5436         /* Headphone: output 0 (0x0c) */
5437         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5438         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5439         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5440         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5441         /* Front Mic: input vref at 80% */
5442         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5443         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5444         { }
5445 };
5446
5447 /* Toggle speaker-output according to the hp-jack state */
5448 static void alc885_imac24_automute(struct hda_codec *codec)
5449 {
5450         unsigned int present;
5451
5452         present = snd_hda_codec_read(codec, 0x14, 0,
5453                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5454         snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5455                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5456         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5457                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5458 }
5459
5460 /* Processes unsolicited events. */
5461 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5462                                       unsigned int res)
5463 {
5464         /* Headphone insertion or removal. */
5465         if ((res >> 26) == ALC880_HP_EVENT)
5466                 alc885_imac24_automute(codec);
5467 }
5468
5469 static void alc885_mbp3_automute(struct hda_codec *codec)
5470 {
5471         unsigned int present;
5472
5473         present = snd_hda_codec_read(codec, 0x15, 0,
5474                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5475         snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5476                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5477         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5478                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5479
5480 }
5481 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5482                                     unsigned int res)
5483 {
5484         /* Headphone insertion or removal. */
5485         if ((res >> 26) == ALC880_HP_EVENT)
5486                 alc885_mbp3_automute(codec);
5487 }
5488
5489
5490 static struct hda_verb alc882_targa_verbs[] = {
5491         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5492         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5493
5494         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5495         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5496         
5497         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5498         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5499         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5500
5501         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5502         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5503         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5504         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5505         { } /* end */
5506 };
5507
5508 /* toggle speaker-output according to the hp-jack state */
5509 static void alc882_targa_automute(struct hda_codec *codec)
5510 {
5511         unsigned int present;
5512  
5513         present = snd_hda_codec_read(codec, 0x14, 0,
5514                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5515         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5516                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5517         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5518                                   present ? 1 : 3);
5519 }
5520
5521 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5522 {
5523         /* Looks like the unsol event is incompatible with the standard
5524          * definition.  4bit tag is placed at 26 bit!
5525          */
5526         if (((res >> 26) == ALC880_HP_EVENT)) {
5527                 alc882_targa_automute(codec);
5528         }
5529 }
5530
5531 static struct hda_verb alc882_asus_a7j_verbs[] = {
5532         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5533         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5534
5535         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5536         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5537         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5538         
5539         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5540         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5541         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5542
5543         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5544         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5545         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5546         { } /* end */
5547 };
5548
5549 static struct hda_verb alc882_asus_a7m_verbs[] = {
5550         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5551         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5552
5553         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5554         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5555         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5556         
5557         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5558         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5559         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5560
5561         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5562         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5563         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5564         { } /* end */
5565 };
5566
5567 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5568 {
5569         unsigned int gpiostate, gpiomask, gpiodir;
5570
5571         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5572                                        AC_VERB_GET_GPIO_DATA, 0);
5573
5574         if (!muted)
5575                 gpiostate |= (1 << pin);
5576         else
5577                 gpiostate &= ~(1 << pin);
5578
5579         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5580                                       AC_VERB_GET_GPIO_MASK, 0);
5581         gpiomask |= (1 << pin);
5582
5583         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5584                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5585         gpiodir |= (1 << pin);
5586
5587
5588         snd_hda_codec_write(codec, codec->afg, 0,
5589                             AC_VERB_SET_GPIO_MASK, gpiomask);
5590         snd_hda_codec_write(codec, codec->afg, 0,
5591                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5592
5593         msleep(1);
5594
5595         snd_hda_codec_write(codec, codec->afg, 0,
5596                             AC_VERB_SET_GPIO_DATA, gpiostate);
5597 }
5598
5599 /* set up GPIO at initialization */
5600 static void alc885_macpro_init_hook(struct hda_codec *codec)
5601 {
5602         alc882_gpio_mute(codec, 0, 0);
5603         alc882_gpio_mute(codec, 1, 0);
5604 }
5605
5606 /* set up GPIO and update auto-muting at initialization */
5607 static void alc885_imac24_init_hook(struct hda_codec *codec)
5608 {
5609         alc885_macpro_init_hook(codec);
5610         alc885_imac24_automute(codec);
5611 }
5612
5613 /*
5614  * generic initialization of ADC, input mixers and output mixers
5615  */
5616 static struct hda_verb alc882_auto_init_verbs[] = {
5617         /*
5618          * Unmute ADC0-2 and set the default input to mic-in
5619          */
5620         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5621         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5622         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5623         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5624         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5625         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5626
5627         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5628          * mixer widget
5629          * Note: PASD motherboards uses the Line In 2 as the input for
5630          * front panel mic (mic 2)
5631          */
5632         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5633         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5634         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5635         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5636         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5637         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5638
5639         /*
5640          * Set up output mixers (0x0c - 0x0f)
5641          */
5642         /* set vol=0 to output mixers */
5643         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5644         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5645         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5646         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5647         /* set up input amps for analog loopback */
5648         /* Amp Indices: DAC = 0, mixer = 1 */
5649         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5650         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5651         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5652         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5653         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5654         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5655         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5656         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5657         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5658         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5659
5660         /* FIXME: use matrix-type input source selection */
5661         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5662         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5663         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5664         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5665         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5666         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5667         /* Input mixer2 */
5668         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5669         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5670         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5671         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5672         /* Input mixer3 */
5673         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5674         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5675         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5676         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5677
5678         { }
5679 };
5680
5681 /* capture mixer elements */
5682 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5683         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5684         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5685         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5686         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5687         {
5688                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5689                 /* The multiple "Capture Source" controls confuse alsamixer
5690                  * So call somewhat different..
5691                  * FIXME: the controls appear in the "playback" view!
5692                  */
5693                 /* .name = "Capture Source", */
5694                 .name = "Input Source",
5695                 .count = 2,
5696                 .info = alc882_mux_enum_info,
5697                 .get = alc882_mux_enum_get,
5698                 .put = alc882_mux_enum_put,
5699         },
5700         { } /* end */
5701 };
5702
5703 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5704         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5705         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5706         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5707         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5708         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5709         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5710         {
5711                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5712                 /* The multiple "Capture Source" controls confuse alsamixer
5713                  * So call somewhat different..
5714                  * FIXME: the controls appear in the "playback" view!
5715                  */
5716                 /* .name = "Capture Source", */
5717                 .name = "Input Source",
5718                 .count = 3,
5719                 .info = alc882_mux_enum_info,
5720                 .get = alc882_mux_enum_get,
5721                 .put = alc882_mux_enum_put,
5722         },
5723         { } /* end */
5724 };
5725
5726 #ifdef CONFIG_SND_HDA_POWER_SAVE
5727 #define alc882_loopbacks        alc880_loopbacks
5728 #endif
5729
5730 /* pcm configuration: identiacal with ALC880 */
5731 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5732 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5733 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5734 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5735
5736 /*
5737  * configuration and preset
5738  */
5739 static const char *alc882_models[ALC882_MODEL_LAST] = {
5740         [ALC882_3ST_DIG]        = "3stack-dig",
5741         [ALC882_6ST_DIG]        = "6stack-dig",
5742         [ALC882_ARIMA]          = "arima",
5743         [ALC882_W2JC]           = "w2jc",
5744         [ALC882_TARGA]          = "targa",
5745         [ALC882_ASUS_A7J]       = "asus-a7j",
5746         [ALC882_ASUS_A7M]       = "asus-a7m",
5747         [ALC885_MACPRO]         = "macpro",
5748         [ALC885_MBP3]           = "mbp3",
5749         [ALC885_IMAC24]         = "imac24",
5750         [ALC882_AUTO]           = "auto",
5751 };
5752
5753 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5754         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5755         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5756         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5757         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5758         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5759         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5760         SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
5761         SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
5762         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5763         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5764         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5765         {}
5766 };
5767
5768 static struct alc_config_preset alc882_presets[] = {
5769         [ALC882_3ST_DIG] = {
5770                 .mixers = { alc882_base_mixer },
5771                 .init_verbs = { alc882_init_verbs },
5772                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5773                 .dac_nids = alc882_dac_nids,
5774                 .dig_out_nid = ALC882_DIGOUT_NID,
5775                 .dig_in_nid = ALC882_DIGIN_NID,
5776                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5777                 .channel_mode = alc882_ch_modes,
5778                 .need_dac_fix = 1,
5779                 .input_mux = &alc882_capture_source,
5780         },
5781         [ALC882_6ST_DIG] = {
5782                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5783                 .init_verbs = { alc882_init_verbs },
5784                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5785                 .dac_nids = alc882_dac_nids,
5786                 .dig_out_nid = ALC882_DIGOUT_NID,
5787                 .dig_in_nid = ALC882_DIGIN_NID,
5788                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5789                 .channel_mode = alc882_sixstack_modes,
5790                 .input_mux = &alc882_capture_source,
5791         },
5792         [ALC882_ARIMA] = {
5793                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5794                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5795                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5796                 .dac_nids = alc882_dac_nids,
5797                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5798                 .channel_mode = alc882_sixstack_modes,
5799                 .input_mux = &alc882_capture_source,
5800         },
5801         [ALC882_W2JC] = {
5802                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5803                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5804                                 alc880_gpio1_init_verbs },
5805                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5806                 .dac_nids = alc882_dac_nids,
5807                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5808                 .channel_mode = alc880_threestack_modes,
5809                 .need_dac_fix = 1,
5810                 .input_mux = &alc882_capture_source,
5811                 .dig_out_nid = ALC882_DIGOUT_NID,
5812         },
5813         [ALC885_MBP3] = {
5814                 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5815                 .init_verbs = { alc885_mbp3_init_verbs,
5816                                 alc880_gpio1_init_verbs },
5817                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5818                 .dac_nids = alc882_dac_nids,
5819                 .channel_mode = alc885_mbp_6ch_modes,
5820                 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5821                 .input_mux = &alc882_capture_source,
5822                 .dig_out_nid = ALC882_DIGOUT_NID,
5823                 .dig_in_nid = ALC882_DIGIN_NID,
5824                 .unsol_event = alc885_mbp3_unsol_event,
5825                 .init_hook = alc885_mbp3_automute,
5826         },
5827         [ALC885_MACPRO] = {
5828                 .mixers = { alc882_macpro_mixer },
5829                 .init_verbs = { alc882_macpro_init_verbs },
5830                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5831                 .dac_nids = alc882_dac_nids,
5832                 .dig_out_nid = ALC882_DIGOUT_NID,
5833                 .dig_in_nid = ALC882_DIGIN_NID,
5834                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5835                 .channel_mode = alc882_ch_modes,
5836                 .input_mux = &alc882_capture_source,
5837                 .init_hook = alc885_macpro_init_hook,
5838         },
5839         [ALC885_IMAC24] = {
5840                 .mixers = { alc885_imac24_mixer },
5841                 .init_verbs = { alc885_imac24_init_verbs },
5842                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5843                 .dac_nids = alc882_dac_nids,
5844                 .dig_out_nid = ALC882_DIGOUT_NID,
5845                 .dig_in_nid = ALC882_DIGIN_NID,
5846                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5847                 .channel_mode = alc882_ch_modes,
5848                 .input_mux = &alc882_capture_source,
5849                 .unsol_event = alc885_imac24_unsol_event,
5850                 .init_hook = alc885_imac24_init_hook,
5851         },
5852         [ALC882_TARGA] = {
5853                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5854                             alc882_capture_mixer },
5855                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5856                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5857                 .dac_nids = alc882_dac_nids,
5858                 .dig_out_nid = ALC882_DIGOUT_NID,
5859                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5860                 .adc_nids = alc882_adc_nids,
5861                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5862                 .channel_mode = alc882_3ST_6ch_modes,
5863                 .need_dac_fix = 1,
5864                 .input_mux = &alc882_capture_source,
5865                 .unsol_event = alc882_targa_unsol_event,
5866                 .init_hook = alc882_targa_automute,
5867         },
5868         [ALC882_ASUS_A7J] = {
5869                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5870                             alc882_capture_mixer },
5871                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5872                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5873                 .dac_nids = alc882_dac_nids,
5874                 .dig_out_nid = ALC882_DIGOUT_NID,
5875                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5876                 .adc_nids = alc882_adc_nids,
5877                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5878                 .channel_mode = alc882_3ST_6ch_modes,
5879                 .need_dac_fix = 1,
5880                 .input_mux = &alc882_capture_source,
5881         },      
5882         [ALC882_ASUS_A7M] = {
5883                 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5884                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5885                                 alc880_gpio1_init_verbs,
5886                                 alc882_asus_a7m_verbs },
5887                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5888                 .dac_nids = alc882_dac_nids,
5889                 .dig_out_nid = ALC882_DIGOUT_NID,
5890                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5891                 .channel_mode = alc880_threestack_modes,
5892                 .need_dac_fix = 1,
5893                 .input_mux = &alc882_capture_source,
5894         },      
5895 };
5896
5897
5898 /*
5899  * Pin config fixes
5900  */
5901 enum { 
5902         PINFIX_ABIT_AW9D_MAX
5903 };
5904
5905 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5906         { 0x15, 0x01080104 }, /* side */
5907         { 0x16, 0x01011012 }, /* rear */
5908         { 0x17, 0x01016011 }, /* clfe */
5909         { }
5910 };
5911
5912 static const struct alc_pincfg *alc882_pin_fixes[] = {
5913         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5914 };
5915
5916 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5917         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5918         {}
5919 };
5920
5921 /*
5922  * BIOS auto configuration
5923  */
5924 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5925                                               hda_nid_t nid, int pin_type,
5926                                               int dac_idx)
5927 {
5928         /* set as output */
5929         struct alc_spec *spec = codec->spec;
5930         int idx;
5931
5932         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5933                 idx = 4;
5934         else
5935                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5936
5937         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5938                             pin_type);
5939         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5940                             AMP_OUT_UNMUTE);
5941         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5942
5943 }
5944
5945 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5946 {
5947         struct alc_spec *spec = codec->spec;
5948         int i;
5949
5950         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5951         for (i = 0; i <= HDA_SIDE; i++) {
5952                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5953                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5954                 if (nid)
5955                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5956                                                           i);
5957         }
5958 }
5959
5960 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5961 {
5962         struct alc_spec *spec = codec->spec;
5963         hda_nid_t pin;
5964
5965         pin = spec->autocfg.hp_pins[0];
5966         if (pin) /* connect to front */
5967                 /* use dac 0 */
5968                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5969 }
5970
5971 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5972 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5973
5974 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5975 {
5976         struct alc_spec *spec = codec->spec;
5977         int i;
5978
5979         for (i = 0; i < AUTO_PIN_LAST; i++) {
5980                 hda_nid_t nid = spec->autocfg.input_pins[i];
5981                 if (alc882_is_input_pin(nid)) {
5982                         snd_hda_codec_write(codec, nid, 0,
5983                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5984                                             i <= AUTO_PIN_FRONT_MIC ?
5985                                             PIN_VREF80 : PIN_IN);
5986                         if (nid != ALC882_PIN_CD_NID)
5987                                 snd_hda_codec_write(codec, nid, 0,
5988                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5989                                                     AMP_OUT_MUTE);
5990                 }
5991         }
5992 }
5993
5994 /* add mic boosts if needed */
5995 static int alc_auto_add_mic_boost(struct hda_codec *codec)
5996 {
5997         struct alc_spec *spec = codec->spec;
5998         int err;
5999         hda_nid_t nid;
6000
6001         nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6002         if (nid) {
6003                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6004                                   "Mic Boost",
6005                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6006                 if (err < 0)
6007                         return err;
6008         }
6009         nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6010         if (nid) {
6011                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6012                                   "Front Mic Boost",
6013                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6014                 if (err < 0)
6015                         return err;
6016         }
6017         return 0;
6018 }
6019
6020 /* almost identical with ALC880 parser... */
6021 static int alc882_parse_auto_config(struct hda_codec *codec)
6022 {
6023         struct alc_spec *spec = codec->spec;
6024         int err = alc880_parse_auto_config(codec);
6025
6026         if (err < 0)
6027                 return err;
6028         else if (!err)
6029                 return 0; /* no config found */
6030
6031         err = alc_auto_add_mic_boost(codec);
6032         if (err < 0)
6033                 return err;
6034
6035         /* hack - override the init verbs */
6036         spec->init_verbs[0] = alc882_auto_init_verbs;
6037
6038         return 1; /* config found */
6039 }
6040
6041 /* additional initialization for auto-configuration model */
6042 static void alc882_auto_init(struct hda_codec *codec)
6043 {
6044         alc882_auto_init_multi_out(codec);
6045         alc882_auto_init_hp_out(codec);
6046         alc882_auto_init_analog_input(codec);
6047 }
6048
6049 static int patch_alc882(struct hda_codec *codec)
6050 {
6051         struct alc_spec *spec;
6052         int err, board_config;
6053
6054         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6055         if (spec == NULL)
6056                 return -ENOMEM;
6057
6058         codec->spec = spec;
6059
6060         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6061                                                   alc882_models,
6062                                                   alc882_cfg_tbl);
6063
6064         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6065                 /* Pick up systems that don't supply PCI SSID */
6066                 switch (codec->subsystem_id) {
6067                 case 0x106b0c00: /* Mac Pro */
6068                         board_config = ALC885_MACPRO;
6069                         break;
6070                 case 0x106b1000: /* iMac 24 */
6071                         board_config = ALC885_IMAC24;
6072                         break;
6073                 case 0x106b2c00: /* Macbook Pro rev3 */
6074                         board_config = ALC885_MBP3;
6075                         break;
6076                 default:
6077                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6078                                          "trying auto-probe from BIOS...\n");
6079                         board_config = ALC882_AUTO;
6080                 }
6081         }
6082
6083         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6084
6085         if (board_config == ALC882_AUTO) {
6086                 /* automatic parse from the BIOS config */
6087                 err = alc882_parse_auto_config(codec);
6088                 if (err < 0) {
6089                         alc_free(codec);
6090                         return err;
6091                 } else if (!err) {
6092                         printk(KERN_INFO
6093                                "hda_codec: Cannot set up configuration "
6094                                "from BIOS.  Using base mode...\n");
6095                         board_config = ALC882_3ST_DIG;
6096                 }
6097         }
6098
6099         if (board_config != ALC882_AUTO)
6100                 setup_preset(spec, &alc882_presets[board_config]);
6101
6102         spec->stream_name_analog = "ALC882 Analog";
6103         spec->stream_analog_playback = &alc882_pcm_analog_playback;
6104         spec->stream_analog_capture = &alc882_pcm_analog_capture;
6105
6106         spec->stream_name_digital = "ALC882 Digital";
6107         spec->stream_digital_playback = &alc882_pcm_digital_playback;
6108         spec->stream_digital_capture = &alc882_pcm_digital_capture;
6109
6110         if (!spec->adc_nids && spec->input_mux) {
6111                 /* check whether NID 0x07 is valid */
6112                 unsigned int wcap = get_wcaps(codec, 0x07);
6113                 /* get type */
6114                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6115                 if (wcap != AC_WID_AUD_IN) {
6116                         spec->adc_nids = alc882_adc_nids_alt;
6117                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6118                         spec->mixers[spec->num_mixers] =
6119                                 alc882_capture_alt_mixer;
6120                         spec->num_mixers++;
6121                 } else {
6122                         spec->adc_nids = alc882_adc_nids;
6123                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6124                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6125                         spec->num_mixers++;
6126                 }
6127         }
6128
6129         codec->patch_ops = alc_patch_ops;
6130         if (board_config == ALC882_AUTO)
6131                 spec->init_hook = alc882_auto_init;
6132 #ifdef CONFIG_SND_HDA_POWER_SAVE
6133         if (!spec->loopback.amplist)
6134                 spec->loopback.amplist = alc882_loopbacks;
6135 #endif
6136
6137         return 0;
6138 }
6139
6140 /*
6141  * ALC883 support
6142  *
6143  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6144  * configuration.  Each pin widget can choose any input DACs and a mixer.
6145  * Each ADC is connected from a mixer of all inputs.  This makes possible
6146  * 6-channel independent captures.
6147  *
6148  * In addition, an independent DAC for the multi-playback (not used in this
6149  * driver yet).
6150  */
6151 #define ALC883_DIGOUT_NID       0x06
6152 #define ALC883_DIGIN_NID        0x0a
6153
6154 static hda_nid_t alc883_dac_nids[4] = {
6155         /* front, rear, clfe, rear_surr */
6156         0x02, 0x04, 0x03, 0x05
6157 };
6158
6159 static hda_nid_t alc883_adc_nids[2] = {
6160         /* ADC1-2 */
6161         0x08, 0x09,
6162 };
6163
6164 /* input MUX */
6165 /* FIXME: should be a matrix-type input source selection */
6166
6167 static struct hda_input_mux alc883_capture_source = {
6168         .num_items = 4,
6169         .items = {
6170                 { "Mic", 0x0 },
6171                 { "Front Mic", 0x1 },
6172                 { "Line", 0x2 },
6173                 { "CD", 0x4 },
6174         },
6175 };
6176
6177 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6178         .num_items = 2,
6179         .items = {
6180                 { "Mic", 0x1 },
6181                 { "Line", 0x2 },
6182         },
6183 };
6184
6185 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6186         .num_items = 4,
6187         .items = {
6188                 { "Mic", 0x0 },
6189                 { "iMic", 0x1 },
6190                 { "Line", 0x2 },
6191                 { "CD", 0x4 },
6192         },
6193 };
6194
6195 #define alc883_mux_enum_info alc_mux_enum_info
6196 #define alc883_mux_enum_get alc_mux_enum_get
6197
6198 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6199                                struct snd_ctl_elem_value *ucontrol)
6200 {
6201         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6202         struct alc_spec *spec = codec->spec;
6203         const struct hda_input_mux *imux = spec->input_mux;
6204         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6205         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6206         hda_nid_t nid = capture_mixers[adc_idx];
6207         unsigned int *cur_val = &spec->cur_mux[adc_idx];
6208         unsigned int i, idx;
6209
6210         idx = ucontrol->value.enumerated.item[0];
6211         if (idx >= imux->num_items)
6212                 idx = imux->num_items - 1;
6213         if (*cur_val == idx)
6214                 return 0;
6215         for (i = 0; i < imux->num_items; i++) {
6216                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6217                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6218                                          imux->items[i].index,
6219                                          HDA_AMP_MUTE, v);
6220         }
6221         *cur_val = idx;
6222         return 1;
6223 }
6224
6225 /*
6226  * 2ch mode
6227  */
6228 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6229         { 2, NULL }
6230 };
6231
6232 /*
6233  * 2ch mode
6234  */
6235 static struct hda_verb alc883_3ST_ch2_init[] = {
6236         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6237         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6238         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6239         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6240         { } /* end */
6241 };
6242
6243 /*
6244  * 4ch mode
6245  */
6246 static struct hda_verb alc883_3ST_ch4_init[] = {
6247         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6248         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6249         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6250         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6251         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6252         { } /* end */
6253 };
6254
6255 /*
6256  * 6ch mode
6257  */
6258 static struct hda_verb alc883_3ST_ch6_init[] = {
6259         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6260         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6261         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6262         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6263         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6264         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6265         { } /* end */
6266 };
6267
6268 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6269         { 2, alc883_3ST_ch2_init },
6270         { 4, alc883_3ST_ch4_init },
6271         { 6, alc883_3ST_ch6_init },
6272 };
6273
6274 /*
6275  * 6ch mode
6276  */
6277 static struct hda_verb alc883_sixstack_ch6_init[] = {
6278         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6279         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6280         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6281         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6282         { } /* end */
6283 };
6284
6285 /*
6286  * 8ch mode
6287  */
6288 static struct hda_verb alc883_sixstack_ch8_init[] = {
6289         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6290         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6291         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6292         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6293         { } /* end */
6294 };
6295
6296 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6297         { 6, alc883_sixstack_ch6_init },
6298         { 8, alc883_sixstack_ch8_init },
6299 };
6300
6301 static struct hda_verb alc883_medion_eapd_verbs[] = {
6302         /* eanable EAPD on medion laptop */
6303         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6304         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6305         { }
6306 };
6307
6308 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6309  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6310  */
6311
6312 static struct snd_kcontrol_new alc883_base_mixer[] = {
6313         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6314         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6315         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6316         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6317         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6318         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6319         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6320         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6321         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6322         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6323         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6324         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6325         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6326         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6327         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6328         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6329         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6330         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6331         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6332         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6333         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6334         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6335         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6336         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6337         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6338         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6339         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6340         {
6341                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6342                 /* .name = "Capture Source", */
6343                 .name = "Input Source",
6344                 .count = 2,
6345                 .info = alc883_mux_enum_info,
6346                 .get = alc883_mux_enum_get,
6347                 .put = alc883_mux_enum_put,
6348         },
6349         { } /* end */
6350 };
6351
6352 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6353         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6354         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6355         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6356         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6357         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6358         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6359         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6360         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6361         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6362         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6363         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6364         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6365         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6366         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6367         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6368         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6369         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6370         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6371         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6372         {
6373                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6374                 /* .name = "Capture Source", */
6375                 .name = "Input Source",
6376                 .count = 2,
6377                 .info = alc883_mux_enum_info,
6378                 .get = alc883_mux_enum_get,
6379                 .put = alc883_mux_enum_put,
6380         },
6381         { } /* end */
6382 };
6383
6384 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6385         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6386         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6387         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6388         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6389         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6390         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6391         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6392         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6393         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6394         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6395         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6396         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6397         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6398         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6399         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6400         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6401         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6402         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6403         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6404         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6405         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6406         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6407         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6408         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6409         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6410         {
6411                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6412                 /* .name = "Capture Source", */
6413                 .name = "Input Source",
6414                 .count = 2,
6415                 .info = alc883_mux_enum_info,
6416                 .get = alc883_mux_enum_get,
6417                 .put = alc883_mux_enum_put,
6418         },
6419         { } /* end */
6420 };
6421
6422 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6423         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6424         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6425         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6426         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6427         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6428         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6429         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6430         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6431         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6432         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6433         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6434         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6435         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6436         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6437         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6438         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6439         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6440         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6441         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6442         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6443         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6444         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6445         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6446
6447         {
6448                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6449                 /* .name = "Capture Source", */
6450                 .name = "Input Source",
6451                 .count = 1,
6452                 .info = alc883_mux_enum_info,
6453                 .get = alc883_mux_enum_get,
6454                 .put = alc883_mux_enum_put,
6455         },
6456         { } /* end */
6457 };
6458
6459 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6460         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6461         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6462         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6463         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6464         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6465         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6466         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6467         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6468         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6469         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6470         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6471         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6472         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6473         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6474         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6475         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6476         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6477         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6478         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6479         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6480         {
6481                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6482                 /* .name = "Capture Source", */
6483                 .name = "Input Source",
6484                 .count = 2,
6485                 .info = alc883_mux_enum_info,
6486                 .get = alc883_mux_enum_get,
6487                 .put = alc883_mux_enum_put,
6488         },
6489         { } /* end */
6490 };
6491
6492 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6493         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6494         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6495         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6496         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6497         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6498         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6499         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6500         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6501         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6502         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6503         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6504         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6505         {
6506                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6507                 /* .name = "Capture Source", */
6508                 .name = "Input Source",
6509                 .count = 2,
6510                 .info = alc883_mux_enum_info,
6511                 .get = alc883_mux_enum_get,
6512                 .put = alc883_mux_enum_put,
6513         },
6514         { } /* end */
6515 };
6516
6517 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6518         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6519         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6520         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6521         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6522         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6523         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6524         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6525         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6526         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6527         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6528         {
6529                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6530                 /* .name = "Capture Source", */
6531                 .name = "Input Source",
6532                 .count = 1,
6533                 .info = alc883_mux_enum_info,
6534                 .get = alc883_mux_enum_get,
6535                 .put = alc883_mux_enum_put,
6536         },
6537         { } /* end */
6538 };
6539
6540 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6541         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6542         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6543         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6544         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6545         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6546         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6547         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6548         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6549         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6550         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6551         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6552         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6553         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6554         {
6555                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6556                 /* .name = "Capture Source", */
6557                 .name = "Input Source",
6558                 .count = 2,
6559                 .info = alc883_mux_enum_info,
6560                 .get = alc883_mux_enum_get,
6561                 .put = alc883_mux_enum_put,
6562         },
6563         { } /* end */
6564 };
6565
6566 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6567         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6568         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6569         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6570         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6571         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6572         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6573         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6574         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6575         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6576         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6577         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6578         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6579         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6580         {
6581                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6582                 /* .name = "Capture Source", */
6583                 .name = "Input Source",
6584                 .count = 2,
6585                 .info = alc883_mux_enum_info,
6586                 .get = alc883_mux_enum_get,
6587                 .put = alc883_mux_enum_put,
6588         },
6589         { } /* end */
6590 };      
6591
6592 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6593         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6594         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6595         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6596         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6597         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6598         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6599         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6600         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6601         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6602         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6603         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6604         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6605         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6606         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6607         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6608         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6609         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6610         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6611         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6612         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6613         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6614         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6615         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6616         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6617         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6618         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6619         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6620         {
6621                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6622                 /* .name = "Capture Source", */
6623                 .name = "Input Source",
6624                 .count = 2,
6625                 .info = alc883_mux_enum_info,
6626                 .get = alc883_mux_enum_get,
6627                 .put = alc883_mux_enum_put,
6628         },
6629         { } /* end */
6630 };
6631
6632 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6633         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6634         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6635         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6636         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6637         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6638         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6639         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6640         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6641         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6642         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6643         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6644         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6645         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6646         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6647         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6648         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6649         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6650         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6651         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6652         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6653         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6654         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6655         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6656         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6657         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6658         {
6659                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6660                 /* .name = "Capture Source", */
6661                 .name = "Input Source",
6662                 .count = 2,
6663                 .info = alc883_mux_enum_info,
6664                 .get = alc883_mux_enum_get,
6665                 .put = alc883_mux_enum_put,
6666         },
6667         { } /* end */
6668 };
6669
6670 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6671         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6672         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6673         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6674         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6675         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6676         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6677         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6678         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6679         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6680         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6681         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6682         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6683         {
6684                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6685                 /* .name = "Capture Source", */
6686                 .name = "Input Source",
6687                 .count = 2,
6688                 .info = alc883_mux_enum_info,
6689                 .get = alc883_mux_enum_get,
6690                 .put = alc883_mux_enum_put,
6691         },
6692         { } /* end */
6693 };
6694
6695 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6696         {
6697                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6698                 .name = "Channel Mode",
6699                 .info = alc_ch_mode_info,
6700                 .get = alc_ch_mode_get,
6701                 .put = alc_ch_mode_put,
6702         },
6703         { } /* end */
6704 };
6705
6706 static struct hda_verb alc883_init_verbs[] = {
6707         /* ADC1: mute amp left and right */
6708         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6709         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6710         /* ADC2: mute amp left and right */
6711         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6712         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6713         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6714         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6715         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6716         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6717         /* Rear mixer */
6718         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6719         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6720         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6721         /* CLFE mixer */
6722         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6723         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6724         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6725         /* Side mixer */
6726         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6727         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6728         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6729
6730         /* mute analog input loopbacks */
6731         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6732         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6733         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6734         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6735         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6736
6737         /* Front Pin: output 0 (0x0c) */
6738         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6739         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6740         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6741         /* Rear Pin: output 1 (0x0d) */
6742         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6743         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6744         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6745         /* CLFE Pin: output 2 (0x0e) */
6746         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6747         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6748         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6749         /* Side Pin: output 3 (0x0f) */
6750         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6751         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6752         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6753         /* Mic (rear) pin: input vref at 80% */
6754         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6755         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6756         /* Front Mic pin: input vref at 80% */
6757         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6758         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6759         /* Line In pin: input */
6760         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6761         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6762         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6763         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6764         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6765         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6766         /* CD pin widget for input */
6767         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6768
6769         /* FIXME: use matrix-type input source selection */
6770         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6771         /* Input mixer2 */
6772         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6773         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6774         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6775         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6776         /* Input mixer3 */
6777         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6778         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6779         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6780         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6781         { }
6782 };
6783
6784 static struct hda_verb alc883_tagra_verbs[] = {
6785         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6786         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6787
6788         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6789         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6790         
6791         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6792         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6793         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6794
6795         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6796         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6797         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6798         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6799
6800         { } /* end */
6801 };
6802
6803 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6804         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6805         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6806         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6807         { } /* end */
6808 };
6809
6810 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6811         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6812         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6813         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6814         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6815         { } /* end */
6816 };
6817
6818 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6819         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6820         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6821         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6822         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6823         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6824         { } /* end */
6825 };
6826
6827 static struct hda_verb alc883_haier_w66_verbs[] = {
6828         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6829         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6830
6831         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6832
6833         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6834         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6835         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6836         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6837         { } /* end */
6838 };
6839
6840 static struct hda_verb alc888_6st_hp_verbs[] = {
6841         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6842         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6843         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6844         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6845         { }
6846 };
6847
6848 static struct hda_verb alc888_3st_hp_verbs[] = {
6849         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6850         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6851         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6852         { }
6853 };
6854
6855 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6856         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6857         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6858         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6859         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6860         { }
6861 };
6862
6863 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6864         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6865         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6866         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6867         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6868         { }
6869 };
6870
6871 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6872         { 2, alc888_3st_hp_2ch_init },
6873         { 6, alc888_3st_hp_6ch_init },
6874 };
6875
6876 /* toggle front-jack and RCA according to the hp-jack state */
6877 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6878 {
6879         unsigned int present;
6880  
6881         present = snd_hda_codec_read(codec, 0x1b, 0,
6882                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6883         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6884                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6885         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6886                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6887 }
6888
6889 /* toggle RCA according to the front-jack state */
6890 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6891 {
6892         unsigned int present;
6893  
6894         present = snd_hda_codec_read(codec, 0x14, 0,
6895                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6896         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6897                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6898 }
6899
6900 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6901                                              unsigned int res)
6902 {
6903         if ((res >> 26) == ALC880_HP_EVENT)
6904                 alc888_lenovo_ms7195_front_automute(codec);
6905         if ((res >> 26) == ALC880_FRONT_EVENT)
6906                 alc888_lenovo_ms7195_rca_automute(codec);
6907 }
6908
6909 static struct hda_verb alc883_medion_md2_verbs[] = {
6910         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6911         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6912
6913         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6914
6915         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6916         { } /* end */
6917 };
6918
6919 /* toggle speaker-output according to the hp-jack state */
6920 static void alc883_medion_md2_automute(struct hda_codec *codec)
6921 {
6922         unsigned int present;
6923  
6924         present = snd_hda_codec_read(codec, 0x14, 0,
6925                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6926         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6927                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6928 }
6929
6930 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6931                                           unsigned int res)
6932 {
6933         if ((res >> 26) == ALC880_HP_EVENT)
6934                 alc883_medion_md2_automute(codec);
6935 }
6936
6937 /* toggle speaker-output according to the hp-jack state */
6938 static void alc883_tagra_automute(struct hda_codec *codec)
6939 {
6940         unsigned int present;
6941         unsigned char bits;
6942
6943         present = snd_hda_codec_read(codec, 0x14, 0,
6944                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6945         bits = present ? HDA_AMP_MUTE : 0;
6946         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6947                                  HDA_AMP_MUTE, bits);
6948         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6949                                   present ? 1 : 3);
6950 }
6951
6952 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6953 {
6954         if ((res >> 26) == ALC880_HP_EVENT)
6955                 alc883_tagra_automute(codec);
6956 }
6957
6958 static void alc883_haier_w66_automute(struct hda_codec *codec)
6959 {
6960         unsigned int present;
6961         unsigned char bits;
6962
6963         present = snd_hda_codec_read(codec, 0x1b, 0,
6964                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6965         bits = present ? 0x80 : 0;
6966         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6967                                  0x80, bits);
6968 }
6969
6970 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
6971                                          unsigned int res)
6972 {
6973         if ((res >> 26) == ALC880_HP_EVENT)
6974                 alc883_haier_w66_automute(codec);
6975 }
6976
6977 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6978 {
6979         unsigned int present;
6980         unsigned char bits;
6981
6982         present = snd_hda_codec_read(codec, 0x14, 0,
6983                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6984         bits = present ? HDA_AMP_MUTE : 0;
6985         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6986                                  HDA_AMP_MUTE, bits);
6987 }
6988
6989 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6990 {
6991         unsigned int present;
6992         unsigned char bits;
6993
6994         present = snd_hda_codec_read(codec, 0x1b, 0,
6995                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6996         bits = present ? HDA_AMP_MUTE : 0;
6997         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6998                                  HDA_AMP_MUTE, bits);
6999         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7000                                  HDA_AMP_MUTE, bits);
7001 }
7002
7003 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7004                                            unsigned int res)
7005 {
7006         if ((res >> 26) == ALC880_HP_EVENT)
7007                 alc883_lenovo_101e_all_automute(codec);
7008         if ((res >> 26) == ALC880_FRONT_EVENT)
7009                 alc883_lenovo_101e_ispeaker_automute(codec);
7010 }
7011
7012 /* toggle speaker-output according to the hp-jack state */
7013 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7014 {
7015         unsigned int present;
7016  
7017         present = snd_hda_codec_read(codec, 0x14, 0,
7018                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7019         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7020                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7021         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7022                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7023 }
7024
7025 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7026                                            unsigned int res)
7027 {
7028         if ((res >> 26) == ALC880_HP_EVENT)
7029                 alc883_acer_aspire_automute(codec);
7030 }
7031
7032 static struct hda_verb alc883_acer_eapd_verbs[] = {
7033         /* HP Pin: output 0 (0x0c) */
7034         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7035         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7036         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7037         /* Front Pin: output 0 (0x0c) */
7038         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7039         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7040         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7041         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7042         /* eanable EAPD on medion laptop */
7043         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7044         {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7045         /* enable unsolicited event */
7046         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7047         { }
7048 };
7049
7050 /*
7051  * generic initialization of ADC, input mixers and output mixers
7052  */
7053 static struct hda_verb alc883_auto_init_verbs[] = {
7054         /*
7055          * Unmute ADC0-2 and set the default input to mic-in
7056          */
7057         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7058         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7059         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7060         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7061
7062         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7063          * mixer widget
7064          * Note: PASD motherboards uses the Line In 2 as the input for
7065          * front panel mic (mic 2)
7066          */
7067         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7068         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7069         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7070         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7071         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7072         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7073
7074         /*
7075          * Set up output mixers (0x0c - 0x0f)
7076          */
7077         /* set vol=0 to output mixers */
7078         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7079         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7080         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7081         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7082         /* set up input amps for analog loopback */
7083         /* Amp Indices: DAC = 0, mixer = 1 */
7084         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7085         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7086         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7087         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7088         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7089         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7090         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7091         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7092         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7093         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7094
7095         /* FIXME: use matrix-type input source selection */
7096         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7097         /* Input mixer1 */
7098         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7099         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7100         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7101         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7102         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7103         /* Input mixer2 */
7104         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7105         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7106         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7107         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7108         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7109
7110         { }
7111 };
7112
7113 /* capture mixer elements */
7114 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7115         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7116         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7117         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7118         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7119         {
7120                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7121                 /* The multiple "Capture Source" controls confuse alsamixer
7122                  * So call somewhat different..
7123                  * FIXME: the controls appear in the "playback" view!
7124                  */
7125                 /* .name = "Capture Source", */
7126                 .name = "Input Source",
7127                 .count = 2,
7128                 .info = alc882_mux_enum_info,
7129                 .get = alc882_mux_enum_get,
7130                 .put = alc882_mux_enum_put,
7131         },
7132         { } /* end */
7133 };
7134
7135 #ifdef CONFIG_SND_HDA_POWER_SAVE
7136 #define alc883_loopbacks        alc880_loopbacks
7137 #endif
7138
7139 /* pcm configuration: identiacal with ALC880 */
7140 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
7141 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
7142 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
7143 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
7144
7145 /*
7146  * configuration and preset
7147  */
7148 static const char *alc883_models[ALC883_MODEL_LAST] = {
7149         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
7150         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
7151         [ALC883_3ST_6ch]        = "3stack-6ch",
7152         [ALC883_6ST_DIG]        = "6stack-dig",
7153         [ALC883_TARGA_DIG]      = "targa-dig",
7154         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
7155         [ALC883_ACER]           = "acer",
7156         [ALC883_ACER_ASPIRE]    = "acer-aspire",
7157         [ALC883_MEDION]         = "medion",
7158         [ALC883_MEDION_MD2]     = "medion-md2",
7159         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
7160         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7161         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
7162         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7163         [ALC883_HAIER_W66]      = "haier-w66",
7164         [ALC888_6ST_HP]         = "6stack-hp",
7165         [ALC888_3ST_HP]         = "3stack-hp",
7166         [ALC883_AUTO]           = "auto",
7167 };
7168
7169 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7170         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7171         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7172         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7173         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7174         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7175         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7176         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7177         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7178         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7179         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7180         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7181         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7182         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7183         SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7184         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7185         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7186         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7187         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7188         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7189         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7190         SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7191         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7192         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7193         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7194         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7195         SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7196         SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7197         SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7198         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
7199         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7200         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7201         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7202         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7203         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7204         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7205         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7206         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7207         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7208         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7209         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7210         SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7211         SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7212         SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7213         SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7214         {}
7215 };
7216
7217 static struct alc_config_preset alc883_presets[] = {
7218         [ALC883_3ST_2ch_DIG] = {
7219                 .mixers = { alc883_3ST_2ch_mixer },
7220                 .init_verbs = { alc883_init_verbs },
7221                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7222                 .dac_nids = alc883_dac_nids,
7223                 .dig_out_nid = ALC883_DIGOUT_NID,
7224                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7225                 .adc_nids = alc883_adc_nids,
7226                 .dig_in_nid = ALC883_DIGIN_NID,
7227                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7228                 .channel_mode = alc883_3ST_2ch_modes,
7229                 .input_mux = &alc883_capture_source,
7230         },
7231         [ALC883_3ST_6ch_DIG] = {
7232                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7233                 .init_verbs = { alc883_init_verbs },
7234                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7235                 .dac_nids = alc883_dac_nids,
7236                 .dig_out_nid = ALC883_DIGOUT_NID,
7237                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7238                 .adc_nids = alc883_adc_nids,
7239                 .dig_in_nid = ALC883_DIGIN_NID,
7240                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7241                 .channel_mode = alc883_3ST_6ch_modes,
7242                 .need_dac_fix = 1,
7243                 .input_mux = &alc883_capture_source,
7244         },
7245         [ALC883_3ST_6ch] = {
7246                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7247                 .init_verbs = { alc883_init_verbs },
7248                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7249                 .dac_nids = alc883_dac_nids,
7250                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7251                 .adc_nids = alc883_adc_nids,
7252                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7253                 .channel_mode = alc883_3ST_6ch_modes,
7254                 .need_dac_fix = 1,
7255                 .input_mux = &alc883_capture_source,
7256         },
7257         [ALC883_6ST_DIG] = {
7258                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7259                 .init_verbs = { alc883_init_verbs },
7260                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7261                 .dac_nids = alc883_dac_nids,
7262                 .dig_out_nid = ALC883_DIGOUT_NID,
7263                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7264                 .adc_nids = alc883_adc_nids,
7265                 .dig_in_nid = ALC883_DIGIN_NID,
7266                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7267                 .channel_mode = alc883_sixstack_modes,
7268                 .input_mux = &alc883_capture_source,
7269         },
7270         [ALC883_TARGA_DIG] = {
7271                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7272                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7273                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7274                 .dac_nids = alc883_dac_nids,
7275                 .dig_out_nid = ALC883_DIGOUT_NID,
7276                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7277                 .adc_nids = alc883_adc_nids,
7278                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7279                 .channel_mode = alc883_3ST_6ch_modes,
7280                 .need_dac_fix = 1,
7281                 .input_mux = &alc883_capture_source,
7282                 .unsol_event = alc883_tagra_unsol_event,
7283                 .init_hook = alc883_tagra_automute,
7284         },
7285         [ALC883_TARGA_2ch_DIG] = {
7286                 .mixers = { alc883_tagra_2ch_mixer},
7287                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7288                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7289                 .dac_nids = alc883_dac_nids,
7290                 .dig_out_nid = ALC883_DIGOUT_NID,
7291                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7292                 .adc_nids = alc883_adc_nids,
7293                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7294                 .channel_mode = alc883_3ST_2ch_modes,
7295                 .input_mux = &alc883_capture_source,
7296                 .unsol_event = alc883_tagra_unsol_event,
7297                 .init_hook = alc883_tagra_automute,
7298         },
7299         [ALC883_ACER] = {
7300                 .mixers = { alc883_base_mixer },
7301                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7302                  * and the headphone jack.  Turn this on and rely on the
7303                  * standard mute methods whenever the user wants to turn
7304                  * these outputs off.
7305                  */
7306                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7307                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7308                 .dac_nids = alc883_dac_nids,
7309                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7310                 .adc_nids = alc883_adc_nids,
7311                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7312                 .channel_mode = alc883_3ST_2ch_modes,
7313                 .input_mux = &alc883_capture_source,
7314         },
7315         [ALC883_ACER_ASPIRE] = {
7316                 .mixers = { alc883_acer_aspire_mixer },
7317                 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7318                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7319                 .dac_nids = alc883_dac_nids,
7320                 .dig_out_nid = ALC883_DIGOUT_NID,
7321                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7322                 .adc_nids = alc883_adc_nids,
7323                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7324                 .channel_mode = alc883_3ST_2ch_modes,
7325                 .input_mux = &alc883_capture_source,
7326                 .unsol_event = alc883_acer_aspire_unsol_event,
7327                 .init_hook = alc883_acer_aspire_automute,
7328         },
7329         [ALC883_MEDION] = {
7330                 .mixers = { alc883_fivestack_mixer,
7331                             alc883_chmode_mixer },
7332                 .init_verbs = { alc883_init_verbs,
7333                                 alc883_medion_eapd_verbs },
7334                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7335                 .dac_nids = alc883_dac_nids,
7336                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7337                 .adc_nids = alc883_adc_nids,
7338                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7339                 .channel_mode = alc883_sixstack_modes,
7340                 .input_mux = &alc883_capture_source,
7341         },
7342         [ALC883_MEDION_MD2] = {
7343                 .mixers = { alc883_medion_md2_mixer},
7344                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7345                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7346                 .dac_nids = alc883_dac_nids,
7347                 .dig_out_nid = ALC883_DIGOUT_NID,
7348                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7349                 .adc_nids = alc883_adc_nids,
7350                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7351                 .channel_mode = alc883_3ST_2ch_modes,
7352                 .input_mux = &alc883_capture_source,
7353                 .unsol_event = alc883_medion_md2_unsol_event,
7354                 .init_hook = alc883_medion_md2_automute,
7355         },      
7356         [ALC883_LAPTOP_EAPD] = {
7357                 .mixers = { alc883_base_mixer },
7358                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7359                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7360                 .dac_nids = alc883_dac_nids,
7361                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7362                 .adc_nids = alc883_adc_nids,
7363                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7364                 .channel_mode = alc883_3ST_2ch_modes,
7365                 .input_mux = &alc883_capture_source,
7366         },
7367         [ALC883_LENOVO_101E_2ch] = {
7368                 .mixers = { alc883_lenovo_101e_2ch_mixer},
7369                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7370                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7371                 .dac_nids = alc883_dac_nids,
7372                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7373                 .adc_nids = alc883_adc_nids,
7374                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7375                 .channel_mode = alc883_3ST_2ch_modes,
7376                 .input_mux = &alc883_lenovo_101e_capture_source,
7377                 .unsol_event = alc883_lenovo_101e_unsol_event,
7378                 .init_hook = alc883_lenovo_101e_all_automute,
7379         },
7380         [ALC883_LENOVO_NB0763] = {
7381                 .mixers = { alc883_lenovo_nb0763_mixer },
7382                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7383                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7384                 .dac_nids = alc883_dac_nids,
7385                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7386                 .adc_nids = alc883_adc_nids,
7387                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7388                 .channel_mode = alc883_3ST_2ch_modes,
7389                 .need_dac_fix = 1,
7390                 .input_mux = &alc883_lenovo_nb0763_capture_source,
7391                 .unsol_event = alc883_medion_md2_unsol_event,
7392                 .init_hook = alc883_medion_md2_automute,
7393         },
7394         [ALC888_LENOVO_MS7195_DIG] = {
7395                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7396                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7397                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7398                 .dac_nids = alc883_dac_nids,
7399                 .dig_out_nid = ALC883_DIGOUT_NID,
7400                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7401                 .adc_nids = alc883_adc_nids,
7402                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7403                 .channel_mode = alc883_3ST_6ch_modes,
7404                 .need_dac_fix = 1,
7405                 .input_mux = &alc883_capture_source,
7406                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7407                 .init_hook = alc888_lenovo_ms7195_front_automute,
7408         },
7409         [ALC883_HAIER_W66] = {
7410                 .mixers = { alc883_tagra_2ch_mixer},
7411                 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7412                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7413                 .dac_nids = alc883_dac_nids,
7414                 .dig_out_nid = ALC883_DIGOUT_NID,
7415                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7416                 .adc_nids = alc883_adc_nids,
7417                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7418                 .channel_mode = alc883_3ST_2ch_modes,
7419                 .input_mux = &alc883_capture_source,
7420                 .unsol_event = alc883_haier_w66_unsol_event,
7421                 .init_hook = alc883_haier_w66_automute,
7422         },      
7423         [ALC888_6ST_HP] = {
7424                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7425                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7426                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7427                 .dac_nids = alc883_dac_nids,
7428                 .dig_out_nid = ALC883_DIGOUT_NID,
7429                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7430                 .adc_nids = alc883_adc_nids,
7431                 .dig_in_nid = ALC883_DIGIN_NID,
7432                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7433                 .channel_mode = alc883_sixstack_modes,
7434                 .input_mux = &alc883_capture_source,
7435         },
7436         [ALC888_3ST_HP] = {
7437                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7438                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7439                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7440                 .dac_nids = alc883_dac_nids,
7441                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7442                 .adc_nids = alc883_adc_nids,
7443                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7444                 .channel_mode = alc888_3st_hp_modes,
7445                 .need_dac_fix = 1,
7446                 .input_mux = &alc883_capture_source,
7447         },
7448 };
7449
7450
7451 /*
7452  * BIOS auto configuration
7453  */
7454 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7455                                               hda_nid_t nid, int pin_type,
7456                                               int dac_idx)
7457 {
7458         /* set as output */
7459         struct alc_spec *spec = codec->spec;
7460         int idx;
7461
7462         if (spec->multiout.dac_nids[dac_idx] == 0x25)
7463                 idx = 4;
7464         else
7465                 idx = spec->multiout.dac_nids[dac_idx] - 2;
7466
7467         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7468                             pin_type);
7469         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7470                             AMP_OUT_UNMUTE);
7471         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7472
7473 }
7474
7475 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7476 {
7477         struct alc_spec *spec = codec->spec;
7478         int i;
7479
7480         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7481         for (i = 0; i <= HDA_SIDE; i++) {
7482                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7483                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7484                 if (nid)
7485                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7486                                                           i);
7487         }
7488 }
7489
7490 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7491 {
7492         struct alc_spec *spec = codec->spec;
7493         hda_nid_t pin;
7494
7495         pin = spec->autocfg.hp_pins[0];
7496         if (pin) /* connect to front */
7497                 /* use dac 0 */
7498                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7499 }
7500
7501 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
7502 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
7503
7504 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7505 {
7506         struct alc_spec *spec = codec->spec;
7507         int i;
7508
7509         for (i = 0; i < AUTO_PIN_LAST; i++) {
7510                 hda_nid_t nid = spec->autocfg.input_pins[i];
7511                 if (alc883_is_input_pin(nid)) {
7512                         snd_hda_codec_write(codec, nid, 0,
7513                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
7514                                             (i <= AUTO_PIN_FRONT_MIC ?
7515                                              PIN_VREF80 : PIN_IN));
7516                         if (nid != ALC883_PIN_CD_NID)
7517                                 snd_hda_codec_write(codec, nid, 0,
7518                                                     AC_VERB_SET_AMP_GAIN_MUTE,
7519                                                     AMP_OUT_MUTE);
7520                 }
7521         }
7522 }
7523
7524 /* almost identical with ALC880 parser... */
7525 static int alc883_parse_auto_config(struct hda_codec *codec)
7526 {
7527         struct alc_spec *spec = codec->spec;
7528         int err = alc880_parse_auto_config(codec);
7529
7530         if (err < 0)
7531                 return err;
7532         else if (!err)
7533                 return 0; /* no config found */
7534
7535         err = alc_auto_add_mic_boost(codec);
7536         if (err < 0)
7537                 return err;
7538
7539         /* hack - override the init verbs */
7540         spec->init_verbs[0] = alc883_auto_init_verbs;
7541         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7542         spec->num_mixers++;
7543
7544         return 1; /* config found */
7545 }
7546
7547 /* additional initialization for auto-configuration model */
7548 static void alc883_auto_init(struct hda_codec *codec)
7549 {
7550         alc883_auto_init_multi_out(codec);
7551         alc883_auto_init_hp_out(codec);
7552         alc883_auto_init_analog_input(codec);
7553 }
7554
7555 static int patch_alc883(struct hda_codec *codec)
7556 {
7557         struct alc_spec *spec;
7558         int err, board_config;
7559
7560         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7561         if (spec == NULL)
7562                 return -ENOMEM;
7563
7564         codec->spec = spec;
7565
7566         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7567                                                   alc883_models,
7568                                                   alc883_cfg_tbl);
7569         if (board_config < 0) {
7570                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7571                        "trying auto-probe from BIOS...\n");
7572                 board_config = ALC883_AUTO;
7573         }
7574
7575         if (board_config == ALC883_AUTO) {
7576                 /* automatic parse from the BIOS config */
7577                 err = alc883_parse_auto_config(codec);
7578                 if (err < 0) {
7579                         alc_free(codec);
7580                         return err;
7581                 } else if (!err) {
7582                         printk(KERN_INFO
7583                                "hda_codec: Cannot set up configuration "
7584                                "from BIOS.  Using base mode...\n");
7585                         board_config = ALC883_3ST_2ch_DIG;
7586                 }
7587         }
7588
7589         if (board_config != ALC883_AUTO)
7590                 setup_preset(spec, &alc883_presets[board_config]);
7591
7592         spec->stream_name_analog = "ALC883 Analog";
7593         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7594         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7595
7596         spec->stream_name_digital = "ALC883 Digital";
7597         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7598         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7599
7600         if (!spec->adc_nids && spec->input_mux) {
7601                 spec->adc_nids = alc883_adc_nids;
7602                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7603         }
7604
7605         codec->patch_ops = alc_patch_ops;
7606         if (board_config == ALC883_AUTO)
7607                 spec->init_hook = alc883_auto_init;
7608 #ifdef CONFIG_SND_HDA_POWER_SAVE
7609         if (!spec->loopback.amplist)
7610                 spec->loopback.amplist = alc883_loopbacks;
7611 #endif
7612
7613         return 0;
7614 }
7615
7616 /*
7617  * ALC262 support
7618  */
7619
7620 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7621 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7622
7623 #define alc262_dac_nids         alc260_dac_nids
7624 #define alc262_adc_nids         alc882_adc_nids
7625 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7626
7627 #define alc262_modes            alc260_modes
7628 #define alc262_capture_source   alc882_capture_source
7629
7630 static struct snd_kcontrol_new alc262_base_mixer[] = {
7631         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7632         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7633         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7634         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7635         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7636         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7637         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7638         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7639         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7640         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7641         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7642         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7643         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7644            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7645         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7646         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7647         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7648         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7649         { } /* end */
7650 };
7651
7652 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7653         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7654         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7655         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7656         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7657         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7658         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7659         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7660         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7661         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7662         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7663         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7664         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7665         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7666            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7667         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7668         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7669         { } /* end */
7670 };
7671
7672 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7673         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7674         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7675         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7676         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7677         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7678
7679         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7680         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7681         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7682         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7683         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7684         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7685         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7686         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7687         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7688         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7689         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7690         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7691         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7692         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7693         { } /* end */
7694 };
7695
7696 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7697         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7698         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7699         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7700         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7701         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7702         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7703         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7704         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7705         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7706         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7707         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7708         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7709         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7710         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7711         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7712         { } /* end */
7713 };
7714
7715 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7716         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7717         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7718         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7719         { } /* end */
7720 };
7721
7722 static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
7723         .ops = &snd_hda_bind_vol,
7724         .values = {
7725                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7726                 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7727                 0
7728         },
7729 };
7730
7731 static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
7732         .ops = &snd_hda_bind_sw,
7733         .values = {
7734                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7735                 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7736                 0
7737         },
7738 };
7739
7740 /* mute/unmute internal speaker according to the hp jack and mute state */
7741 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
7742 {
7743         struct alc_spec *spec = codec->spec;
7744         unsigned int mute;
7745
7746         if (force || !spec->sense_updated) {
7747                 unsigned int present;
7748                 present = snd_hda_codec_read(codec, 0x15, 0,
7749                                              AC_VERB_GET_PIN_SENSE, 0);
7750                 spec->jack_present = (present & 0x80000000) != 0;
7751                 spec->sense_updated = 1;
7752         }
7753         if (spec->jack_present)
7754                 mute = (0x7080 | ((0)<<8));  /* mute internal speaker */
7755         else    /* unmute internal speaker if necessary */
7756                 mute = (0x7000 | ((0)<<8));
7757         snd_hda_codec_write(codec, 0x0c, 0,
7758                             AC_VERB_SET_AMP_GAIN_MUTE, mute );
7759 }
7760
7761 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
7762                                         unsigned int res)
7763 {
7764         if ((res >> 26) != ALC880_HP_EVENT)
7765                 return;
7766         alc262_hp_t5735_automute(codec, 1);
7767 }
7768
7769 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
7770 {
7771         alc262_hp_t5735_automute(codec, 1);
7772 }
7773
7774 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
7775         HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
7776         HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
7777         HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7778         HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7779         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7780         HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7781         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7782         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7783         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7784         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7785         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7786         { } /* end */
7787 };
7788
7789 static struct hda_verb alc262_hp_t5735_verbs[] = {
7790         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7791         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7792
7793         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7794         { }
7795 };
7796
7797 /* bind hp and internal speaker mute (with plug check) */
7798 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7799                                      struct snd_ctl_elem_value *ucontrol)
7800 {
7801         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7802         long *valp = ucontrol->value.integer.value;
7803         int change;
7804
7805         /* change hp mute */
7806         change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7807                                           HDA_AMP_MUTE,
7808                                           valp[0] ? 0 : HDA_AMP_MUTE);
7809         change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7810                                            HDA_AMP_MUTE,
7811                                            valp[1] ? 0 : HDA_AMP_MUTE);
7812         if (change) {
7813                 /* change speaker according to HP jack state */
7814                 struct alc_spec *spec = codec->spec;
7815                 unsigned int mute;
7816                 if (spec->jack_present)
7817                         mute = HDA_AMP_MUTE;
7818                 else
7819                         mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7820                                                       HDA_OUTPUT, 0);
7821                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7822                                          HDA_AMP_MUTE, mute);
7823         }
7824         return change;
7825 }
7826
7827 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7828         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7829         {
7830                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7831                 .name = "Master Playback Switch",
7832                 .info = snd_hda_mixer_amp_switch_info,
7833                 .get = snd_hda_mixer_amp_switch_get,
7834                 .put = alc262_sony_master_sw_put,
7835                 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7836         },
7837         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7838         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7839         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7840         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7841         { } /* end */
7842 };
7843
7844 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7845         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7846         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7847         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7848         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7849         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7850         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7851         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7852         { } /* end */
7853 };
7854
7855 #define alc262_capture_mixer            alc882_capture_mixer
7856 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7857
7858 /*
7859  * generic initialization of ADC, input mixers and output mixers
7860  */
7861 static struct hda_verb alc262_init_verbs[] = {
7862         /*
7863          * Unmute ADC0-2 and set the default input to mic-in
7864          */
7865         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7866         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7867         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7868         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7869         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7870         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7871
7872         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7873          * mixer widget
7874          * Note: PASD motherboards uses the Line In 2 as the input for
7875          * front panel mic (mic 2)
7876          */
7877         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7878         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7879         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7880         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7881         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7882         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7883
7884         /*
7885          * Set up output mixers (0x0c - 0x0e)
7886          */
7887         /* set vol=0 to output mixers */
7888         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7889         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7890         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7891         /* set up input amps for analog loopback */
7892         /* Amp Indices: DAC = 0, mixer = 1 */
7893         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7894         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7895         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7896         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7897         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7898         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7899
7900         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7901         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7902         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7903         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7904         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7905         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7906
7907         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7908         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7909         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7910         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7911         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7912         
7913         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7914         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7915         
7916         /* FIXME: use matrix-type input source selection */
7917         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7918         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7919         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7920         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7921         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7922         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7923         /* Input mixer2 */
7924         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7925         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7926         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7927         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7928         /* Input mixer3 */
7929         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7930         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7931         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7932         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7933
7934         { }
7935 };
7936
7937 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7938         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7939         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7940         {}
7941 };
7942
7943 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7944         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7945         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7946         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7947
7948         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7949         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7950         {}
7951 };
7952
7953 static struct hda_verb alc262_sony_unsol_verbs[] = {
7954         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7955         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7956         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7957
7958         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7959         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7960 };
7961
7962 /* mute/unmute internal speaker according to the hp jack and mute state */
7963 static void alc262_hippo_automute(struct hda_codec *codec)
7964 {
7965         struct alc_spec *spec = codec->spec;
7966         unsigned int mute;
7967         unsigned int present;
7968
7969         /* need to execute and sync at first */
7970         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7971         present = snd_hda_codec_read(codec, 0x15, 0,
7972                                      AC_VERB_GET_PIN_SENSE, 0);
7973         spec->jack_present = (present & 0x80000000) != 0;
7974         if (spec->jack_present) {
7975                 /* mute internal speaker */
7976                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7977                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7978         } else {
7979                 /* unmute internal speaker if necessary */
7980                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7981                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7982                                          HDA_AMP_MUTE, mute);
7983         }
7984 }
7985
7986 /* unsolicited event for HP jack sensing */
7987 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7988                                        unsigned int res)
7989 {
7990         if ((res >> 26) != ALC880_HP_EVENT)
7991                 return;
7992         alc262_hippo_automute(codec);
7993 }
7994
7995 static void alc262_hippo1_automute(struct hda_codec *codec)
7996 {
7997         unsigned int mute;
7998         unsigned int present;
7999
8000         snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8001         present = snd_hda_codec_read(codec, 0x1b, 0,
8002                                      AC_VERB_GET_PIN_SENSE, 0);
8003         present = (present & 0x80000000) != 0;
8004         if (present) {
8005                 /* mute internal speaker */
8006                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8007                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8008         } else {
8009                 /* unmute internal speaker if necessary */
8010                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8011                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8012                                          HDA_AMP_MUTE, mute);
8013         }
8014 }
8015
8016 /* unsolicited event for HP jack sensing */
8017 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8018                                        unsigned int res)
8019 {
8020         if ((res >> 26) != ALC880_HP_EVENT)
8021                 return;
8022         alc262_hippo1_automute(codec);
8023 }
8024
8025 /*
8026  * fujitsu model
8027  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
8028  */
8029
8030 #define ALC_HP_EVENT    0x37
8031
8032 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8033         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8034         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8035         {}
8036 };
8037
8038 static struct hda_input_mux alc262_fujitsu_capture_source = {
8039         .num_items = 3,
8040         .items = {
8041                 { "Mic", 0x0 },
8042                 { "Int Mic", 0x1 },
8043                 { "CD", 0x4 },
8044         },
8045 };
8046
8047 static struct hda_input_mux alc262_HP_capture_source = {
8048         .num_items = 5,
8049         .items = {
8050                 { "Mic", 0x0 },
8051                 { "Front Mic", 0x1 },
8052                 { "Line", 0x2 },
8053                 { "CD", 0x4 },
8054                 { "AUX IN", 0x6 },
8055         },
8056 };
8057
8058 static struct hda_input_mux alc262_HP_D7000_capture_source = {
8059         .num_items = 4,
8060         .items = {
8061                 { "Mic", 0x0 },
8062                 { "Front Mic", 0x2 },
8063                 { "Line", 0x1 },
8064                 { "CD", 0x4 },
8065         },
8066 };
8067
8068 /* mute/unmute internal speaker according to the hp jack and mute state */
8069 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8070 {
8071         struct alc_spec *spec = codec->spec;
8072         unsigned int mute;
8073
8074         if (force || !spec->sense_updated) {
8075                 unsigned int present;
8076                 /* need to execute and sync at first */
8077                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8078                 present = snd_hda_codec_read(codec, 0x14, 0,
8079                                          AC_VERB_GET_PIN_SENSE, 0);
8080                 spec->jack_present = (present & 0x80000000) != 0;
8081                 spec->sense_updated = 1;
8082         }
8083         if (spec->jack_present) {
8084                 /* mute internal speaker */
8085                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8086                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8087         } else {
8088                 /* unmute internal speaker if necessary */
8089                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8090                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8091                                          HDA_AMP_MUTE, mute);
8092         }
8093 }
8094
8095 /* unsolicited event for HP jack sensing */
8096 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8097                                        unsigned int res)
8098 {
8099         if ((res >> 26) != ALC_HP_EVENT)
8100                 return;
8101         alc262_fujitsu_automute(codec, 1);
8102 }
8103
8104 /* bind volumes of both NID 0x0c and 0x0d */
8105 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8106         .ops = &snd_hda_bind_vol,
8107         .values = {
8108                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8109                 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8110                 0
8111         },
8112 };
8113
8114 /* bind hp and internal speaker mute (with plug check) */
8115 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8116                                          struct snd_ctl_elem_value *ucontrol)
8117 {
8118         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8119         long *valp = ucontrol->value.integer.value;
8120         int change;
8121
8122         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8123                                           HDA_AMP_MUTE,
8124                                           valp[0] ? 0 : HDA_AMP_MUTE);
8125         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8126                                            HDA_AMP_MUTE,
8127                                            valp[1] ? 0 : HDA_AMP_MUTE);
8128         if (change)
8129                 alc262_fujitsu_automute(codec, 0);
8130         return change;
8131 }
8132
8133 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8134         HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8135         {
8136                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8137                 .name = "Master Playback Switch",
8138                 .info = snd_hda_mixer_amp_switch_info,
8139                 .get = snd_hda_mixer_amp_switch_get,
8140                 .put = alc262_fujitsu_master_sw_put,
8141                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8142         },
8143         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8144         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8145         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8146         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8147         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8148         HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8149         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8150         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8151         { } /* end */
8152 };
8153
8154 /* additional init verbs for Benq laptops */
8155 static struct hda_verb alc262_EAPD_verbs[] = {
8156         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8157         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
8158         {}
8159 };
8160
8161 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8162         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8163         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8164
8165         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8166         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
8167         {}
8168 };
8169
8170 /* Samsung Q1 Ultra Vista model setup */
8171 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8172         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8173         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8174         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8175         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8176         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8177         HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8178         { } /* end */
8179 };
8180
8181 static struct hda_verb alc262_ultra_verbs[] = {
8182         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8183         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8184         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8185         /* Mic is on Node 0x19 */
8186         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8187         {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8188         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8189         {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8190         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8191         {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8192         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8193         {}
8194 };
8195
8196 static struct hda_input_mux alc262_ultra_capture_source = {
8197         .num_items = 1,
8198         .items = {
8199                 { "Mic", 0x1 },
8200         },
8201 };
8202
8203 /* mute/unmute internal speaker according to the hp jack and mute state */
8204 static void alc262_ultra_automute(struct hda_codec *codec)
8205 {
8206         struct alc_spec *spec = codec->spec;
8207         unsigned int mute;
8208         unsigned int present;
8209
8210         /* need to execute and sync at first */
8211         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8212         present = snd_hda_codec_read(codec, 0x15, 0,
8213                                      AC_VERB_GET_PIN_SENSE, 0);
8214         spec->jack_present = (present & 0x80000000) != 0;
8215         if (spec->jack_present) {
8216                 /* mute internal speaker */
8217                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8218                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8219         } else {
8220                 /* unmute internal speaker if necessary */
8221                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8222                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8223                                          HDA_AMP_MUTE, mute);
8224         }
8225 }
8226
8227 /* unsolicited event for HP jack sensing */
8228 static void alc262_ultra_unsol_event(struct hda_codec *codec,
8229                                        unsigned int res)
8230 {
8231         if ((res >> 26) != ALC880_HP_EVENT)
8232                 return;
8233         alc262_ultra_automute(codec);
8234 }
8235
8236 /* add playback controls from the parsed DAC table */
8237 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8238                                              const struct auto_pin_cfg *cfg)
8239 {
8240         hda_nid_t nid;
8241         int err;
8242
8243         spec->multiout.num_dacs = 1;    /* only use one dac */
8244         spec->multiout.dac_nids = spec->private_dac_nids;
8245         spec->multiout.dac_nids[0] = 2;
8246
8247         nid = cfg->line_out_pins[0];
8248         if (nid) {
8249                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8250                                   "Front Playback Volume",
8251                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8252                 if (err < 0)
8253                         return err;
8254                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8255                                   "Front Playback Switch",
8256                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8257                 if (err < 0)
8258                         return err;
8259         }
8260
8261         nid = cfg->speaker_pins[0];
8262         if (nid) {
8263                 if (nid == 0x16) {
8264                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
8265                                           "Speaker Playback Volume",
8266                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8267                                                               HDA_OUTPUT));
8268                         if (err < 0)
8269                                 return err;
8270                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8271                                           "Speaker Playback Switch",
8272                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8273                                                               HDA_OUTPUT));
8274                         if (err < 0)
8275                                 return err;
8276                 } else {
8277                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8278                                           "Speaker Playback Switch",
8279                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8280                                                               HDA_OUTPUT));
8281                         if (err < 0)
8282                                 return err;
8283                 }
8284         }
8285         nid = cfg->hp_pins[0];
8286         if (nid) {
8287                 /* spec->multiout.hp_nid = 2; */
8288                 if (nid == 0x16) {
8289                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
8290                                           "Headphone Playback Volume",
8291                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8292                                                               HDA_OUTPUT));
8293                         if (err < 0)
8294                                 return err;
8295                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8296                                           "Headphone Playback Switch",
8297                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8298                                                               HDA_OUTPUT));
8299                         if (err < 0)
8300                                 return err;
8301                 } else {
8302                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8303                                           "Headphone Playback Switch",
8304                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8305                                                               HDA_OUTPUT));
8306                         if (err < 0)
8307                                 return err;
8308                 }
8309         }
8310         return 0;
8311 }
8312
8313 /* identical with ALC880 */
8314 #define alc262_auto_create_analog_input_ctls \
8315         alc880_auto_create_analog_input_ctls
8316
8317 /*
8318  * generic initialization of ADC, input mixers and output mixers
8319  */
8320 static struct hda_verb alc262_volume_init_verbs[] = {
8321         /*
8322          * Unmute ADC0-2 and set the default input to mic-in
8323          */
8324         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8325         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8326         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8327         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8328         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8329         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8330
8331         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8332          * mixer widget
8333          * Note: PASD motherboards uses the Line In 2 as the input for
8334          * front panel mic (mic 2)
8335          */
8336         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8337         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8338         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8339         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8340         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8341         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8342
8343         /*
8344          * Set up output mixers (0x0c - 0x0f)
8345          */
8346         /* set vol=0 to output mixers */
8347         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8348         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8349         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8350         
8351         /* set up input amps for analog loopback */
8352         /* Amp Indices: DAC = 0, mixer = 1 */
8353         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8354         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8355         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8356         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8357         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8358         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8359
8360         /* FIXME: use matrix-type input source selection */
8361         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8362         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8363         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8364         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8365         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8366         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8367         /* Input mixer2 */
8368         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8369         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8370         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8371         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8372         /* Input mixer3 */
8373         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8374         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8375         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8376         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8377
8378         { }
8379 };
8380
8381 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8382         /*
8383          * Unmute ADC0-2 and set the default input to mic-in
8384          */
8385         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8386         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8387         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8388         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8389         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8390         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8391
8392         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8393          * mixer widget
8394          * Note: PASD motherboards uses the Line In 2 as the input for
8395          * front panel mic (mic 2)
8396          */
8397         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8398         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8399         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8400         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8401         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8402         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8403         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8404         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8405         
8406         /*
8407          * Set up output mixers (0x0c - 0x0e)
8408          */
8409         /* set vol=0 to output mixers */
8410         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8411         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8412         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8413
8414         /* set up input amps for analog loopback */
8415         /* Amp Indices: DAC = 0, mixer = 1 */
8416         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8417         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8418         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8419         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8420         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8421         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8422
8423         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8424         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8425         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8426
8427         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8428         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8429
8430         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8431         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8432
8433         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8434         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8435         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8436         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8437         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8438
8439         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8440         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8441         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8442         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8443         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8444         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8445
8446
8447         /* FIXME: use matrix-type input source selection */
8448         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8449         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8450         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8451         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8452         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8453         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8454         /* Input mixer2 */
8455         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8456         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8457         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8458         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8459         /* Input mixer3 */
8460         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8461         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8462         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8463         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8464
8465         { }
8466 };
8467
8468 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8469         /*
8470          * Unmute ADC0-2 and set the default input to mic-in
8471          */
8472         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8473         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8474         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8475         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8476         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8477         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8478
8479         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8480          * mixer widget
8481          * Note: PASD motherboards uses the Line In 2 as the input for front
8482          * panel mic (mic 2)
8483          */
8484         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8485         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8486         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8487         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8488         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8489         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8490         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8491         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8492         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8493         /*
8494          * Set up output mixers (0x0c - 0x0e)
8495          */
8496         /* set vol=0 to output mixers */
8497         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8498         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8499         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8500
8501         /* set up input amps for analog loopback */
8502         /* Amp Indices: DAC = 0, mixer = 1 */
8503         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8504         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8505         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8506         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8507         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8508         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8509
8510
8511         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
8512         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
8513         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
8514         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
8515         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
8516         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
8517         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
8518
8519         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8520         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8521
8522         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8523         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8524
8525         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8526         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8527         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8528         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8529         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8530         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8531
8532         /* FIXME: use matrix-type input source selection */
8533         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8534         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8535         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8536         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8537         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8538         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8539         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8540         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
8541         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8542         /* Input mixer2 */
8543         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8544         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8545         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8546         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8547         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8548         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8549         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8550         /* Input mixer3 */
8551         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8552         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8553         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8554         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8555         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8556         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8557         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8558
8559         { }
8560 };
8561
8562 #ifdef CONFIG_SND_HDA_POWER_SAVE
8563 #define alc262_loopbacks        alc880_loopbacks
8564 #endif
8565
8566 /* pcm configuration: identiacal with ALC880 */
8567 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
8568 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
8569 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
8570 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
8571
8572 /*
8573  * BIOS auto configuration
8574  */
8575 static int alc262_parse_auto_config(struct hda_codec *codec)
8576 {
8577         struct alc_spec *spec = codec->spec;
8578         int err;
8579         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8580
8581         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8582                                            alc262_ignore);
8583         if (err < 0)
8584                 return err;
8585         if (!spec->autocfg.line_outs)
8586                 return 0; /* can't find valid BIOS pin config */
8587         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8588         if (err < 0)
8589                 return err;
8590         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8591         if (err < 0)
8592                 return err;
8593
8594         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8595
8596         if (spec->autocfg.dig_out_pin)
8597                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8598         if (spec->autocfg.dig_in_pin)
8599                 spec->dig_in_nid = ALC262_DIGIN_NID;
8600
8601         if (spec->kctl_alloc)
8602                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8603
8604         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8605         spec->num_mux_defs = 1;
8606         spec->input_mux = &spec->private_imux;
8607
8608         err = alc_auto_add_mic_boost(codec);
8609         if (err < 0)
8610                 return err;
8611
8612         return 1;
8613 }
8614
8615 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
8616 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
8617 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
8618
8619
8620 /* init callback for auto-configuration model -- overriding the default init */
8621 static void alc262_auto_init(struct hda_codec *codec)
8622 {
8623         alc262_auto_init_multi_out(codec);
8624         alc262_auto_init_hp_out(codec);
8625         alc262_auto_init_analog_input(codec);
8626 }
8627
8628 /*
8629  * configuration and preset
8630  */
8631 static const char *alc262_models[ALC262_MODEL_LAST] = {
8632         [ALC262_BASIC]          = "basic",
8633         [ALC262_HIPPO]          = "hippo",
8634         [ALC262_HIPPO_1]        = "hippo_1",
8635         [ALC262_FUJITSU]        = "fujitsu",
8636         [ALC262_HP_BPC]         = "hp-bpc",
8637         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8638         [ALC262_HP_TC_T5735]    = "hp-tc-t5735",
8639         [ALC262_BENQ_ED8]       = "benq",
8640         [ALC262_BENQ_T31]       = "benq-t31",
8641         [ALC262_SONY_ASSAMD]    = "sony-assamd",
8642         [ALC262_ULTRA]          = "ultra",
8643         [ALC262_AUTO]           = "auto",
8644 };
8645
8646 static struct snd_pci_quirk alc262_cfg_tbl[] = {
8647         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8648         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8649         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8650         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8651         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8652         SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
8653         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8654         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8655         SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
8656         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8657         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8658         SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
8659         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8660         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8661         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8662         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8663         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8664         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8665         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8666         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8667         SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8668                       ALC262_HP_TC_T5735),
8669         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8670         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8671         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8672         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8673         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8674         SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8675         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8676         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8677         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8678         SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
8679         {}
8680 };
8681
8682 static struct alc_config_preset alc262_presets[] = {
8683         [ALC262_BASIC] = {
8684                 .mixers = { alc262_base_mixer },
8685                 .init_verbs = { alc262_init_verbs },
8686                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8687                 .dac_nids = alc262_dac_nids,
8688                 .hp_nid = 0x03,
8689                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8690                 .channel_mode = alc262_modes,
8691                 .input_mux = &alc262_capture_source,
8692         },
8693         [ALC262_HIPPO] = {
8694                 .mixers = { alc262_base_mixer },
8695                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8696                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8697                 .dac_nids = alc262_dac_nids,
8698                 .hp_nid = 0x03,
8699                 .dig_out_nid = ALC262_DIGOUT_NID,
8700                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8701                 .channel_mode = alc262_modes,
8702                 .input_mux = &alc262_capture_source,
8703                 .unsol_event = alc262_hippo_unsol_event,
8704                 .init_hook = alc262_hippo_automute,
8705         },
8706         [ALC262_HIPPO_1] = {
8707                 .mixers = { alc262_hippo1_mixer },
8708                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8709                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8710                 .dac_nids = alc262_dac_nids,
8711                 .hp_nid = 0x02,
8712                 .dig_out_nid = ALC262_DIGOUT_NID,
8713                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8714                 .channel_mode = alc262_modes,
8715                 .input_mux = &alc262_capture_source,
8716                 .unsol_event = alc262_hippo1_unsol_event,
8717                 .init_hook = alc262_hippo1_automute,
8718         },
8719         [ALC262_FUJITSU] = {
8720                 .mixers = { alc262_fujitsu_mixer },
8721                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8722                                 alc262_fujitsu_unsol_verbs },
8723                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8724                 .dac_nids = alc262_dac_nids,
8725                 .hp_nid = 0x03,
8726                 .dig_out_nid = ALC262_DIGOUT_NID,
8727                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8728                 .channel_mode = alc262_modes,
8729                 .input_mux = &alc262_fujitsu_capture_source,
8730                 .unsol_event = alc262_fujitsu_unsol_event,
8731         },
8732         [ALC262_HP_BPC] = {
8733                 .mixers = { alc262_HP_BPC_mixer },
8734                 .init_verbs = { alc262_HP_BPC_init_verbs },
8735                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8736                 .dac_nids = alc262_dac_nids,
8737                 .hp_nid = 0x03,
8738                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8739                 .channel_mode = alc262_modes,
8740                 .input_mux = &alc262_HP_capture_source,
8741         },
8742         [ALC262_HP_BPC_D7000_WF] = {
8743                 .mixers = { alc262_HP_BPC_WildWest_mixer },
8744                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8745                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8746                 .dac_nids = alc262_dac_nids,
8747                 .hp_nid = 0x03,
8748                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8749                 .channel_mode = alc262_modes,
8750                 .input_mux = &alc262_HP_D7000_capture_source,
8751         },
8752         [ALC262_HP_BPC_D7000_WL] = {
8753                 .mixers = { alc262_HP_BPC_WildWest_mixer,
8754                             alc262_HP_BPC_WildWest_option_mixer },
8755                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8756                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8757                 .dac_nids = alc262_dac_nids,
8758                 .hp_nid = 0x03,
8759                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8760                 .channel_mode = alc262_modes,
8761                 .input_mux = &alc262_HP_D7000_capture_source,
8762         },
8763         [ALC262_HP_TC_T5735] = {
8764                 .mixers = { alc262_hp_t5735_mixer },
8765                 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
8766                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8767                 .dac_nids = alc262_dac_nids,
8768                 .hp_nid = 0x03,
8769                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8770                 .channel_mode = alc262_modes,
8771                 .input_mux = &alc262_capture_source,
8772                 .unsol_event = alc262_hp_t5735_unsol_event,
8773                 .init_hook = alc262_hp_t5735_init_hook,
8774         },
8775         [ALC262_BENQ_ED8] = {
8776                 .mixers = { alc262_base_mixer },
8777                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8778                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8779                 .dac_nids = alc262_dac_nids,
8780                 .hp_nid = 0x03,
8781                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8782                 .channel_mode = alc262_modes,
8783                 .input_mux = &alc262_capture_source,
8784         },
8785         [ALC262_SONY_ASSAMD] = {
8786                 .mixers = { alc262_sony_mixer },
8787                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8788                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8789                 .dac_nids = alc262_dac_nids,
8790                 .hp_nid = 0x02,
8791                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8792                 .channel_mode = alc262_modes,
8793                 .input_mux = &alc262_capture_source,
8794                 .unsol_event = alc262_hippo_unsol_event,
8795                 .init_hook = alc262_hippo_automute,
8796         },
8797         [ALC262_BENQ_T31] = {
8798                 .mixers = { alc262_benq_t31_mixer },
8799                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8800                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8801                 .dac_nids = alc262_dac_nids,
8802                 .hp_nid = 0x03,
8803                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8804                 .channel_mode = alc262_modes,
8805                 .input_mux = &alc262_capture_source,
8806                 .unsol_event = alc262_hippo_unsol_event,
8807                 .init_hook = alc262_hippo_automute,
8808         },      
8809         [ALC262_ULTRA] = {
8810                 .mixers = { alc262_ultra_mixer },
8811                 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
8812                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8813                 .dac_nids = alc262_dac_nids,
8814                 .hp_nid = 0x03,
8815                 .dig_out_nid = ALC262_DIGOUT_NID,
8816                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8817                 .channel_mode = alc262_modes,
8818                 .input_mux = &alc262_ultra_capture_source,
8819                 .unsol_event = alc262_ultra_unsol_event,
8820                 .init_hook = alc262_ultra_automute,
8821         },
8822 };
8823
8824 static int patch_alc262(struct hda_codec *codec)
8825 {
8826         struct alc_spec *spec;
8827         int board_config;
8828         int err;
8829
8830         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8831         if (spec == NULL)
8832                 return -ENOMEM;
8833
8834         codec->spec = spec;
8835 #if 0
8836         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8837          * under-run
8838          */
8839         {
8840         int tmp;
8841         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8842         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8843         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8844         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8845         }
8846 #endif
8847
8848         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8849                                                   alc262_models,
8850                                                   alc262_cfg_tbl);
8851
8852         if (board_config < 0) {
8853                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8854                        "trying auto-probe from BIOS...\n");
8855                 board_config = ALC262_AUTO;
8856         }
8857
8858         if (board_config == ALC262_AUTO) {
8859                 /* automatic parse from the BIOS config */
8860                 err = alc262_parse_auto_config(codec);
8861                 if (err < 0) {
8862                         alc_free(codec);
8863                         return err;
8864                 } else if (!err) {
8865                         printk(KERN_INFO
8866                                "hda_codec: Cannot set up configuration "
8867                                "from BIOS.  Using base mode...\n");
8868                         board_config = ALC262_BASIC;
8869                 }
8870         }
8871
8872         if (board_config != ALC262_AUTO)
8873                 setup_preset(spec, &alc262_presets[board_config]);
8874
8875         spec->stream_name_analog = "ALC262 Analog";
8876         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8877         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8878                 
8879         spec->stream_name_digital = "ALC262 Digital";
8880         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8881         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8882
8883         if (!spec->adc_nids && spec->input_mux) {
8884                 /* check whether NID 0x07 is valid */
8885                 unsigned int wcap = get_wcaps(codec, 0x07);
8886
8887                 /* get type */
8888                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8889                 if (wcap != AC_WID_AUD_IN) {
8890                         spec->adc_nids = alc262_adc_nids_alt;
8891                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8892                         spec->mixers[spec->num_mixers] =
8893                                 alc262_capture_alt_mixer;
8894                         spec->num_mixers++;
8895                 } else {
8896                         spec->adc_nids = alc262_adc_nids;
8897                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8898                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8899                         spec->num_mixers++;
8900                 }
8901         }
8902
8903         codec->patch_ops = alc_patch_ops;
8904         if (board_config == ALC262_AUTO)
8905                 spec->init_hook = alc262_auto_init;
8906 #ifdef CONFIG_SND_HDA_POWER_SAVE
8907         if (!spec->loopback.amplist)
8908                 spec->loopback.amplist = alc262_loopbacks;
8909 #endif
8910                 
8911         return 0;
8912 }
8913
8914 /*
8915  *  ALC268 channel source setting (2 channel)
8916  */
8917 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8918 #define alc268_modes            alc260_modes
8919         
8920 static hda_nid_t alc268_dac_nids[2] = {
8921         /* front, hp */
8922         0x02, 0x03
8923 };
8924
8925 static hda_nid_t alc268_adc_nids[2] = {
8926         /* ADC0-1 */
8927         0x08, 0x07
8928 };
8929
8930 static hda_nid_t alc268_adc_nids_alt[1] = {
8931         /* ADC0 */
8932         0x08
8933 };
8934
8935 static struct snd_kcontrol_new alc268_base_mixer[] = {
8936         /* output mixer control */
8937         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8938         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8939         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8940         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8941         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8942         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8943         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
8944         { }
8945 };
8946
8947 static struct hda_verb alc268_eapd_verbs[] = {
8948         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8949         {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8950         { }
8951 };
8952
8953 /* Toshiba specific */
8954 #define alc268_toshiba_automute alc262_hippo_automute
8955
8956 static struct hda_verb alc268_toshiba_verbs[] = {
8957         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8958         { } /* end */
8959 };
8960
8961 /* Acer specific */
8962 /* bind volumes of both NID 0x02 and 0x03 */
8963 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
8964         .ops = &snd_hda_bind_vol,
8965         .values = {
8966                 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
8967                 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
8968                 0
8969         },
8970 };
8971
8972 /* mute/unmute internal speaker according to the hp jack and mute state */
8973 static void alc268_acer_automute(struct hda_codec *codec, int force)
8974 {
8975         struct alc_spec *spec = codec->spec;
8976         unsigned int mute;
8977
8978         if (force || !spec->sense_updated) {
8979                 unsigned int present;
8980                 present = snd_hda_codec_read(codec, 0x14, 0,
8981                                          AC_VERB_GET_PIN_SENSE, 0);
8982                 spec->jack_present = (present & 0x80000000) != 0;
8983                 spec->sense_updated = 1;
8984         }
8985         if (spec->jack_present)
8986                 mute = HDA_AMP_MUTE; /* mute internal speaker */
8987         else /* unmute internal speaker if necessary */
8988                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8989         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8990                                  HDA_AMP_MUTE, mute);
8991 }
8992
8993
8994 /* bind hp and internal speaker mute (with plug check) */
8995 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
8996                                      struct snd_ctl_elem_value *ucontrol)
8997 {
8998         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8999         long *valp = ucontrol->value.integer.value;
9000         int change;
9001
9002         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9003                                           HDA_AMP_MUTE,
9004                                           valp[0] ? 0 : HDA_AMP_MUTE);
9005         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9006                                            HDA_AMP_MUTE,
9007                                            valp[1] ? 0 : HDA_AMP_MUTE);
9008         if (change)
9009                 alc268_acer_automute(codec, 0);
9010         return change;
9011 }
9012
9013 static struct snd_kcontrol_new alc268_acer_mixer[] = {
9014         /* output mixer control */
9015         HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9016         {
9017                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9018                 .name = "Master Playback Switch",
9019                 .info = snd_hda_mixer_amp_switch_info,
9020                 .get = snd_hda_mixer_amp_switch_get,
9021                 .put = alc268_acer_master_sw_put,
9022                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9023         },
9024         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9025         HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9026         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9027         { }
9028 };
9029
9030 static struct hda_verb alc268_acer_verbs[] = {
9031         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9032         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9033
9034         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9035         { }
9036 };
9037
9038 /* unsolicited event for HP jack sensing */
9039 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9040                                        unsigned int res)
9041 {
9042         if ((res >> 26) != ALC880_HP_EVENT)
9043                 return;
9044         alc268_toshiba_automute(codec);
9045 }
9046
9047 static void alc268_acer_unsol_event(struct hda_codec *codec,
9048                                        unsigned int res)
9049 {
9050         if ((res >> 26) != ALC880_HP_EVENT)
9051                 return;
9052         alc268_acer_automute(codec, 1);
9053 }
9054
9055 static void alc268_acer_init_hook(struct hda_codec *codec)
9056 {
9057         alc268_acer_automute(codec, 1);
9058 }
9059
9060 /*
9061  * generic initialization of ADC, input mixers and output mixers
9062  */
9063 static struct hda_verb alc268_base_init_verbs[] = {
9064         /* Unmute DAC0-1 and set vol = 0 */
9065         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9066         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9067         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9068         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9069         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9070         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9071
9072         /*
9073          * Set up output mixers (0x0c - 0x0e)
9074          */
9075         /* set vol=0 to output mixers */
9076         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9077         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9078         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9079         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9080
9081         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9082         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9083
9084         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9085         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9086         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9087         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9088         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9089         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9090         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9091         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9092
9093         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9094         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9095         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9096         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9097         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9098         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9099         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9100         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9101
9102         /* FIXME: use matrix-type input source selection */
9103         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
9104         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9105         /* Input mixer2 */
9106         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9107         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9108         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9109         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9110
9111         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9112         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9113         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9114         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9115         { }
9116 };
9117
9118 /*
9119  * generic initialization of ADC, input mixers and output mixers
9120  */
9121 static struct hda_verb alc268_volume_init_verbs[] = {
9122         /* set output DAC */
9123         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9124         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9125         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9126         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9127
9128         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9129         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9130         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9131         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9132         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9133
9134         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9135         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9136         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9137         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9138         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9139
9140         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9141         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9142         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9143         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9144
9145         /* set PCBEEP vol = 0 */
9146         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9147
9148         { }
9149 };
9150
9151 #define alc268_mux_enum_info alc_mux_enum_info
9152 #define alc268_mux_enum_get alc_mux_enum_get
9153
9154 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9155                                struct snd_ctl_elem_value *ucontrol)
9156 {
9157         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9158         struct alc_spec *spec = codec->spec;
9159         const struct hda_input_mux *imux = spec->input_mux;
9160         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9161         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9162         hda_nid_t nid = capture_mixers[adc_idx];
9163         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9164         unsigned int i, idx;
9165
9166         idx = ucontrol->value.enumerated.item[0];
9167         if (idx >= imux->num_items)
9168                 idx = imux->num_items - 1;
9169         if (*cur_val == idx)
9170                 return 0;
9171         for (i = 0; i < imux->num_items; i++) {
9172                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
9173                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
9174                                          imux->items[i].index,
9175                                          HDA_AMP_MUTE, v);
9176                 snd_hda_codec_write_cache(codec, nid, 0,
9177                                           AC_VERB_SET_CONNECT_SEL,
9178                                           idx );
9179         }
9180         *cur_val = idx;
9181         return 1;
9182 }
9183
9184 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9185         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9186         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9187         {
9188                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9189                 /* The multiple "Capture Source" controls confuse alsamixer
9190                  * So call somewhat different..
9191                  * FIXME: the controls appear in the "playback" view!
9192                  */
9193                 /* .name = "Capture Source", */
9194                 .name = "Input Source",
9195                 .count = 1,
9196                 .info = alc268_mux_enum_info,
9197                 .get = alc268_mux_enum_get,
9198                 .put = alc268_mux_enum_put,
9199         },
9200         { } /* end */
9201 };
9202
9203 static struct snd_kcontrol_new alc268_capture_mixer[] = {
9204         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9205         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9206         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9207         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9208         {
9209                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9210                 /* The multiple "Capture Source" controls confuse alsamixer
9211                  * So call somewhat different..
9212                  * FIXME: the controls appear in the "playback" view!
9213                  */
9214                 /* .name = "Capture Source", */
9215                 .name = "Input Source",
9216                 .count = 2,
9217                 .info = alc268_mux_enum_info,
9218                 .get = alc268_mux_enum_get,
9219                 .put = alc268_mux_enum_put,
9220         },
9221         { } /* end */
9222 };
9223
9224 static struct hda_input_mux alc268_capture_source = {
9225         .num_items = 4,
9226         .items = {
9227                 { "Mic", 0x0 },
9228                 { "Front Mic", 0x1 },
9229                 { "Line", 0x2 },
9230                 { "CD", 0x3 },
9231         },
9232 };
9233
9234 /* create input playback/capture controls for the given pin */
9235 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9236                                     const char *ctlname, int idx)
9237 {
9238         char name[32];
9239         int err;
9240
9241         sprintf(name, "%s Playback Volume", ctlname);
9242         if (nid == 0x14) {
9243                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9244                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9245                                                       HDA_OUTPUT));
9246                 if (err < 0)
9247                         return err;
9248         } else if (nid == 0x15) {
9249                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9250                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9251                                                       HDA_OUTPUT));
9252                 if (err < 0)
9253                         return err;
9254         } else
9255                 return -1;
9256         sprintf(name, "%s Playback Switch", ctlname);
9257         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9258                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9259         if (err < 0)
9260                 return err;
9261         return 0;
9262 }
9263
9264 /* add playback controls from the parsed DAC table */
9265 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9266                                              const struct auto_pin_cfg *cfg)
9267 {
9268         hda_nid_t nid;
9269         int err;
9270
9271         spec->multiout.num_dacs = 2;    /* only use one dac */
9272         spec->multiout.dac_nids = spec->private_dac_nids;
9273         spec->multiout.dac_nids[0] = 2;
9274         spec->multiout.dac_nids[1] = 3;
9275
9276         nid = cfg->line_out_pins[0];
9277         if (nid)
9278                 alc268_new_analog_output(spec, nid, "Front", 0);        
9279
9280         nid = cfg->speaker_pins[0];
9281         if (nid == 0x1d) {
9282                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9283                                   "Speaker Playback Volume",
9284                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9285                 if (err < 0)
9286                         return err;
9287         }
9288         nid = cfg->hp_pins[0];
9289         if (nid)
9290                 alc268_new_analog_output(spec, nid, "Headphone", 0);
9291
9292         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9293         if (nid == 0x16) {
9294                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9295                                   "Mono Playback Switch",
9296                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9297                 if (err < 0)
9298                         return err;
9299         }
9300         return 0;       
9301 }
9302
9303 /* create playback/capture controls for input pins */
9304 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9305                                                 const struct auto_pin_cfg *cfg)
9306 {
9307         struct hda_input_mux *imux = &spec->private_imux;
9308         int i, idx1;
9309
9310         for (i = 0; i < AUTO_PIN_LAST; i++) {
9311                 switch(cfg->input_pins[i]) {
9312                 case 0x18:
9313                         idx1 = 0;       /* Mic 1 */
9314                         break;
9315                 case 0x19:
9316                         idx1 = 1;       /* Mic 2 */
9317                         break;
9318                 case 0x1a:
9319                         idx1 = 2;       /* Line In */
9320                         break;
9321                 case 0x1c:      
9322                         idx1 = 3;       /* CD */
9323                         break;
9324                 default:
9325                         continue;
9326                 }
9327                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9328                 imux->items[imux->num_items].index = idx1;
9329                 imux->num_items++;      
9330         }
9331         return 0;
9332 }
9333
9334 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9335 {
9336         struct alc_spec *spec = codec->spec;
9337         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9338         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9339         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9340         unsigned int    dac_vol1, dac_vol2;
9341
9342         if (speaker_nid) {
9343                 snd_hda_codec_write(codec, speaker_nid, 0,
9344                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9345                 snd_hda_codec_write(codec, 0x0f, 0,
9346                                     AC_VERB_SET_AMP_GAIN_MUTE,
9347                                     AMP_IN_UNMUTE(1));
9348                 snd_hda_codec_write(codec, 0x10, 0,
9349                                     AC_VERB_SET_AMP_GAIN_MUTE,
9350                                     AMP_IN_UNMUTE(1));
9351         } else {
9352                 snd_hda_codec_write(codec, 0x0f, 0,
9353                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9354                 snd_hda_codec_write(codec, 0x10, 0,
9355                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9356         }
9357
9358         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
9359         if (line_nid == 0x14)   
9360                 dac_vol2 = AMP_OUT_ZERO;
9361         else if (line_nid == 0x15)
9362                 dac_vol1 = AMP_OUT_ZERO;
9363         if (hp_nid == 0x14)     
9364                 dac_vol2 = AMP_OUT_ZERO;
9365         else if (hp_nid == 0x15)
9366                 dac_vol1 = AMP_OUT_ZERO;
9367         if (line_nid != 0x16 || hp_nid != 0x16 ||
9368             spec->autocfg.line_out_pins[1] != 0x16 ||
9369             spec->autocfg.line_out_pins[2] != 0x16)
9370                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9371
9372         snd_hda_codec_write(codec, 0x02, 0,
9373                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9374         snd_hda_codec_write(codec, 0x03, 0,
9375                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9376 }
9377
9378 /* pcm configuration: identiacal with ALC880 */
9379 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
9380 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
9381 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
9382
9383 /*
9384  * BIOS auto configuration
9385  */
9386 static int alc268_parse_auto_config(struct hda_codec *codec)
9387 {
9388         struct alc_spec *spec = codec->spec;
9389         int err;
9390         static hda_nid_t alc268_ignore[] = { 0 };
9391
9392         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9393                                            alc268_ignore);
9394         if (err < 0)
9395                 return err;
9396         if (!spec->autocfg.line_outs)
9397                 return 0; /* can't find valid BIOS pin config */
9398
9399         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9400         if (err < 0)
9401                 return err;
9402         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9403         if (err < 0)
9404                 return err;
9405
9406         spec->multiout.max_channels = 2;
9407
9408         /* digital only support output */
9409         if (spec->autocfg.dig_out_pin)
9410                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9411
9412         if (spec->kctl_alloc)
9413                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9414
9415         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9416         spec->num_mux_defs = 1;
9417         spec->input_mux = &spec->private_imux;
9418
9419         err = alc_auto_add_mic_boost(codec);
9420         if (err < 0)
9421                 return err;
9422
9423         return 1;
9424 }
9425
9426 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
9427 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
9428 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
9429
9430 /* init callback for auto-configuration model -- overriding the default init */
9431 static void alc268_auto_init(struct hda_codec *codec)
9432 {
9433         alc268_auto_init_multi_out(codec);
9434         alc268_auto_init_hp_out(codec);
9435         alc268_auto_init_mono_speaker_out(codec);
9436         alc268_auto_init_analog_input(codec);
9437 }
9438
9439 /*
9440  * configuration and preset
9441  */
9442 static const char *alc268_models[ALC268_MODEL_LAST] = {
9443         [ALC268_3ST]            = "3stack",
9444         [ALC268_TOSHIBA]        = "toshiba",
9445         [ALC268_ACER]           = "acer",
9446         [ALC268_AUTO]           = "auto",
9447 };
9448
9449 static struct snd_pci_quirk alc268_cfg_tbl[] = {
9450         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
9451         SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
9452         SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
9453         SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
9454         SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9455         SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9456         SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
9457         {}
9458 };
9459
9460 static struct alc_config_preset alc268_presets[] = {
9461         [ALC268_3ST] = {
9462                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9463                 .init_verbs = { alc268_base_init_verbs },
9464                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9465                 .dac_nids = alc268_dac_nids,
9466                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9467                 .adc_nids = alc268_adc_nids_alt,
9468                 .hp_nid = 0x03,
9469                 .dig_out_nid = ALC268_DIGOUT_NID,
9470                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9471                 .channel_mode = alc268_modes,
9472                 .input_mux = &alc268_capture_source,
9473         },
9474         [ALC268_TOSHIBA] = {
9475                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9476                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9477                                 alc268_toshiba_verbs },
9478                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9479                 .dac_nids = alc268_dac_nids,
9480                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9481                 .adc_nids = alc268_adc_nids_alt,
9482                 .hp_nid = 0x03,
9483                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9484                 .channel_mode = alc268_modes,
9485                 .input_mux = &alc268_capture_source,
9486                 .unsol_event = alc268_toshiba_unsol_event,
9487                 .init_hook = alc268_toshiba_automute,
9488         },
9489         [ALC268_ACER] = {
9490                 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9491                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9492                                 alc268_acer_verbs },
9493                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9494                 .dac_nids = alc268_dac_nids,
9495                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9496                 .adc_nids = alc268_adc_nids_alt,
9497                 .hp_nid = 0x02,
9498                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9499                 .channel_mode = alc268_modes,
9500                 .input_mux = &alc268_capture_source,
9501                 .unsol_event = alc268_acer_unsol_event,
9502                 .init_hook = alc268_acer_init_hook,
9503         },
9504 };
9505
9506 static int patch_alc268(struct hda_codec *codec)
9507 {
9508         struct alc_spec *spec;
9509         int board_config;
9510         int err;
9511
9512         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9513         if (spec == NULL)
9514                 return -ENOMEM;
9515
9516         codec->spec = spec;
9517
9518         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9519                                                   alc268_models,
9520                                                   alc268_cfg_tbl);
9521
9522         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9523                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9524                        "trying auto-probe from BIOS...\n");
9525                 board_config = ALC268_AUTO;
9526         }
9527
9528         if (board_config == ALC268_AUTO) {
9529                 /* automatic parse from the BIOS config */
9530                 err = alc268_parse_auto_config(codec);
9531                 if (err < 0) {
9532                         alc_free(codec);
9533                         return err;
9534                 } else if (!err) {
9535                         printk(KERN_INFO
9536                                "hda_codec: Cannot set up configuration "
9537                                "from BIOS.  Using base mode...\n");
9538                         board_config = ALC268_3ST;
9539                 }
9540         }
9541
9542         if (board_config != ALC268_AUTO)
9543                 setup_preset(spec, &alc268_presets[board_config]);
9544
9545         spec->stream_name_analog = "ALC268 Analog";
9546         spec->stream_analog_playback = &alc268_pcm_analog_playback;
9547         spec->stream_analog_capture = &alc268_pcm_analog_capture;
9548
9549         spec->stream_name_digital = "ALC268 Digital";
9550         spec->stream_digital_playback = &alc268_pcm_digital_playback;
9551
9552         if (board_config == ALC268_AUTO) {
9553                 if (!spec->adc_nids && spec->input_mux) {
9554                         /* check whether NID 0x07 is valid */
9555                         unsigned int wcap = get_wcaps(codec, 0x07);
9556
9557                         /* get type */
9558                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9559                         if (wcap != AC_WID_AUD_IN) {
9560                                 spec->adc_nids = alc268_adc_nids_alt;
9561                                 spec->num_adc_nids =
9562                                         ARRAY_SIZE(alc268_adc_nids_alt);
9563                                 spec->mixers[spec->num_mixers] =
9564                                         alc268_capture_alt_mixer;
9565                                 spec->num_mixers++;
9566                         } else {
9567                                 spec->adc_nids = alc268_adc_nids;
9568                                 spec->num_adc_nids =
9569                                         ARRAY_SIZE(alc268_adc_nids);
9570                                 spec->mixers[spec->num_mixers] =
9571                                         alc268_capture_mixer;
9572                                 spec->num_mixers++;
9573                         }
9574                 }
9575         }
9576         codec->patch_ops = alc_patch_ops;
9577         if (board_config == ALC268_AUTO)
9578                 spec->init_hook = alc268_auto_init;
9579                 
9580         return 0;
9581 }
9582
9583 /*
9584  *  ALC269 channel source setting (2 channel)
9585  */
9586 #define ALC269_DIGOUT_NID       ALC880_DIGOUT_NID
9587
9588 #define alc269_dac_nids         alc260_dac_nids
9589
9590 static hda_nid_t alc269_adc_nids[1] = {
9591         /* ADC1 */
9592         0x07,
9593 };
9594
9595 #define alc269_modes            alc260_modes
9596 #define alc269_capture_source   alc880_lg_lw_capture_source
9597
9598 static struct snd_kcontrol_new alc269_base_mixer[] = {
9599         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9600         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9601         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9602         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9603         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9604         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9605         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9606         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9607         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9608         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9609         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9610         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9611         { } /* end */
9612 };
9613
9614 /* capture mixer elements */
9615 static struct snd_kcontrol_new alc269_capture_mixer[] = {
9616         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9617         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9618         {
9619                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9620                 /* The multiple "Capture Source" controls confuse alsamixer
9621                  * So call somewhat different..
9622                  * FIXME: the controls appear in the "playback" view!
9623                  */
9624                 /* .name = "Capture Source", */
9625                 .name = "Input Source",
9626                 .count = 1,
9627                 .info = alc_mux_enum_info,
9628                 .get = alc_mux_enum_get,
9629                 .put = alc_mux_enum_put,
9630         },
9631         { } /* end */
9632 };
9633
9634 /*
9635  * generic initialization of ADC, input mixers and output mixers
9636  */
9637 static struct hda_verb alc269_init_verbs[] = {
9638         /*
9639          * Unmute ADC0 and set the default input to mic-in
9640          */
9641         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9642
9643         /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
9644          * analog-loopback mixer widget
9645          * Note: PASD motherboards uses the Line In 2 as the input for
9646          * front panel mic (mic 2)
9647          */
9648         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9649         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9650         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9651         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9652         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9653         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9654
9655         /*
9656          * Set up output mixers (0x0c - 0x0e)
9657          */
9658         /* set vol=0 to output mixers */
9659         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9660         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9661
9662         /* set up input amps for analog loopback */
9663         /* Amp Indices: DAC = 0, mixer = 1 */
9664         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9665         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9666         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9667         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9668         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9669         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9670
9671         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9672         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9673         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9674         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9675         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9676         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9677         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9678
9679         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9680         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9681         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9682         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9683         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9684         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9685         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9686
9687         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9688         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9689
9690         /* FIXME: use matrix-type input source selection */
9691         /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
9692         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9693         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9694         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9695         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9696         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9697
9698         /* set EAPD */
9699         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9700         {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9701         { }
9702 };
9703
9704 /* add playback controls from the parsed DAC table */
9705 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
9706                                              const struct auto_pin_cfg *cfg)
9707 {
9708         hda_nid_t nid;
9709         int err;
9710
9711         spec->multiout.num_dacs = 1;    /* only use one dac */
9712         spec->multiout.dac_nids = spec->private_dac_nids;
9713         spec->multiout.dac_nids[0] = 2;
9714
9715         nid = cfg->line_out_pins[0];
9716         if (nid) {
9717                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9718                                   "Front Playback Volume",
9719                                   HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
9720                 if (err < 0)
9721                         return err;
9722                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9723                                   "Front Playback Switch",
9724                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9725                 if (err < 0)
9726                         return err;
9727         }
9728
9729         nid = cfg->speaker_pins[0];
9730         if (nid) {
9731                 if (!cfg->line_out_pins[0]) {
9732                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
9733                                           "Speaker Playback Volume",
9734                                           HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9735                                                               HDA_OUTPUT));
9736                         if (err < 0)
9737                                 return err;
9738                 }
9739                 if (nid == 0x16) {
9740                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9741                                           "Speaker Playback Switch",
9742                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9743                                                               HDA_OUTPUT));
9744                         if (err < 0)
9745                                 return err;
9746                 } else {
9747                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9748                                           "Speaker Playback Switch",
9749                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9750                                                               HDA_OUTPUT));
9751                         if (err < 0)
9752                                 return err;
9753                 }
9754         }
9755         nid = cfg->hp_pins[0];
9756         if (nid) {
9757                 /* spec->multiout.hp_nid = 2; */
9758                 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
9759                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
9760                                           "Headphone Playback Volume",
9761                                           HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9762                                                               HDA_OUTPUT));
9763                         if (err < 0)
9764                                 return err;
9765                 }
9766                 if (nid == 0x16) {
9767                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9768                                           "Headphone Playback Switch",
9769                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9770                                                               HDA_OUTPUT));
9771                         if (err < 0)
9772                                 return err;
9773                 } else {
9774                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9775                                           "Headphone Playback Switch",
9776                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9777                                                               HDA_OUTPUT));
9778                         if (err < 0)
9779                                 return err;
9780                 }
9781         }
9782         return 0;
9783 }
9784
9785 #define alc269_auto_create_analog_input_ctls \
9786         alc880_auto_create_analog_input_ctls
9787
9788 #ifdef CONFIG_SND_HDA_POWER_SAVE
9789 #define alc269_loopbacks        alc880_loopbacks
9790 #endif
9791
9792 /* pcm configuration: identiacal with ALC880 */
9793 #define alc269_pcm_analog_playback      alc880_pcm_analog_playback
9794 #define alc269_pcm_analog_capture       alc880_pcm_analog_capture
9795 #define alc269_pcm_digital_playback     alc880_pcm_digital_playback
9796 #define alc269_pcm_digital_capture      alc880_pcm_digital_capture
9797
9798 /*
9799  * BIOS auto configuration
9800  */
9801 static int alc269_parse_auto_config(struct hda_codec *codec)
9802 {
9803         struct alc_spec *spec = codec->spec;
9804         int err;
9805         static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
9806
9807         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9808                                            alc269_ignore);
9809         if (err < 0)
9810                 return err;
9811
9812         err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
9813         if (err < 0)
9814                 return err;
9815         err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
9816         if (err < 0)
9817                 return err;
9818
9819         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9820
9821         if (spec->autocfg.dig_out_pin)
9822                 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
9823
9824         if (spec->kctl_alloc)
9825                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9826
9827         spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
9828         spec->num_mux_defs = 1;
9829         spec->input_mux = &spec->private_imux;
9830
9831         err = alc_auto_add_mic_boost(codec);
9832         if (err < 0)
9833                 return err;
9834
9835         return 1;
9836 }
9837
9838 #define alc269_auto_init_multi_out      alc882_auto_init_multi_out
9839 #define alc269_auto_init_hp_out         alc882_auto_init_hp_out
9840 #define alc269_auto_init_analog_input   alc882_auto_init_analog_input
9841
9842
9843 /* init callback for auto-configuration model -- overriding the default init */
9844 static void alc269_auto_init(struct hda_codec *codec)
9845 {
9846         alc269_auto_init_multi_out(codec);
9847         alc269_auto_init_hp_out(codec);
9848         alc269_auto_init_analog_input(codec);
9849 }
9850
9851 /*
9852  * configuration and preset
9853  */
9854 static const char *alc269_models[ALC269_MODEL_LAST] = {
9855         [ALC269_BASIC]          = "basic",
9856 };
9857
9858 static struct snd_pci_quirk alc269_cfg_tbl[] = {
9859         {}
9860 };
9861
9862 static struct alc_config_preset alc269_presets[] = {
9863         [ALC269_BASIC] = {
9864                 .mixers = { alc269_base_mixer },
9865                 .init_verbs = { alc269_init_verbs },
9866                 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
9867                 .dac_nids = alc269_dac_nids,
9868                 .hp_nid = 0x03,
9869                 .num_channel_mode = ARRAY_SIZE(alc269_modes),
9870                 .channel_mode = alc269_modes,
9871                 .input_mux = &alc269_capture_source,
9872         },
9873 };
9874
9875 static int patch_alc269(struct hda_codec *codec)
9876 {
9877         struct alc_spec *spec;
9878         int board_config;
9879         int err;
9880
9881         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9882         if (spec == NULL)
9883                 return -ENOMEM;
9884
9885         codec->spec = spec;
9886
9887         board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
9888                                                   alc269_models,
9889                                                   alc269_cfg_tbl);
9890
9891         if (board_config < 0) {
9892                 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
9893                        "trying auto-probe from BIOS...\n");
9894                 board_config = ALC269_AUTO;
9895         }
9896
9897         if (board_config == ALC269_AUTO) {
9898                 /* automatic parse from the BIOS config */
9899                 err = alc269_parse_auto_config(codec);
9900                 if (err < 0) {
9901                         alc_free(codec);
9902                         return err;
9903                 } else if (!err) {
9904                         printk(KERN_INFO
9905                                "hda_codec: Cannot set up configuration "
9906                                "from BIOS.  Using base mode...\n");
9907                         board_config = ALC269_BASIC;
9908                 }
9909         }
9910
9911         if (board_config != ALC269_AUTO)
9912                 setup_preset(spec, &alc269_presets[board_config]);
9913
9914         spec->stream_name_analog = "ALC269 Analog";
9915         spec->stream_analog_playback = &alc269_pcm_analog_playback;
9916         spec->stream_analog_capture = &alc269_pcm_analog_capture;
9917
9918         spec->stream_name_digital = "ALC269 Digital";
9919         spec->stream_digital_playback = &alc269_pcm_digital_playback;
9920         spec->stream_digital_capture = &alc269_pcm_digital_capture;
9921
9922         spec->adc_nids = alc269_adc_nids;
9923         spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
9924         spec->mixers[spec->num_mixers] = alc269_capture_mixer;
9925         spec->num_mixers++;
9926
9927         codec->patch_ops = alc_patch_ops;
9928         if (board_config == ALC269_AUTO)
9929                 spec->init_hook = alc269_auto_init;
9930 #ifdef CONFIG_SND_HDA_POWER_SAVE
9931         if (!spec->loopback.amplist)
9932                 spec->loopback.amplist = alc269_loopbacks;
9933 #endif
9934
9935         return 0;
9936 }
9937
9938 /*
9939  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
9940  */
9941
9942 /*
9943  * set the path ways for 2 channel output
9944  * need to set the codec line out and mic 1 pin widgets to inputs
9945  */
9946 static struct hda_verb alc861_threestack_ch2_init[] = {
9947         /* set pin widget 1Ah (line in) for input */
9948         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9949         /* set pin widget 18h (mic1/2) for input, for mic also enable
9950          * the vref
9951          */
9952         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9953
9954         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9955 #if 0
9956         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9957         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9958 #endif
9959         { } /* end */
9960 };
9961 /*
9962  * 6ch mode
9963  * need to set the codec line out and mic 1 pin widgets to outputs
9964  */
9965 static struct hda_verb alc861_threestack_ch6_init[] = {
9966         /* set pin widget 1Ah (line in) for output (Back Surround)*/
9967         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9968         /* set pin widget 18h (mic1) for output (CLFE)*/
9969         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9970
9971         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9972         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9973
9974         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9975 #if 0
9976         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9977         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9978 #endif
9979         { } /* end */
9980 };
9981
9982 static struct hda_channel_mode alc861_threestack_modes[2] = {
9983         { 2, alc861_threestack_ch2_init },
9984         { 6, alc861_threestack_ch6_init },
9985 };
9986 /* Set mic1 as input and unmute the mixer */
9987 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
9988         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9989         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9990         { } /* end */
9991 };
9992 /* Set mic1 as output and mute mixer */
9993 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
9994         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9995         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9996         { } /* end */
9997 };
9998
9999 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10000         { 2, alc861_uniwill_m31_ch2_init },
10001         { 4, alc861_uniwill_m31_ch4_init },
10002 };
10003
10004 /* Set mic1 and line-in as input and unmute the mixer */
10005 static struct hda_verb alc861_asus_ch2_init[] = {
10006         /* set pin widget 1Ah (line in) for input */
10007         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10008         /* set pin widget 18h (mic1/2) for input, for mic also enable
10009          * the vref
10010          */
10011         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10012
10013         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10014 #if 0
10015         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10016         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10017 #endif
10018         { } /* end */
10019 };
10020 /* Set mic1 nad line-in as output and mute mixer */
10021 static struct hda_verb alc861_asus_ch6_init[] = {
10022         /* set pin widget 1Ah (line in) for output (Back Surround)*/
10023         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10024         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10025         /* set pin widget 18h (mic1) for output (CLFE)*/
10026         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10027         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10028         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10029         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10030
10031         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10032 #if 0
10033         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10034         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10035 #endif
10036         { } /* end */
10037 };
10038
10039 static struct hda_channel_mode alc861_asus_modes[2] = {
10040         { 2, alc861_asus_ch2_init },
10041         { 6, alc861_asus_ch6_init },
10042 };
10043
10044 /* patch-ALC861 */
10045
10046 static struct snd_kcontrol_new alc861_base_mixer[] = {
10047         /* output mixer control */
10048         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10049         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10050         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10051         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10052         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10053
10054         /*Input mixer control */
10055         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10056            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10057         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10058         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10059         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10060         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10061         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10062         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10063         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10064         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10065
10066         /* Capture mixer control */
10067         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10068         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10069         {
10070                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10071                 .name = "Capture Source",
10072                 .count = 1,
10073                 .info = alc_mux_enum_info,
10074                 .get = alc_mux_enum_get,
10075                 .put = alc_mux_enum_put,
10076         },
10077         { } /* end */
10078 };
10079
10080 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10081         /* output mixer control */
10082         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10083         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10084         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10085         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10086         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10087
10088         /* Input mixer control */
10089         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10090            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10091         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10092         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10093         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10094         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10095         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10096         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10097         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10098         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10099
10100         /* Capture mixer control */
10101         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10102         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10103         {
10104                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10105                 .name = "Capture Source",
10106                 .count = 1,
10107                 .info = alc_mux_enum_info,
10108                 .get = alc_mux_enum_get,
10109                 .put = alc_mux_enum_put,
10110         },
10111         {
10112                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10113                 .name = "Channel Mode",
10114                 .info = alc_ch_mode_info,
10115                 .get = alc_ch_mode_get,
10116                 .put = alc_ch_mode_put,
10117                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10118         },
10119         { } /* end */
10120 };
10121
10122 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
10123         /* output mixer control */
10124         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10125         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10126         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10127         
10128         /*Capture mixer control */
10129         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10130         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10131         {
10132                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10133                 .name = "Capture Source",
10134                 .count = 1,
10135                 .info = alc_mux_enum_info,
10136                 .get = alc_mux_enum_get,
10137                 .put = alc_mux_enum_put,
10138         },
10139
10140         { } /* end */
10141 };
10142
10143 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10144         /* output mixer control */
10145         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10146         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10147         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10148         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10149         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10150
10151         /* Input mixer control */
10152         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10153            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10154         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10155         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10156         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10157         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10158         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10159         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10160         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10161         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10162
10163         /* Capture mixer control */
10164         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10165         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10166         {
10167                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10168                 .name = "Capture Source",
10169                 .count = 1,
10170                 .info = alc_mux_enum_info,
10171                 .get = alc_mux_enum_get,
10172                 .put = alc_mux_enum_put,
10173         },
10174         {
10175                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10176                 .name = "Channel Mode",
10177                 .info = alc_ch_mode_info,
10178                 .get = alc_ch_mode_get,
10179                 .put = alc_ch_mode_put,
10180                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10181         },
10182         { } /* end */
10183 };
10184
10185 static struct snd_kcontrol_new alc861_asus_mixer[] = {
10186         /* output mixer control */
10187         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10188         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10189         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10190         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10191         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10192
10193         /* Input mixer control */
10194         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10195         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10196         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10197         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10198         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10199         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10200         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10201         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10202         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10203         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10204
10205         /* Capture mixer control */
10206         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10207         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10208         {
10209                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10210                 .name = "Capture Source",
10211                 .count = 1,
10212                 .info = alc_mux_enum_info,
10213                 .get = alc_mux_enum_get,
10214                 .put = alc_mux_enum_put,
10215         },
10216         {
10217                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10218                 .name = "Channel Mode",
10219                 .info = alc_ch_mode_info,
10220                 .get = alc_ch_mode_get,
10221                 .put = alc_ch_mode_put,
10222                 .private_value = ARRAY_SIZE(alc861_asus_modes),
10223         },
10224         { }
10225 };
10226
10227 /* additional mixer */
10228 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
10229         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10230         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10231         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10232         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10233         { }
10234 };
10235
10236 /*
10237  * generic initialization of ADC, input mixers and output mixers
10238  */
10239 static struct hda_verb alc861_base_init_verbs[] = {
10240         /*
10241          * Unmute ADC0 and set the default input to mic-in
10242          */
10243         /* port-A for surround (rear panel) */
10244         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10245         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10246         /* port-B for mic-in (rear panel) with vref */
10247         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10248         /* port-C for line-in (rear panel) */
10249         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10250         /* port-D for Front */
10251         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10252         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10253         /* port-E for HP out (front panel) */
10254         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10255         /* route front PCM to HP */
10256         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10257         /* port-F for mic-in (front panel) with vref */
10258         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10259         /* port-G for CLFE (rear panel) */
10260         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10261         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10262         /* port-H for side (rear panel) */
10263         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10264         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10265         /* CD-in */
10266         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10267         /* route front mic to ADC1*/
10268         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10269         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10270         
10271         /* Unmute DAC0~3 & spdif out*/
10272         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10273         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10274         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10275         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10276         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10277         
10278         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10279         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10280         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10281         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10282         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10283         
10284         /* Unmute Stereo Mixer 15 */
10285         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10286         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10287         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10288         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10289
10290         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10291         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10292         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10293         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10294         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10295         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10296         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10297         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10298         /* hp used DAC 3 (Front) */
10299         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10300         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10301
10302         { }
10303 };
10304
10305 static struct hda_verb alc861_threestack_init_verbs[] = {
10306         /*
10307          * Unmute ADC0 and set the default input to mic-in
10308          */
10309         /* port-A for surround (rear panel) */
10310         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10311         /* port-B for mic-in (rear panel) with vref */
10312         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10313         /* port-C for line-in (rear panel) */
10314         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10315         /* port-D for Front */
10316         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10317         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10318         /* port-E for HP out (front panel) */
10319         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10320         /* route front PCM to HP */
10321         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10322         /* port-F for mic-in (front panel) with vref */
10323         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10324         /* port-G for CLFE (rear panel) */
10325         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10326         /* port-H for side (rear panel) */
10327         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10328         /* CD-in */
10329         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10330         /* route front mic to ADC1*/
10331         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10332         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10333         /* Unmute DAC0~3 & spdif out*/
10334         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10335         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10336         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10337         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10338         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10339         
10340         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10341         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10342         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10343         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10344         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10345         
10346         /* Unmute Stereo Mixer 15 */
10347         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10348         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10349         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10350         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10351
10352         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10353         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10354         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10355         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10356         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10357         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10358         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10359         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10360         /* hp used DAC 3 (Front) */
10361         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10362         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10363         { }
10364 };
10365
10366 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
10367         /*
10368          * Unmute ADC0 and set the default input to mic-in
10369          */
10370         /* port-A for surround (rear panel) */
10371         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10372         /* port-B for mic-in (rear panel) with vref */
10373         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10374         /* port-C for line-in (rear panel) */
10375         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10376         /* port-D for Front */
10377         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10378         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10379         /* port-E for HP out (front panel) */
10380         /* this has to be set to VREF80 */
10381         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10382         /* route front PCM to HP */
10383         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10384         /* port-F for mic-in (front panel) with vref */
10385         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10386         /* port-G for CLFE (rear panel) */
10387         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10388         /* port-H for side (rear panel) */
10389         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10390         /* CD-in */
10391         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10392         /* route front mic to ADC1*/
10393         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10394         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10395         /* Unmute DAC0~3 & spdif out*/
10396         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10397         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10398         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10399         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10400         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10401         
10402         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10403         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10404         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10405         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10406         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10407         
10408         /* Unmute Stereo Mixer 15 */
10409         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10410         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10411         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10412         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10413
10414         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10415         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10416         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10417         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10418         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10419         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10420         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10421         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10422         /* hp used DAC 3 (Front) */
10423         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10424         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10425         { }
10426 };
10427
10428 static struct hda_verb alc861_asus_init_verbs[] = {
10429         /*
10430          * Unmute ADC0 and set the default input to mic-in
10431          */
10432         /* port-A for surround (rear panel)
10433          * according to codec#0 this is the HP jack
10434          */
10435         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
10436         /* route front PCM to HP */
10437         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
10438         /* port-B for mic-in (rear panel) with vref */
10439         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10440         /* port-C for line-in (rear panel) */
10441         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10442         /* port-D for Front */
10443         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10444         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10445         /* port-E for HP out (front panel) */
10446         /* this has to be set to VREF80 */
10447         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10448         /* route front PCM to HP */
10449         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10450         /* port-F for mic-in (front panel) with vref */
10451         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10452         /* port-G for CLFE (rear panel) */
10453         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10454         /* port-H for side (rear panel) */
10455         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10456         /* CD-in */
10457         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10458         /* route front mic to ADC1*/
10459         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10460         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10461         /* Unmute DAC0~3 & spdif out*/
10462         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10463         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10464         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10465         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10466         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10467         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10468         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10469         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10470         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10471         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10472         
10473         /* Unmute Stereo Mixer 15 */
10474         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10475         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10476         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10477         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10478
10479         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10480         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10481         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10482         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10483         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10484         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10485         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10486         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10487         /* hp used DAC 3 (Front) */
10488         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10489         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10490         { }
10491 };
10492
10493 /* additional init verbs for ASUS laptops */
10494 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10495         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10496         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10497         { }
10498 };
10499
10500 /*
10501  * generic initialization of ADC, input mixers and output mixers
10502  */
10503 static struct hda_verb alc861_auto_init_verbs[] = {
10504         /*
10505          * Unmute ADC0 and set the default input to mic-in
10506          */
10507         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
10508         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10509         
10510         /* Unmute DAC0~3 & spdif out*/
10511         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10512         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10513         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10514         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10515         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10516         
10517         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10518         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10519         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10520         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10521         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10522         
10523         /* Unmute Stereo Mixer 15 */
10524         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10525         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10526         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10527         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10528
10529         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10530         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10531         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10532         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10533         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10534         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10535         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10536         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10537
10538         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10539         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10540         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10541         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10542         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10543         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10544         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10545         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10546
10547         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
10548
10549         { }
10550 };
10551
10552 static struct hda_verb alc861_toshiba_init_verbs[] = {
10553         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10554
10555         { }
10556 };
10557
10558 /* toggle speaker-output according to the hp-jack state */
10559 static void alc861_toshiba_automute(struct hda_codec *codec)
10560 {
10561         unsigned int present;
10562
10563         present = snd_hda_codec_read(codec, 0x0f, 0,
10564                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10565         snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10566                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10567         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10568                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
10569 }
10570
10571 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10572                                        unsigned int res)
10573 {
10574         if ((res >> 26) == ALC880_HP_EVENT)
10575                 alc861_toshiba_automute(codec);
10576 }
10577
10578 /* pcm configuration: identiacal with ALC880 */
10579 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
10580 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
10581 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
10582 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
10583
10584
10585 #define ALC861_DIGOUT_NID       0x07
10586
10587 static struct hda_channel_mode alc861_8ch_modes[1] = {
10588         { 8, NULL }
10589 };
10590
10591 static hda_nid_t alc861_dac_nids[4] = {
10592         /* front, surround, clfe, side */
10593         0x03, 0x06, 0x05, 0x04
10594 };
10595
10596 static hda_nid_t alc660_dac_nids[3] = {
10597         /* front, clfe, surround */
10598         0x03, 0x05, 0x06
10599 };
10600
10601 static hda_nid_t alc861_adc_nids[1] = {
10602         /* ADC0-2 */
10603         0x08,
10604 };
10605
10606 static struct hda_input_mux alc861_capture_source = {
10607         .num_items = 5,
10608         .items = {
10609                 { "Mic", 0x0 },
10610                 { "Front Mic", 0x3 },
10611                 { "Line", 0x1 },
10612                 { "CD", 0x4 },
10613                 { "Mixer", 0x5 },
10614         },
10615 };
10616
10617 /* fill in the dac_nids table from the parsed pin configuration */
10618 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10619                                      const struct auto_pin_cfg *cfg)
10620 {
10621         int i;
10622         hda_nid_t nid;
10623
10624         spec->multiout.dac_nids = spec->private_dac_nids;
10625         for (i = 0; i < cfg->line_outs; i++) {
10626                 nid = cfg->line_out_pins[i];
10627                 if (nid) {
10628                         if (i >= ARRAY_SIZE(alc861_dac_nids))
10629                                 continue;
10630                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10631                 }
10632         }
10633         spec->multiout.num_dacs = cfg->line_outs;
10634         return 0;
10635 }
10636
10637 /* add playback controls from the parsed DAC table */
10638 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10639                                              const struct auto_pin_cfg *cfg)
10640 {
10641         char name[32];
10642         static const char *chname[4] = {
10643                 "Front", "Surround", NULL /*CLFE*/, "Side"
10644         };
10645         hda_nid_t nid;
10646         int i, idx, err;
10647
10648         for (i = 0; i < cfg->line_outs; i++) {
10649                 nid = spec->multiout.dac_nids[i];
10650                 if (!nid)
10651                         continue;
10652                 if (nid == 0x05) {
10653                         /* Center/LFE */
10654                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10655                                           "Center Playback Switch",
10656                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10657                                                               HDA_OUTPUT));
10658                         if (err < 0)
10659                                 return err;
10660                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10661                                           "LFE Playback Switch",
10662                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10663                                                               HDA_OUTPUT));
10664                         if (err < 0)
10665                                 return err;
10666                 } else {
10667                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10668                              idx++)
10669                                 if (nid == alc861_dac_nids[idx])
10670                                         break;
10671                         sprintf(name, "%s Playback Switch", chname[idx]);
10672                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10673                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10674                                                               HDA_OUTPUT));
10675                         if (err < 0)
10676                                 return err;
10677                 }
10678         }
10679         return 0;
10680 }
10681
10682 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10683 {
10684         int err;
10685         hda_nid_t nid;
10686
10687         if (!pin)
10688                 return 0;
10689
10690         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10691                 nid = 0x03;
10692                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10693                                   "Headphone Playback Switch",
10694                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10695                 if (err < 0)
10696                         return err;
10697                 spec->multiout.hp_nid = nid;
10698         }
10699         return 0;
10700 }
10701
10702 /* create playback/capture controls for input pins */
10703 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10704                                                 const struct auto_pin_cfg *cfg)
10705 {
10706         struct hda_input_mux *imux = &spec->private_imux;
10707         int i, err, idx, idx1;
10708
10709         for (i = 0; i < AUTO_PIN_LAST; i++) {
10710                 switch (cfg->input_pins[i]) {
10711                 case 0x0c:
10712                         idx1 = 1;
10713                         idx = 2;        /* Line In */
10714                         break;
10715                 case 0x0f:
10716                         idx1 = 2;
10717                         idx = 2;        /* Line In */
10718                         break;
10719                 case 0x0d:
10720                         idx1 = 0;
10721                         idx = 1;        /* Mic In */
10722                         break;
10723                 case 0x10:
10724                         idx1 = 3;
10725                         idx = 1;        /* Mic In */
10726                         break;
10727                 case 0x11:
10728                         idx1 = 4;
10729                         idx = 0;        /* CD */
10730                         break;
10731                 default:
10732                         continue;
10733                 }
10734
10735                 err = new_analog_input(spec, cfg->input_pins[i],
10736                                        auto_pin_cfg_labels[i], idx, 0x15);
10737                 if (err < 0)
10738                         return err;
10739
10740                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10741                 imux->items[imux->num_items].index = idx1;
10742                 imux->num_items++;
10743         }
10744         return 0;
10745 }
10746
10747 static struct snd_kcontrol_new alc861_capture_mixer[] = {
10748         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10749         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10750
10751         {
10752                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10753                 /* The multiple "Capture Source" controls confuse alsamixer
10754                  * So call somewhat different..
10755                  *FIXME: the controls appear in the "playback" view!
10756                  */
10757                 /* .name = "Capture Source", */
10758                 .name = "Input Source",
10759                 .count = 1,
10760                 .info = alc_mux_enum_info,
10761                 .get = alc_mux_enum_get,
10762                 .put = alc_mux_enum_put,
10763         },
10764         { } /* end */
10765 };
10766
10767 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10768                                               hda_nid_t nid,
10769                                               int pin_type, int dac_idx)
10770 {
10771         /* set as output */
10772
10773         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10774                             pin_type);
10775         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10776                             AMP_OUT_UNMUTE);
10777
10778 }
10779
10780 static void alc861_auto_init_multi_out(struct hda_codec *codec)
10781 {
10782         struct alc_spec *spec = codec->spec;
10783         int i;
10784
10785         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
10786         for (i = 0; i < spec->autocfg.line_outs; i++) {
10787                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10788                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10789                 if (nid)
10790                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
10791                                                           spec->multiout.dac_nids[i]);
10792         }
10793 }
10794
10795 static void alc861_auto_init_hp_out(struct hda_codec *codec)
10796 {
10797         struct alc_spec *spec = codec->spec;
10798         hda_nid_t pin;
10799
10800         pin = spec->autocfg.hp_pins[0];
10801         if (pin) /* connect to front */
10802                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
10803                                                   spec->multiout.dac_nids[0]);
10804 }
10805
10806 static void alc861_auto_init_analog_input(struct hda_codec *codec)
10807 {
10808         struct alc_spec *spec = codec->spec;
10809         int i;
10810
10811         for (i = 0; i < AUTO_PIN_LAST; i++) {
10812                 hda_nid_t nid = spec->autocfg.input_pins[i];
10813                 if (nid >= 0x0c && nid <= 0x11) {
10814                         snd_hda_codec_write(codec, nid, 0,
10815                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
10816                                             i <= AUTO_PIN_FRONT_MIC ?
10817                                             PIN_VREF80 : PIN_IN);
10818                 }
10819         }
10820 }
10821
10822 /* parse the BIOS configuration and set up the alc_spec */
10823 /* return 1 if successful, 0 if the proper config is not found,
10824  * or a negative error code
10825  */
10826 static int alc861_parse_auto_config(struct hda_codec *codec)
10827 {
10828         struct alc_spec *spec = codec->spec;
10829         int err;
10830         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
10831
10832         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10833                                            alc861_ignore);
10834         if (err < 0)
10835                 return err;
10836         if (!spec->autocfg.line_outs)
10837                 return 0; /* can't find valid BIOS pin config */
10838
10839         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
10840         if (err < 0)
10841                 return err;
10842         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
10843         if (err < 0)
10844                 return err;
10845         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
10846         if (err < 0)
10847                 return err;
10848         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
10849         if (err < 0)
10850                 return err;
10851
10852         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10853
10854         if (spec->autocfg.dig_out_pin)
10855                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
10856
10857         if (spec->kctl_alloc)
10858                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10859
10860         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
10861
10862         spec->num_mux_defs = 1;
10863         spec->input_mux = &spec->private_imux;
10864
10865         spec->adc_nids = alc861_adc_nids;
10866         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
10867         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
10868         spec->num_mixers++;
10869
10870         return 1;
10871 }
10872
10873 /* additional initialization for auto-configuration model */
10874 static void alc861_auto_init(struct hda_codec *codec)
10875 {
10876         alc861_auto_init_multi_out(codec);
10877         alc861_auto_init_hp_out(codec);
10878         alc861_auto_init_analog_input(codec);
10879 }
10880
10881 #ifdef CONFIG_SND_HDA_POWER_SAVE
10882 static struct hda_amp_list alc861_loopbacks[] = {
10883         { 0x15, HDA_INPUT, 0 },
10884         { 0x15, HDA_INPUT, 1 },
10885         { 0x15, HDA_INPUT, 2 },
10886         { 0x15, HDA_INPUT, 3 },
10887         { } /* end */
10888 };
10889 #endif
10890
10891
10892 /*
10893  * configuration and preset
10894  */
10895 static const char *alc861_models[ALC861_MODEL_LAST] = {
10896         [ALC861_3ST]            = "3stack",
10897         [ALC660_3ST]            = "3stack-660",
10898         [ALC861_3ST_DIG]        = "3stack-dig",
10899         [ALC861_6ST_DIG]        = "6stack-dig",
10900         [ALC861_UNIWILL_M31]    = "uniwill-m31",
10901         [ALC861_TOSHIBA]        = "toshiba",
10902         [ALC861_ASUS]           = "asus",
10903         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
10904         [ALC861_AUTO]           = "auto",
10905 };
10906
10907 static struct snd_pci_quirk alc861_cfg_tbl[] = {
10908         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
10909         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
10910         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
10911         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
10912         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
10913         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
10914         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
10915         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
10916         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
10917          *        Any other models that need this preset?
10918          */
10919         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
10920         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
10921         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
10922         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
10923         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
10924         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
10925         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
10926         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
10927         {}
10928 };
10929
10930 static struct alc_config_preset alc861_presets[] = {
10931         [ALC861_3ST] = {
10932                 .mixers = { alc861_3ST_mixer },
10933                 .init_verbs = { alc861_threestack_init_verbs },
10934                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10935                 .dac_nids = alc861_dac_nids,
10936                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10937                 .channel_mode = alc861_threestack_modes,
10938                 .need_dac_fix = 1,
10939                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10940                 .adc_nids = alc861_adc_nids,
10941                 .input_mux = &alc861_capture_source,
10942         },
10943         [ALC861_3ST_DIG] = {
10944                 .mixers = { alc861_base_mixer },
10945                 .init_verbs = { alc861_threestack_init_verbs },
10946                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10947                 .dac_nids = alc861_dac_nids,
10948                 .dig_out_nid = ALC861_DIGOUT_NID,
10949                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10950                 .channel_mode = alc861_threestack_modes,
10951                 .need_dac_fix = 1,
10952                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10953                 .adc_nids = alc861_adc_nids,
10954                 .input_mux = &alc861_capture_source,
10955         },
10956         [ALC861_6ST_DIG] = {
10957                 .mixers = { alc861_base_mixer },
10958                 .init_verbs = { alc861_base_init_verbs },
10959                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10960                 .dac_nids = alc861_dac_nids,
10961                 .dig_out_nid = ALC861_DIGOUT_NID,
10962                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
10963                 .channel_mode = alc861_8ch_modes,
10964                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10965                 .adc_nids = alc861_adc_nids,
10966                 .input_mux = &alc861_capture_source,
10967         },
10968         [ALC660_3ST] = {
10969                 .mixers = { alc861_3ST_mixer },
10970                 .init_verbs = { alc861_threestack_init_verbs },
10971                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
10972                 .dac_nids = alc660_dac_nids,
10973                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10974                 .channel_mode = alc861_threestack_modes,
10975                 .need_dac_fix = 1,
10976                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10977                 .adc_nids = alc861_adc_nids,
10978                 .input_mux = &alc861_capture_source,
10979         },
10980         [ALC861_UNIWILL_M31] = {
10981                 .mixers = { alc861_uniwill_m31_mixer },
10982                 .init_verbs = { alc861_uniwill_m31_init_verbs },
10983                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10984                 .dac_nids = alc861_dac_nids,
10985                 .dig_out_nid = ALC861_DIGOUT_NID,
10986                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
10987                 .channel_mode = alc861_uniwill_m31_modes,
10988                 .need_dac_fix = 1,
10989                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10990                 .adc_nids = alc861_adc_nids,
10991                 .input_mux = &alc861_capture_source,
10992         },
10993         [ALC861_TOSHIBA] = {
10994                 .mixers = { alc861_toshiba_mixer },
10995                 .init_verbs = { alc861_base_init_verbs,
10996                                 alc861_toshiba_init_verbs },
10997                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10998                 .dac_nids = alc861_dac_nids,
10999                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11000                 .channel_mode = alc883_3ST_2ch_modes,
11001                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11002                 .adc_nids = alc861_adc_nids,
11003                 .input_mux = &alc861_capture_source,
11004                 .unsol_event = alc861_toshiba_unsol_event,
11005                 .init_hook = alc861_toshiba_automute,
11006         },
11007         [ALC861_ASUS] = {
11008                 .mixers = { alc861_asus_mixer },
11009                 .init_verbs = { alc861_asus_init_verbs },
11010                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11011                 .dac_nids = alc861_dac_nids,
11012                 .dig_out_nid = ALC861_DIGOUT_NID,
11013                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11014                 .channel_mode = alc861_asus_modes,
11015                 .need_dac_fix = 1,
11016                 .hp_nid = 0x06,
11017                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11018                 .adc_nids = alc861_adc_nids,
11019                 .input_mux = &alc861_capture_source,
11020         },
11021         [ALC861_ASUS_LAPTOP] = {
11022                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11023                 .init_verbs = { alc861_asus_init_verbs,
11024                                 alc861_asus_laptop_init_verbs },
11025                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11026                 .dac_nids = alc861_dac_nids,
11027                 .dig_out_nid = ALC861_DIGOUT_NID,
11028                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11029                 .channel_mode = alc883_3ST_2ch_modes,
11030                 .need_dac_fix = 1,
11031                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11032                 .adc_nids = alc861_adc_nids,
11033                 .input_mux = &alc861_capture_source,
11034         },
11035 };
11036
11037
11038 static int patch_alc861(struct hda_codec *codec)
11039 {
11040         struct alc_spec *spec;
11041         int board_config;
11042         int err;
11043
11044         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11045         if (spec == NULL)
11046                 return -ENOMEM;
11047
11048         codec->spec = spec;
11049
11050         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11051                                                   alc861_models,
11052                                                   alc861_cfg_tbl);
11053
11054         if (board_config < 0) {
11055                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11056                        "trying auto-probe from BIOS...\n");
11057                 board_config = ALC861_AUTO;
11058         }
11059
11060         if (board_config == ALC861_AUTO) {
11061                 /* automatic parse from the BIOS config */
11062                 err = alc861_parse_auto_config(codec);
11063                 if (err < 0) {
11064                         alc_free(codec);
11065                         return err;
11066                 } else if (!err) {
11067                         printk(KERN_INFO
11068                                "hda_codec: Cannot set up configuration "
11069                                "from BIOS.  Using base mode...\n");
11070                    board_config = ALC861_3ST_DIG;
11071                 }
11072         }
11073
11074         if (board_config != ALC861_AUTO)
11075                 setup_preset(spec, &alc861_presets[board_config]);
11076
11077         spec->stream_name_analog = "ALC861 Analog";
11078         spec->stream_analog_playback = &alc861_pcm_analog_playback;
11079         spec->stream_analog_capture = &alc861_pcm_analog_capture;
11080
11081         spec->stream_name_digital = "ALC861 Digital";
11082         spec->stream_digital_playback = &alc861_pcm_digital_playback;
11083         spec->stream_digital_capture = &alc861_pcm_digital_capture;
11084
11085         codec->patch_ops = alc_patch_ops;
11086         if (board_config == ALC861_AUTO)
11087                 spec->init_hook = alc861_auto_init;
11088 #ifdef CONFIG_SND_HDA_POWER_SAVE
11089         if (!spec->loopback.amplist)
11090                 spec->loopback.amplist = alc861_loopbacks;
11091 #endif
11092                 
11093         return 0;
11094 }
11095
11096 /*
11097  * ALC861-VD support
11098  *
11099  * Based on ALC882
11100  *
11101  * In addition, an independent DAC
11102  */
11103 #define ALC861VD_DIGOUT_NID     0x06
11104
11105 static hda_nid_t alc861vd_dac_nids[4] = {
11106         /* front, surr, clfe, side surr */
11107         0x02, 0x03, 0x04, 0x05
11108 };
11109
11110 /* dac_nids for ALC660vd are in a different order - according to
11111  * Realtek's driver.
11112  * This should probably tesult in a different mixer for 6stack models
11113  * of ALC660vd codecs, but for now there is only 3stack mixer
11114  * - and it is the same as in 861vd.
11115  * adc_nids in ALC660vd are (is) the same as in 861vd
11116  */
11117 static hda_nid_t alc660vd_dac_nids[3] = {
11118         /* front, rear, clfe, rear_surr */
11119         0x02, 0x04, 0x03
11120 };
11121
11122 static hda_nid_t alc861vd_adc_nids[1] = {
11123         /* ADC0 */
11124         0x09,
11125 };
11126
11127 /* input MUX */
11128 /* FIXME: should be a matrix-type input source selection */
11129 static struct hda_input_mux alc861vd_capture_source = {
11130         .num_items = 4,
11131         .items = {
11132                 { "Mic", 0x0 },
11133                 { "Front Mic", 0x1 },
11134                 { "Line", 0x2 },
11135                 { "CD", 0x4 },
11136         },
11137 };
11138
11139 static struct hda_input_mux alc861vd_dallas_capture_source = {
11140         .num_items = 3,
11141         .items = {
11142                 { "Front Mic", 0x0 },
11143                 { "ATAPI Mic", 0x1 },
11144                 { "Line In", 0x5 },
11145         },
11146 };
11147
11148 static struct hda_input_mux alc861vd_hp_capture_source = {
11149         .num_items = 2,
11150         .items = {
11151                 { "Front Mic", 0x0 },
11152                 { "ATAPI Mic", 0x1 },
11153         },
11154 };
11155
11156 #define alc861vd_mux_enum_info alc_mux_enum_info
11157 #define alc861vd_mux_enum_get alc_mux_enum_get
11158
11159 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11160                                 struct snd_ctl_elem_value *ucontrol)
11161 {
11162         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11163         struct alc_spec *spec = codec->spec;
11164         const struct hda_input_mux *imux = spec->input_mux;
11165         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11166         static hda_nid_t capture_mixers[1] = { 0x22 };
11167         hda_nid_t nid = capture_mixers[adc_idx];
11168         unsigned int *cur_val = &spec->cur_mux[adc_idx];
11169         unsigned int i, idx;
11170
11171         idx = ucontrol->value.enumerated.item[0];
11172         if (idx >= imux->num_items)
11173                 idx = imux->num_items - 1;
11174         if (*cur_val == idx)
11175                 return 0;
11176         for (i = 0; i < imux->num_items; i++) {
11177                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11178                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11179                                          imux->items[i].index,
11180                                          HDA_AMP_MUTE, v);
11181         }
11182         *cur_val = idx;
11183         return 1;
11184 }
11185
11186 /*
11187  * 2ch mode
11188  */
11189 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11190         { 2, NULL }
11191 };
11192
11193 /*
11194  * 6ch mode
11195  */
11196 static struct hda_verb alc861vd_6stack_ch6_init[] = {
11197         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11198         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11199         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11200         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11201         { } /* end */
11202 };
11203
11204 /*
11205  * 8ch mode
11206  */
11207 static struct hda_verb alc861vd_6stack_ch8_init[] = {
11208         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11209         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11210         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11211         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11212         { } /* end */
11213 };
11214
11215 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11216         { 6, alc861vd_6stack_ch6_init },
11217         { 8, alc861vd_6stack_ch8_init },
11218 };
11219
11220 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11221         {
11222                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11223                 .name = "Channel Mode",
11224                 .info = alc_ch_mode_info,
11225                 .get = alc_ch_mode_get,
11226                 .put = alc_ch_mode_put,
11227         },
11228         { } /* end */
11229 };
11230
11231 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11232         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11233         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11234
11235         {
11236                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11237                 /* The multiple "Capture Source" controls confuse alsamixer
11238                  * So call somewhat different..
11239                  *FIXME: the controls appear in the "playback" view!
11240                  */
11241                 /* .name = "Capture Source", */
11242                 .name = "Input Source",
11243                 .count = 1,
11244                 .info = alc861vd_mux_enum_info,
11245                 .get = alc861vd_mux_enum_get,
11246                 .put = alc861vd_mux_enum_put,
11247         },
11248         { } /* end */
11249 };
11250
11251 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11252  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11253  */
11254 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11255         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11256         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11257
11258         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11259         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11260
11261         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11262                                 HDA_OUTPUT),
11263         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11264                                 HDA_OUTPUT),
11265         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11266         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11267
11268         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11269         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11270
11271         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11272
11273         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11274         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11275         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11276
11277         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11278         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11279         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11280
11281         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11282         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11283
11284         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11285         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11286
11287         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11288         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11289
11290         { } /* end */
11291 };
11292
11293 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11294         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11295         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11296
11297         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11298
11299         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11300         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11301         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11302
11303         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11304         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11305         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11306
11307         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11308         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11309
11310         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11311         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11312
11313         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11314         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11315
11316         { } /* end */
11317 };
11318
11319 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11320         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11321         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11322         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11323
11324         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11325
11326         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11327         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11328         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11329
11330         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11331         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11332         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11333
11334         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11335         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11336
11337         { } /* end */
11338 };
11339
11340 /* Pin assignment: Front=0x14, HP = 0x15,
11341  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
11342  */
11343 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
11344         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11345         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11346         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11347         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11348         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11349         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11350         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11351         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11352         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
11353         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
11354         { } /* end */
11355 };
11356
11357 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
11358  *                 Front Mic=0x18, ATAPI Mic = 0x19,
11359  */
11360 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
11361         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11362         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11363         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11364         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11365         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11366         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11367         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11368         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11369         
11370         { } /* end */
11371 };
11372
11373 /*
11374  * generic initialization of ADC, input mixers and output mixers
11375  */
11376 static struct hda_verb alc861vd_volume_init_verbs[] = {
11377         /*
11378          * Unmute ADC0 and set the default input to mic-in
11379          */
11380         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11381         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11382
11383         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
11384          * the analog-loopback mixer widget
11385          */
11386         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11387         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11388         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11389         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11390         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11391         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11392
11393         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
11394         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11395         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11396         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11397         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11398
11399         /*
11400          * Set up output mixers (0x02 - 0x05)
11401          */
11402         /* set vol=0 to output mixers */
11403         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11404         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11405         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11406         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11407
11408         /* set up input amps for analog loopback */
11409         /* Amp Indices: DAC = 0, mixer = 1 */
11410         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11411         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11412         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11413         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11414         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11415         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11416         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11417         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11418
11419         { }
11420 };
11421
11422 /*
11423  * 3-stack pin configuration:
11424  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
11425  */
11426 static struct hda_verb alc861vd_3stack_init_verbs[] = {
11427         /*
11428          * Set pin mode and muting
11429          */
11430         /* set front pin widgets 0x14 for output */
11431         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11432         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11433         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11434
11435         /* Mic (rear) pin: input vref at 80% */
11436         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11437         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11438         /* Front Mic pin: input vref at 80% */
11439         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11440         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11441         /* Line In pin: input */
11442         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11443         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11444         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11445         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11446         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11447         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11448         /* CD pin widget for input */
11449         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11450
11451         { }
11452 };
11453
11454 /*
11455  * 6-stack pin configuration:
11456  */
11457 static struct hda_verb alc861vd_6stack_init_verbs[] = {
11458         /*
11459          * Set pin mode and muting
11460          */
11461         /* set front pin widgets 0x14 for output */
11462         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11463         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11464         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11465
11466         /* Rear Pin: output 1 (0x0d) */
11467         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11468         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11469         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11470         /* CLFE Pin: output 2 (0x0e) */
11471         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11472         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11473         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11474         /* Side Pin: output 3 (0x0f) */
11475         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11476         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11477         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11478
11479         /* Mic (rear) pin: input vref at 80% */
11480         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11481         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11482         /* Front Mic pin: input vref at 80% */
11483         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11484         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11485         /* Line In pin: input */
11486         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11487         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11488         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11489         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11490         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11491         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11492         /* CD pin widget for input */
11493         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11494
11495         { }
11496 };
11497
11498 static struct hda_verb alc861vd_eapd_verbs[] = {
11499         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11500         { }
11501 };
11502
11503 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11504         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11505         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11506         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11507         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11508         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
11509         {}
11510 };
11511
11512 /* toggle speaker-output according to the hp-jack state */
11513 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11514 {
11515         unsigned int present;
11516         unsigned char bits;
11517
11518         present = snd_hda_codec_read(codec, 0x1b, 0,
11519                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11520         bits = present ? HDA_AMP_MUTE : 0;
11521         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11522                                  HDA_AMP_MUTE, bits);
11523 }
11524
11525 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11526 {
11527         unsigned int present;
11528         unsigned char bits;
11529
11530         present = snd_hda_codec_read(codec, 0x18, 0,
11531                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11532         bits = present ? HDA_AMP_MUTE : 0;
11533         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11534                                  HDA_AMP_MUTE, bits);
11535 }
11536
11537 static void alc861vd_lenovo_automute(struct hda_codec *codec)
11538 {
11539         alc861vd_lenovo_hp_automute(codec);
11540         alc861vd_lenovo_mic_automute(codec);
11541 }
11542
11543 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11544                                         unsigned int res)
11545 {
11546         switch (res >> 26) {
11547         case ALC880_HP_EVENT:
11548                 alc861vd_lenovo_hp_automute(codec);
11549                 break;
11550         case ALC880_MIC_EVENT:
11551                 alc861vd_lenovo_mic_automute(codec);
11552                 break;
11553         }
11554 }
11555
11556 static struct hda_verb alc861vd_dallas_verbs[] = {
11557         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11558         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11559         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11560         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11561
11562         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11563         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11564         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11565         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11566         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11567         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11568         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11569         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11570         
11571         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11572         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11573         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11574         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11575         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11576         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11577         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11578         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11579
11580         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11581         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11582         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11583         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11584         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11585         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11586         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11587         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11588
11589         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11590         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11591         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11592         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11593
11594         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11595         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
11596         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11597
11598         { } /* end */
11599 };
11600
11601 /* toggle speaker-output according to the hp-jack state */
11602 static void alc861vd_dallas_automute(struct hda_codec *codec)
11603 {
11604         unsigned int present;
11605
11606         present = snd_hda_codec_read(codec, 0x15, 0,
11607                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11608         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11609                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11610 }
11611
11612 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11613 {
11614         if ((res >> 26) == ALC880_HP_EVENT)
11615                 alc861vd_dallas_automute(codec);
11616 }
11617
11618 #ifdef CONFIG_SND_HDA_POWER_SAVE
11619 #define alc861vd_loopbacks      alc880_loopbacks
11620 #endif
11621
11622 /* pcm configuration: identiacal with ALC880 */
11623 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
11624 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
11625 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
11626 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
11627
11628 /*
11629  * configuration and preset
11630  */
11631 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11632         [ALC660VD_3ST]          = "3stack-660",
11633         [ALC660VD_3ST_DIG]      = "3stack-660-digout",
11634         [ALC861VD_3ST]          = "3stack",
11635         [ALC861VD_3ST_DIG]      = "3stack-digout",
11636         [ALC861VD_6ST_DIG]      = "6stack-digout",
11637         [ALC861VD_LENOVO]       = "lenovo",
11638         [ALC861VD_DALLAS]       = "dallas",
11639         [ALC861VD_HP]           = "hp",
11640         [ALC861VD_AUTO]         = "auto",
11641 };
11642
11643 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
11644         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
11645         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
11646         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
11647         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
11648         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11649
11650         /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
11651         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
11652         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
11653         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11654         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
11655         SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
11656         SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
11657         SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
11658         SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
11659         {}
11660 };
11661
11662 static struct alc_config_preset alc861vd_presets[] = {
11663         [ALC660VD_3ST] = {
11664                 .mixers = { alc861vd_3st_mixer },
11665                 .init_verbs = { alc861vd_volume_init_verbs,
11666                                  alc861vd_3stack_init_verbs },
11667                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11668                 .dac_nids = alc660vd_dac_nids,
11669                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11670                 .adc_nids = alc861vd_adc_nids,
11671                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11672                 .channel_mode = alc861vd_3stack_2ch_modes,
11673                 .input_mux = &alc861vd_capture_source,
11674         },
11675         [ALC660VD_3ST_DIG] = {
11676                 .mixers = { alc861vd_3st_mixer },
11677                 .init_verbs = { alc861vd_volume_init_verbs,
11678                                  alc861vd_3stack_init_verbs },
11679                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11680                 .dac_nids = alc660vd_dac_nids,
11681                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11682                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11683                 .adc_nids = alc861vd_adc_nids,
11684                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11685                 .channel_mode = alc861vd_3stack_2ch_modes,
11686                 .input_mux = &alc861vd_capture_source,
11687         },
11688         [ALC861VD_3ST] = {
11689                 .mixers = { alc861vd_3st_mixer },
11690                 .init_verbs = { alc861vd_volume_init_verbs,
11691                                  alc861vd_3stack_init_verbs },
11692                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11693                 .dac_nids = alc861vd_dac_nids,
11694                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11695                 .channel_mode = alc861vd_3stack_2ch_modes,
11696                 .input_mux = &alc861vd_capture_source,
11697         },
11698         [ALC861VD_3ST_DIG] = {
11699                 .mixers = { alc861vd_3st_mixer },
11700                 .init_verbs = { alc861vd_volume_init_verbs,
11701                                  alc861vd_3stack_init_verbs },
11702                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11703                 .dac_nids = alc861vd_dac_nids,
11704                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11705                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11706                 .channel_mode = alc861vd_3stack_2ch_modes,
11707                 .input_mux = &alc861vd_capture_source,
11708         },
11709         [ALC861VD_6ST_DIG] = {
11710                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11711                 .init_verbs = { alc861vd_volume_init_verbs,
11712                                 alc861vd_6stack_init_verbs },
11713                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11714                 .dac_nids = alc861vd_dac_nids,
11715                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11716                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11717                 .channel_mode = alc861vd_6stack_modes,
11718                 .input_mux = &alc861vd_capture_source,
11719         },
11720         [ALC861VD_LENOVO] = {
11721                 .mixers = { alc861vd_lenovo_mixer },
11722                 .init_verbs = { alc861vd_volume_init_verbs,
11723                                 alc861vd_3stack_init_verbs,
11724                                 alc861vd_eapd_verbs,
11725                                 alc861vd_lenovo_unsol_verbs },
11726                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11727                 .dac_nids = alc660vd_dac_nids,
11728                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11729                 .adc_nids = alc861vd_adc_nids,
11730                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11731                 .channel_mode = alc861vd_3stack_2ch_modes,
11732                 .input_mux = &alc861vd_capture_source,
11733                 .unsol_event = alc861vd_lenovo_unsol_event,
11734                 .init_hook = alc861vd_lenovo_automute,
11735         },
11736         [ALC861VD_DALLAS] = {
11737                 .mixers = { alc861vd_dallas_mixer },
11738                 .init_verbs = { alc861vd_dallas_verbs },
11739                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11740                 .dac_nids = alc861vd_dac_nids,
11741                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11742                 .adc_nids = alc861vd_adc_nids,
11743                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11744                 .channel_mode = alc861vd_3stack_2ch_modes,
11745                 .input_mux = &alc861vd_dallas_capture_source,
11746                 .unsol_event = alc861vd_dallas_unsol_event,
11747                 .init_hook = alc861vd_dallas_automute,
11748         },
11749         [ALC861VD_HP] = {
11750                 .mixers = { alc861vd_hp_mixer },
11751                 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11752                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11753                 .dac_nids = alc861vd_dac_nids,
11754                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11755                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11756                 .adc_nids = alc861vd_adc_nids,
11757                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11758                 .channel_mode = alc861vd_3stack_2ch_modes,
11759                 .input_mux = &alc861vd_hp_capture_source,
11760                 .unsol_event = alc861vd_dallas_unsol_event,
11761                 .init_hook = alc861vd_dallas_automute,
11762         },              
11763 };
11764
11765 /*
11766  * BIOS auto configuration
11767  */
11768 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11769                                 hda_nid_t nid, int pin_type, int dac_idx)
11770 {
11771         /* set as output */
11772         snd_hda_codec_write(codec, nid, 0,
11773                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11774         snd_hda_codec_write(codec, nid, 0,
11775                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11776 }
11777
11778 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11779 {
11780         struct alc_spec *spec = codec->spec;
11781         int i;
11782
11783         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
11784         for (i = 0; i <= HDA_SIDE; i++) {
11785                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11786                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11787                 if (nid)
11788                         alc861vd_auto_set_output_and_unmute(codec, nid,
11789                                                             pin_type, i);
11790         }
11791 }
11792
11793
11794 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
11795 {
11796         struct alc_spec *spec = codec->spec;
11797         hda_nid_t pin;
11798
11799         pin = spec->autocfg.hp_pins[0];
11800         if (pin) /* connect to front and  use dac 0 */
11801                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11802 }
11803
11804 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
11805 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
11806
11807 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
11808 {
11809         struct alc_spec *spec = codec->spec;
11810         int i;
11811
11812         for (i = 0; i < AUTO_PIN_LAST; i++) {
11813                 hda_nid_t nid = spec->autocfg.input_pins[i];
11814                 if (alc861vd_is_input_pin(nid)) {
11815                         snd_hda_codec_write(codec, nid, 0,
11816                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
11817                                         i <= AUTO_PIN_FRONT_MIC ?
11818                                                         PIN_VREF80 : PIN_IN);
11819                         if (nid != ALC861VD_PIN_CD_NID)
11820                                 snd_hda_codec_write(codec, nid, 0,
11821                                                 AC_VERB_SET_AMP_GAIN_MUTE,
11822                                                 AMP_OUT_MUTE);
11823                 }
11824         }
11825 }
11826
11827 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
11828 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
11829
11830 /* add playback controls from the parsed DAC table */
11831 /* Based on ALC880 version. But ALC861VD has separate,
11832  * different NIDs for mute/unmute switch and volume control */
11833 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
11834                                              const struct auto_pin_cfg *cfg)
11835 {
11836         char name[32];
11837         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
11838         hda_nid_t nid_v, nid_s;
11839         int i, err;
11840
11841         for (i = 0; i < cfg->line_outs; i++) {
11842                 if (!spec->multiout.dac_nids[i])
11843                         continue;
11844                 nid_v = alc861vd_idx_to_mixer_vol(
11845                                 alc880_dac_to_idx(
11846                                         spec->multiout.dac_nids[i]));
11847                 nid_s = alc861vd_idx_to_mixer_switch(
11848                                 alc880_dac_to_idx(
11849                                         spec->multiout.dac_nids[i]));
11850
11851                 if (i == 2) {
11852                         /* Center/LFE */
11853                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11854                                           "Center Playback Volume",
11855                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
11856                                                               HDA_OUTPUT));
11857                         if (err < 0)
11858                                 return err;
11859                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11860                                           "LFE Playback Volume",
11861                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
11862                                                               HDA_OUTPUT));
11863                         if (err < 0)
11864                                 return err;
11865                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11866                                           "Center Playback Switch",
11867                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
11868                                                               HDA_INPUT));
11869                         if (err < 0)
11870                                 return err;
11871                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11872                                           "LFE Playback Switch",
11873                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
11874                                                               HDA_INPUT));
11875                         if (err < 0)
11876                                 return err;
11877                 } else {
11878                         sprintf(name, "%s Playback Volume", chname[i]);
11879                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11880                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
11881                                                               HDA_OUTPUT));
11882                         if (err < 0)
11883                                 return err;
11884                         sprintf(name, "%s Playback Switch", chname[i]);
11885                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11886                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
11887                                                               HDA_INPUT));
11888                         if (err < 0)
11889                                 return err;
11890                 }
11891         }
11892         return 0;
11893 }
11894
11895 /* add playback controls for speaker and HP outputs */
11896 /* Based on ALC880 version. But ALC861VD has separate,
11897  * different NIDs for mute/unmute switch and volume control */
11898 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
11899                                         hda_nid_t pin, const char *pfx)
11900 {
11901         hda_nid_t nid_v, nid_s;
11902         int err;
11903         char name[32];
11904
11905         if (!pin)
11906                 return 0;
11907
11908         if (alc880_is_fixed_pin(pin)) {
11909                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11910                 /* specify the DAC as the extra output */
11911                 if (!spec->multiout.hp_nid)
11912                         spec->multiout.hp_nid = nid_v;
11913                 else
11914                         spec->multiout.extra_out_nid[0] = nid_v;
11915                 /* control HP volume/switch on the output mixer amp */
11916                 nid_v = alc861vd_idx_to_mixer_vol(
11917                                 alc880_fixed_pin_idx(pin));
11918                 nid_s = alc861vd_idx_to_mixer_switch(
11919                                 alc880_fixed_pin_idx(pin));
11920
11921                 sprintf(name, "%s Playback Volume", pfx);
11922                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11923                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
11924                 if (err < 0)
11925                         return err;
11926                 sprintf(name, "%s Playback Switch", pfx);
11927                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11928                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
11929                 if (err < 0)
11930                         return err;
11931         } else if (alc880_is_multi_pin(pin)) {
11932                 /* set manual connection */
11933                 /* we have only a switch on HP-out PIN */
11934                 sprintf(name, "%s Playback Switch", pfx);
11935                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11936                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11937                 if (err < 0)
11938                         return err;
11939         }
11940         return 0;
11941 }
11942
11943 /* parse the BIOS configuration and set up the alc_spec
11944  * return 1 if successful, 0 if the proper config is not found,
11945  * or a negative error code
11946  * Based on ALC880 version - had to change it to override
11947  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
11948 static int alc861vd_parse_auto_config(struct hda_codec *codec)
11949 {
11950         struct alc_spec *spec = codec->spec;
11951         int err;
11952         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
11953
11954         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11955                                            alc861vd_ignore);
11956         if (err < 0)
11957                 return err;
11958         if (!spec->autocfg.line_outs)
11959                 return 0; /* can't find valid BIOS pin config */
11960
11961         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11962         if (err < 0)
11963                 return err;
11964         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
11965         if (err < 0)
11966                 return err;
11967         err = alc861vd_auto_create_extra_out(spec,
11968                                              spec->autocfg.speaker_pins[0],
11969                                              "Speaker");
11970         if (err < 0)
11971                 return err;
11972         err = alc861vd_auto_create_extra_out(spec,
11973                                              spec->autocfg.hp_pins[0],
11974                                              "Headphone");
11975         if (err < 0)
11976                 return err;
11977         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
11978         if (err < 0)
11979                 return err;
11980
11981         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11982
11983         if (spec->autocfg.dig_out_pin)
11984                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
11985
11986         if (spec->kctl_alloc)
11987                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11988
11989         spec->init_verbs[spec->num_init_verbs++]
11990                 = alc861vd_volume_init_verbs;
11991
11992         spec->num_mux_defs = 1;
11993         spec->input_mux = &spec->private_imux;
11994
11995         err = alc_auto_add_mic_boost(codec);
11996         if (err < 0)
11997                 return err;
11998
11999         return 1;
12000 }
12001
12002 /* additional initialization for auto-configuration model */
12003 static void alc861vd_auto_init(struct hda_codec *codec)
12004 {
12005         alc861vd_auto_init_multi_out(codec);
12006         alc861vd_auto_init_hp_out(codec);
12007         alc861vd_auto_init_analog_input(codec);
12008 }
12009
12010 static int patch_alc861vd(struct hda_codec *codec)
12011 {
12012         struct alc_spec *spec;
12013         int err, board_config;
12014
12015         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12016         if (spec == NULL)
12017                 return -ENOMEM;
12018
12019         codec->spec = spec;
12020
12021         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12022                                                   alc861vd_models,
12023                                                   alc861vd_cfg_tbl);
12024
12025         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12026                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12027                         "ALC861VD, trying auto-probe from BIOS...\n");
12028                 board_config = ALC861VD_AUTO;
12029         }
12030
12031         if (board_config == ALC861VD_AUTO) {
12032                 /* automatic parse from the BIOS config */
12033                 err = alc861vd_parse_auto_config(codec);
12034                 if (err < 0) {
12035                         alc_free(codec);
12036                         return err;
12037                 } else if (!err) {
12038                         printk(KERN_INFO
12039                                "hda_codec: Cannot set up configuration "
12040                                "from BIOS.  Using base mode...\n");
12041                         board_config = ALC861VD_3ST;
12042                 }
12043         }
12044
12045         if (board_config != ALC861VD_AUTO)
12046                 setup_preset(spec, &alc861vd_presets[board_config]);
12047
12048         spec->stream_name_analog = "ALC861VD Analog";
12049         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12050         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12051
12052         spec->stream_name_digital = "ALC861VD Digital";
12053         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12054         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12055
12056         spec->adc_nids = alc861vd_adc_nids;
12057         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12058
12059         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12060         spec->num_mixers++;
12061
12062         codec->patch_ops = alc_patch_ops;
12063
12064         if (board_config == ALC861VD_AUTO)
12065                 spec->init_hook = alc861vd_auto_init;
12066 #ifdef CONFIG_SND_HDA_POWER_SAVE
12067         if (!spec->loopback.amplist)
12068                 spec->loopback.amplist = alc861vd_loopbacks;
12069 #endif
12070
12071         return 0;
12072 }
12073
12074 /*
12075  * ALC662 support
12076  *
12077  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12078  * configuration.  Each pin widget can choose any input DACs and a mixer.
12079  * Each ADC is connected from a mixer of all inputs.  This makes possible
12080  * 6-channel independent captures.
12081  *
12082  * In addition, an independent DAC for the multi-playback (not used in this
12083  * driver yet).
12084  */
12085 #define ALC662_DIGOUT_NID       0x06
12086 #define ALC662_DIGIN_NID        0x0a
12087
12088 static hda_nid_t alc662_dac_nids[4] = {
12089         /* front, rear, clfe, rear_surr */
12090         0x02, 0x03, 0x04
12091 };
12092
12093 static hda_nid_t alc662_adc_nids[1] = {
12094         /* ADC1-2 */
12095         0x09,
12096 };
12097 /* input MUX */
12098 /* FIXME: should be a matrix-type input source selection */
12099
12100 static struct hda_input_mux alc662_capture_source = {
12101         .num_items = 4,
12102         .items = {
12103                 { "Mic", 0x0 },
12104                 { "Front Mic", 0x1 },
12105                 { "Line", 0x2 },
12106                 { "CD", 0x4 },
12107         },
12108 };
12109
12110 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12111         .num_items = 2,
12112         .items = {
12113                 { "Mic", 0x1 },
12114                 { "Line", 0x2 },
12115         },
12116 };
12117
12118 static struct hda_input_mux alc662_eeepc_capture_source = {
12119         .num_items = 2,
12120         .items = {
12121                 { "i-Mic", 0x1 },
12122                 { "e-Mic", 0x0 },
12123         },
12124 };
12125
12126 #define alc662_mux_enum_info alc_mux_enum_info
12127 #define alc662_mux_enum_get alc_mux_enum_get
12128
12129 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12130                                struct snd_ctl_elem_value *ucontrol)
12131 {
12132         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12133         struct alc_spec *spec = codec->spec;
12134         const struct hda_input_mux *imux = spec->input_mux;
12135         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
12136         static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
12137         hda_nid_t nid = capture_mixers[adc_idx];
12138         unsigned int *cur_val = &spec->cur_mux[adc_idx];
12139         unsigned int i, idx;
12140
12141         idx = ucontrol->value.enumerated.item[0];
12142         if (idx >= imux->num_items)
12143                 idx = imux->num_items - 1;
12144         if (*cur_val == idx)
12145                 return 0;
12146         for (i = 0; i < imux->num_items; i++) {
12147                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12148                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12149                                          imux->items[i].index,
12150                                          HDA_AMP_MUTE, v);
12151         }
12152         *cur_val = idx;
12153         return 1;
12154 }
12155 /*
12156  * 2ch mode
12157  */
12158 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12159         { 2, NULL }
12160 };
12161
12162 /*
12163  * 2ch mode
12164  */
12165 static struct hda_verb alc662_3ST_ch2_init[] = {
12166         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12167         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12168         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12169         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12170         { } /* end */
12171 };
12172
12173 /*
12174  * 6ch mode
12175  */
12176 static struct hda_verb alc662_3ST_ch6_init[] = {
12177         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12178         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12179         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12180         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12181         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12182         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12183         { } /* end */
12184 };
12185
12186 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12187         { 2, alc662_3ST_ch2_init },
12188         { 6, alc662_3ST_ch6_init },
12189 };
12190
12191 /*
12192  * 2ch mode
12193  */
12194 static struct hda_verb alc662_sixstack_ch6_init[] = {
12195         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12196         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12197         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12198         { } /* end */
12199 };
12200
12201 /*
12202  * 6ch mode
12203  */
12204 static struct hda_verb alc662_sixstack_ch8_init[] = {
12205         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12206         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12207         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12208         { } /* end */
12209 };
12210
12211 static struct hda_channel_mode alc662_5stack_modes[2] = {
12212         { 2, alc662_sixstack_ch6_init },
12213         { 6, alc662_sixstack_ch8_init },
12214 };
12215
12216 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12217  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12218  */
12219
12220 static struct snd_kcontrol_new alc662_base_mixer[] = {
12221         /* output mixer control */
12222         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12223         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12224         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12225         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12226         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12227         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12228         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12229         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12230         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12231
12232         /*Input mixer control */
12233         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12234         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12235         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12236         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12237         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12238         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12239         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12240         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
12241
12242         /* Capture mixer control */
12243         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12244         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12245         {
12246                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12247                 .name = "Capture Source",
12248                 .count = 1,
12249                 .info = alc_mux_enum_info,
12250                 .get = alc_mux_enum_get,
12251                 .put = alc_mux_enum_put,
12252         },
12253         { } /* end */
12254 };
12255
12256 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12257         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12258         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12259         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12260         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12261         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12262         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12263         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12264         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12265         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12266         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12267         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12268         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12269         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12270         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12271         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12272         {
12273                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12274                 /* .name = "Capture Source", */
12275                 .name = "Input Source",
12276                 .count = 1,
12277                 .info = alc662_mux_enum_info,
12278                 .get = alc662_mux_enum_get,
12279                 .put = alc662_mux_enum_put,
12280         },
12281         { } /* end */
12282 };
12283
12284 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12285         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12286         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12287         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12288         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12289         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12290         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12291         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12292         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12293         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12294         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12295         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12296         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12297         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12298         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12299         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12300         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12301         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12302         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12303         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12304         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12305         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12306         {
12307                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12308                 /* .name = "Capture Source", */
12309                 .name = "Input Source",
12310                 .count = 1,
12311                 .info = alc662_mux_enum_info,
12312                 .get = alc662_mux_enum_get,
12313                 .put = alc662_mux_enum_put,
12314         },
12315         { } /* end */
12316 };
12317
12318 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12319         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12320         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12321         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12322         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
12323         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12324         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12325         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12326         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12327         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12328         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12329         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12330         {
12331                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12332                 /* .name = "Capture Source", */
12333                 .name = "Input Source",
12334                 .count = 1,
12335                 .info = alc662_mux_enum_info,
12336                 .get = alc662_mux_enum_get,
12337                 .put = alc662_mux_enum_put,
12338         },
12339         { } /* end */
12340 };
12341
12342 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
12343         HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12344
12345         HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12346         HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12347
12348         HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12349         HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12350         HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12351
12352         HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12353         HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12354         HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12355         { } /* end */
12356 };
12357
12358 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12359         {
12360                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12361                 .name = "Channel Mode",
12362                 .info = alc_ch_mode_info,
12363                 .get = alc_ch_mode_get,
12364                 .put = alc_ch_mode_put,
12365         },
12366         { } /* end */
12367 };
12368
12369 static struct hda_verb alc662_init_verbs[] = {
12370         /* ADC: mute amp left and right */
12371         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12372         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12373         /* Front mixer: unmute input/output amp left and right (volume = 0) */
12374
12375         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12376         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12377         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12378         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12379         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12380
12381         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12382         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12383         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12384         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12385         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12386         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12387
12388         /* Front Pin: output 0 (0x0c) */
12389         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12390         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12391
12392         /* Rear Pin: output 1 (0x0d) */
12393         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12394         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12395
12396         /* CLFE Pin: output 2 (0x0e) */
12397         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12398         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12399
12400         /* Mic (rear) pin: input vref at 80% */
12401         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12402         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12403         /* Front Mic pin: input vref at 80% */
12404         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12405         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12406         /* Line In pin: input */
12407         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12408         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12409         /* Line-2 In: Headphone output (output 0 - 0x0c) */
12410         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12411         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12412         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12413         /* CD pin widget for input */
12414         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12415
12416         /* FIXME: use matrix-type input source selection */
12417         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12418         /* Input mixer */
12419         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12420         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12421         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12422         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12423
12424         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12425         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12426         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12427         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12428         { }
12429 };
12430
12431 static struct hda_verb alc662_sue_init_verbs[] = {
12432         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
12433         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
12434         {}
12435 };
12436
12437 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12438         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12439         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12440         {}
12441 };
12442
12443 /*
12444  * generic initialization of ADC, input mixers and output mixers
12445  */
12446 static struct hda_verb alc662_auto_init_verbs[] = {
12447         /*
12448          * Unmute ADC and set the default input to mic-in
12449          */
12450         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12451         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12452
12453         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12454          * mixer widget
12455          * Note: PASD motherboards uses the Line In 2 as the input for front
12456          * panel mic (mic 2)
12457          */
12458         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12459         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12460         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12461         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12462         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12463         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12464
12465         /*
12466          * Set up output mixers (0x0c - 0x0f)
12467          */
12468         /* set vol=0 to output mixers */
12469         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12470         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12471         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12472
12473         /* set up input amps for analog loopback */
12474         /* Amp Indices: DAC = 0, mixer = 1 */
12475         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12476         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12477         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12478         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12479         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12480         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12481
12482
12483         /* FIXME: use matrix-type input source selection */
12484         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12485         /* Input mixer */
12486         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12487         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12488         { }
12489 };
12490
12491 /* capture mixer elements */
12492 static struct snd_kcontrol_new alc662_capture_mixer[] = {
12493         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12494         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12495         {
12496                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12497                 /* The multiple "Capture Source" controls confuse alsamixer
12498                  * So call somewhat different..
12499                  * FIXME: the controls appear in the "playback" view!
12500                  */
12501                 /* .name = "Capture Source", */
12502                 .name = "Input Source",
12503                 .count = 1,
12504                 .info = alc882_mux_enum_info,
12505                 .get = alc882_mux_enum_get,
12506                 .put = alc882_mux_enum_put,
12507         },
12508         { } /* end */
12509 };
12510
12511 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12512 {
12513         unsigned int present;
12514         unsigned char bits;
12515
12516         present = snd_hda_codec_read(codec, 0x14, 0,
12517                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12518         bits = present ? HDA_AMP_MUTE : 0;
12519         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12520                                  HDA_AMP_MUTE, bits);
12521 }
12522
12523 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12524 {
12525         unsigned int present;
12526         unsigned char bits;
12527
12528         present = snd_hda_codec_read(codec, 0x1b, 0,
12529                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12530         bits = present ? HDA_AMP_MUTE : 0;
12531         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12532                                  HDA_AMP_MUTE, bits);
12533         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12534                                  HDA_AMP_MUTE, bits);
12535 }
12536
12537 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12538                                            unsigned int res)
12539 {
12540         if ((res >> 26) == ALC880_HP_EVENT)
12541                 alc662_lenovo_101e_all_automute(codec);
12542         if ((res >> 26) == ALC880_FRONT_EVENT)
12543                 alc662_lenovo_101e_ispeaker_automute(codec);
12544 }
12545
12546 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12547 {
12548         unsigned int present;
12549
12550         present = snd_hda_codec_read(codec, 0x18, 0,
12551                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12552         snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12553                             0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12554         snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12555                             0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12556         snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12557                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12558         snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12559                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12560 }
12561
12562 /* unsolicited event for HP jack sensing */
12563 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12564                                      unsigned int res)
12565 {
12566         if ((res >> 26) == ALC880_HP_EVENT)
12567                 alc262_hippo1_automute( codec );
12568
12569         if ((res >> 26) == ALC880_MIC_EVENT)
12570                 alc662_eeepc_mic_automute(codec);
12571 }
12572
12573 static void alc662_eeepc_inithook(struct hda_codec *codec)
12574 {
12575         alc262_hippo1_automute( codec );
12576         alc662_eeepc_mic_automute(codec);
12577 }
12578
12579 #ifdef CONFIG_SND_HDA_POWER_SAVE
12580 #define alc662_loopbacks        alc880_loopbacks
12581 #endif
12582
12583
12584 /* pcm configuration: identiacal with ALC880 */
12585 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
12586 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
12587 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
12588 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
12589
12590 /*
12591  * configuration and preset
12592  */
12593 static const char *alc662_models[ALC662_MODEL_LAST] = {
12594         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
12595         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
12596         [ALC662_3ST_6ch]        = "3stack-6ch",
12597         [ALC662_5ST_DIG]        = "6stack-dig",
12598         [ALC662_LENOVO_101E]    = "lenovo-101e",
12599         [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
12600         [ALC662_AUTO]           = "auto",
12601 };
12602
12603 static struct snd_pci_quirk alc662_cfg_tbl[] = {
12604         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12605         SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12606         {}
12607 };
12608
12609 static struct alc_config_preset alc662_presets[] = {
12610         [ALC662_3ST_2ch_DIG] = {
12611                 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
12612                 .init_verbs = { alc662_init_verbs },
12613                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12614                 .dac_nids = alc662_dac_nids,
12615                 .dig_out_nid = ALC662_DIGOUT_NID,
12616                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12617                 .adc_nids = alc662_adc_nids,
12618                 .dig_in_nid = ALC662_DIGIN_NID,
12619                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12620                 .channel_mode = alc662_3ST_2ch_modes,
12621                 .input_mux = &alc662_capture_source,
12622         },
12623         [ALC662_3ST_6ch_DIG] = {
12624                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12625                             alc662_capture_mixer },
12626                 .init_verbs = { alc662_init_verbs },
12627                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12628                 .dac_nids = alc662_dac_nids,
12629                 .dig_out_nid = ALC662_DIGOUT_NID,
12630                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12631                 .adc_nids = alc662_adc_nids,
12632                 .dig_in_nid = ALC662_DIGIN_NID,
12633                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12634                 .channel_mode = alc662_3ST_6ch_modes,
12635                 .need_dac_fix = 1,
12636                 .input_mux = &alc662_capture_source,
12637         },
12638         [ALC662_3ST_6ch] = {
12639                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12640                             alc662_capture_mixer },
12641                 .init_verbs = { alc662_init_verbs },
12642                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12643                 .dac_nids = alc662_dac_nids,
12644                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12645                 .adc_nids = alc662_adc_nids,
12646                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12647                 .channel_mode = alc662_3ST_6ch_modes,
12648                 .need_dac_fix = 1,
12649                 .input_mux = &alc662_capture_source,
12650         },
12651         [ALC662_5ST_DIG] = {
12652                 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
12653                             alc662_capture_mixer },
12654                 .init_verbs = { alc662_init_verbs },
12655                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12656                 .dac_nids = alc662_dac_nids,
12657                 .dig_out_nid = ALC662_DIGOUT_NID,
12658                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12659                 .adc_nids = alc662_adc_nids,
12660                 .dig_in_nid = ALC662_DIGIN_NID,
12661                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12662                 .channel_mode = alc662_5stack_modes,
12663                 .input_mux = &alc662_capture_source,
12664         },
12665         [ALC662_LENOVO_101E] = {
12666                 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
12667                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12668                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12669                 .dac_nids = alc662_dac_nids,
12670                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12671                 .adc_nids = alc662_adc_nids,
12672                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12673                 .channel_mode = alc662_3ST_2ch_modes,
12674                 .input_mux = &alc662_lenovo_101e_capture_source,
12675                 .unsol_event = alc662_lenovo_101e_unsol_event,
12676                 .init_hook = alc662_lenovo_101e_all_automute,
12677         },
12678         [ALC662_ASUS_EEEPC_P701] = {
12679                 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12680                 .init_verbs = { alc662_init_verbs,
12681                                 alc662_eeepc_sue_init_verbs },
12682                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12683                 .dac_nids = alc662_dac_nids,
12684                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12685                 .adc_nids = alc662_adc_nids,
12686                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12687                 .channel_mode = alc662_3ST_2ch_modes,
12688                 .input_mux = &alc662_eeepc_capture_source,
12689                 .unsol_event = alc662_eeepc_unsol_event,
12690                 .init_hook = alc662_eeepc_inithook,
12691         },
12692
12693 };
12694
12695
12696 /*
12697  * BIOS auto configuration
12698  */
12699
12700 /* add playback controls from the parsed DAC table */
12701 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12702                                              const struct auto_pin_cfg *cfg)
12703 {
12704         char name[32];
12705         static const char *chname[4] = {
12706                 "Front", "Surround", NULL /*CLFE*/, "Side"
12707         };
12708         hda_nid_t nid;
12709         int i, err;
12710
12711         for (i = 0; i < cfg->line_outs; i++) {
12712                 if (!spec->multiout.dac_nids[i])
12713                         continue;
12714                 nid = alc880_idx_to_dac(i);
12715                 if (i == 2) {
12716                         /* Center/LFE */
12717                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
12718                                           "Center Playback Volume",
12719                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12720                                                               HDA_OUTPUT));
12721                         if (err < 0)
12722                                 return err;
12723                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
12724                                           "LFE Playback Volume",
12725                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12726                                                               HDA_OUTPUT));
12727                         if (err < 0)
12728                                 return err;
12729                         err = add_control(spec, ALC_CTL_BIND_MUTE,
12730                                           "Center Playback Switch",
12731                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12732                                                               HDA_INPUT));
12733                         if (err < 0)
12734                                 return err;
12735                         err = add_control(spec, ALC_CTL_BIND_MUTE,
12736                                           "LFE Playback Switch",
12737                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12738                                                               HDA_INPUT));
12739                         if (err < 0)
12740                                 return err;
12741                 } else {
12742                         sprintf(name, "%s Playback Volume", chname[i]);
12743                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12744                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12745                                                               HDA_OUTPUT));
12746                         if (err < 0)
12747                                 return err;
12748                         sprintf(name, "%s Playback Switch", chname[i]);
12749                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12750                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12751                                                               HDA_INPUT));
12752                         if (err < 0)
12753                                 return err;
12754                 }
12755         }
12756         return 0;
12757 }
12758
12759 /* add playback controls for speaker and HP outputs */
12760 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12761                                         const char *pfx)
12762 {
12763         hda_nid_t nid;
12764         int err;
12765         char name[32];
12766
12767         if (!pin)
12768                 return 0;
12769
12770         if (alc880_is_fixed_pin(pin)) {
12771                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12772                 /* printk("DAC nid=%x\n",nid); */
12773                 /* specify the DAC as the extra output */
12774                 if (!spec->multiout.hp_nid)
12775                         spec->multiout.hp_nid = nid;
12776                 else
12777                         spec->multiout.extra_out_nid[0] = nid;
12778                 /* control HP volume/switch on the output mixer amp */
12779                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12780                 sprintf(name, "%s Playback Volume", pfx);
12781                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12782                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12783                 if (err < 0)
12784                         return err;
12785                 sprintf(name, "%s Playback Switch", pfx);
12786                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12787                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12788                 if (err < 0)
12789                         return err;
12790         } else if (alc880_is_multi_pin(pin)) {
12791                 /* set manual connection */
12792                 /* we have only a switch on HP-out PIN */
12793                 sprintf(name, "%s Playback Switch", pfx);
12794                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12795                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12796                 if (err < 0)
12797                         return err;
12798         }
12799         return 0;
12800 }
12801
12802 /* create playback/capture controls for input pins */
12803 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12804                                                 const struct auto_pin_cfg *cfg)
12805 {
12806         struct hda_input_mux *imux = &spec->private_imux;
12807         int i, err, idx;
12808
12809         for (i = 0; i < AUTO_PIN_LAST; i++) {
12810                 if (alc880_is_input_pin(cfg->input_pins[i])) {
12811                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
12812                         err = new_analog_input(spec, cfg->input_pins[i],
12813                                                auto_pin_cfg_labels[i],
12814                                                idx, 0x0b);
12815                         if (err < 0)
12816                                 return err;
12817                         imux->items[imux->num_items].label =
12818                                 auto_pin_cfg_labels[i];
12819                         imux->items[imux->num_items].index =
12820                                 alc880_input_pin_idx(cfg->input_pins[i]);
12821                         imux->num_items++;
12822                 }
12823         }
12824         return 0;
12825 }
12826
12827 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12828                                               hda_nid_t nid, int pin_type,
12829                                               int dac_idx)
12830 {
12831         /* set as output */
12832         snd_hda_codec_write(codec, nid, 0,
12833                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12834         snd_hda_codec_write(codec, nid, 0,
12835                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12836         /* need the manual connection? */
12837         if (alc880_is_multi_pin(nid)) {
12838                 struct alc_spec *spec = codec->spec;
12839                 int idx = alc880_multi_pin_idx(nid);
12840                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
12841                                     AC_VERB_SET_CONNECT_SEL,
12842                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
12843         }
12844 }
12845
12846 static void alc662_auto_init_multi_out(struct hda_codec *codec)
12847 {
12848         struct alc_spec *spec = codec->spec;
12849         int i;
12850
12851         for (i = 0; i <= HDA_SIDE; i++) {
12852                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12853                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12854                 if (nid)
12855                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
12856                                                           i);
12857         }
12858 }
12859
12860 static void alc662_auto_init_hp_out(struct hda_codec *codec)
12861 {
12862         struct alc_spec *spec = codec->spec;
12863         hda_nid_t pin;
12864
12865         pin = spec->autocfg.hp_pins[0];
12866         if (pin) /* connect to front */
12867                 /* use dac 0 */
12868                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12869 }
12870
12871 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
12872 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
12873
12874 static void alc662_auto_init_analog_input(struct hda_codec *codec)
12875 {
12876         struct alc_spec *spec = codec->spec;
12877         int i;
12878
12879         for (i = 0; i < AUTO_PIN_LAST; i++) {
12880                 hda_nid_t nid = spec->autocfg.input_pins[i];
12881                 if (alc662_is_input_pin(nid)) {
12882                         snd_hda_codec_write(codec, nid, 0,
12883                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
12884                                             (i <= AUTO_PIN_FRONT_MIC ?
12885                                              PIN_VREF80 : PIN_IN));
12886                         if (nid != ALC662_PIN_CD_NID)
12887                                 snd_hda_codec_write(codec, nid, 0,
12888                                                     AC_VERB_SET_AMP_GAIN_MUTE,
12889                                                     AMP_OUT_MUTE);
12890                 }
12891         }
12892 }
12893
12894 static int alc662_parse_auto_config(struct hda_codec *codec)
12895 {
12896         struct alc_spec *spec = codec->spec;
12897         int err;
12898         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
12899
12900         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12901                                            alc662_ignore);
12902         if (err < 0)
12903                 return err;
12904         if (!spec->autocfg.line_outs)
12905                 return 0; /* can't find valid BIOS pin config */
12906
12907         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12908         if (err < 0)
12909                 return err;
12910         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
12911         if (err < 0)
12912                 return err;
12913         err = alc662_auto_create_extra_out(spec,
12914                                            spec->autocfg.speaker_pins[0],
12915                                            "Speaker");
12916         if (err < 0)
12917                 return err;
12918         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
12919                                            "Headphone");
12920         if (err < 0)
12921                 return err;
12922         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
12923         if (err < 0)
12924                 return err;
12925
12926         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12927
12928         if (spec->autocfg.dig_out_pin)
12929                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
12930
12931         if (spec->kctl_alloc)
12932                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12933
12934         spec->num_mux_defs = 1;
12935         spec->input_mux = &spec->private_imux;
12936         
12937         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
12938         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
12939         spec->num_mixers++;
12940         return 1;
12941 }
12942
12943 /* additional initialization for auto-configuration model */
12944 static void alc662_auto_init(struct hda_codec *codec)
12945 {
12946         alc662_auto_init_multi_out(codec);
12947         alc662_auto_init_hp_out(codec);
12948         alc662_auto_init_analog_input(codec);
12949 }
12950
12951 static int patch_alc662(struct hda_codec *codec)
12952 {
12953         struct alc_spec *spec;
12954         int err, board_config;
12955
12956         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12957         if (!spec)
12958                 return -ENOMEM;
12959
12960         codec->spec = spec;
12961
12962         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
12963                                                   alc662_models,
12964                                                   alc662_cfg_tbl);
12965         if (board_config < 0) {
12966                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
12967                        "trying auto-probe from BIOS...\n");
12968                 board_config = ALC662_AUTO;
12969         }
12970
12971         if (board_config == ALC662_AUTO) {
12972                 /* automatic parse from the BIOS config */
12973                 err = alc662_parse_auto_config(codec);
12974                 if (err < 0) {
12975                         alc_free(codec);
12976                         return err;
12977                 } else if (!err) {
12978                         printk(KERN_INFO
12979                                "hda_codec: Cannot set up configuration "
12980                                "from BIOS.  Using base mode...\n");
12981                         board_config = ALC662_3ST_2ch_DIG;
12982                 }
12983         }
12984
12985         if (board_config != ALC662_AUTO)
12986                 setup_preset(spec, &alc662_presets[board_config]);
12987
12988         spec->stream_name_analog = "ALC662 Analog";
12989         spec->stream_analog_playback = &alc662_pcm_analog_playback;
12990         spec->stream_analog_capture = &alc662_pcm_analog_capture;
12991
12992         spec->stream_name_digital = "ALC662 Digital";
12993         spec->stream_digital_playback = &alc662_pcm_digital_playback;
12994         spec->stream_digital_capture = &alc662_pcm_digital_capture;
12995
12996         if (!spec->adc_nids && spec->input_mux) {
12997                 spec->adc_nids = alc662_adc_nids;
12998                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
12999         }
13000
13001         codec->patch_ops = alc_patch_ops;
13002         if (board_config == ALC662_AUTO)
13003                 spec->init_hook = alc662_auto_init;
13004 #ifdef CONFIG_SND_HDA_POWER_SAVE
13005         if (!spec->loopback.amplist)
13006                 spec->loopback.amplist = alc662_loopbacks;
13007 #endif
13008
13009         return 0;
13010 }
13011
13012 /*
13013  * patch entries
13014  */
13015 struct hda_codec_preset snd_hda_preset_realtek[] = {
13016         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
13017         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
13018         { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
13019         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
13020         { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
13021         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
13022           .patch = patch_alc861 },
13023         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13024         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13025         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
13026         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13027           .patch = patch_alc883 },
13028         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13029           .patch = patch_alc662 },
13030         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
13031         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
13032         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
13033         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
13034         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
13035         { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
13036         {} /* terminator */
13037 };