[ALSA] hda-codec - new PCI SSID for HP machines
[linux-2.6] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25
26 #include <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34
35 #define ALC880_FRONT_EVENT              0x01
36 #define ALC880_DCVOL_EVENT              0x02
37 #define ALC880_HP_EVENT                 0x04
38 #define ALC880_MIC_EVENT                0x08
39
40 /* ALC880 board config type */
41 enum {
42         ALC880_3ST,
43         ALC880_3ST_DIG,
44         ALC880_5ST,
45         ALC880_5ST_DIG,
46         ALC880_W810,
47         ALC880_Z71V,
48         ALC880_6ST,
49         ALC880_6ST_DIG,
50         ALC880_F1734,
51         ALC880_ASUS,
52         ALC880_ASUS_DIG,
53         ALC880_ASUS_W1V,
54         ALC880_ASUS_DIG2,
55         ALC880_FUJITSU,
56         ALC880_UNIWILL_DIG,
57         ALC880_UNIWILL,
58         ALC880_UNIWILL_P53,
59         ALC880_CLEVO,
60         ALC880_TCL_S700,
61         ALC880_LG,
62         ALC880_LG_LW,
63 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_BENQ_ED8,
96         ALC262_SONY_ASSAMD,
97         ALC262_BENQ_T31,
98         ALC262_ULTRA,
99         ALC262_AUTO,
100         ALC262_MODEL_LAST /* last tag */
101 };
102
103 /* ALC268 models */
104 enum {
105         ALC268_3ST,
106         ALC268_TOSHIBA,
107         ALC268_ACER,
108         ALC268_AUTO,
109         ALC268_MODEL_LAST /* last tag */
110 };
111
112 /* ALC861 models */
113 enum {
114         ALC861_3ST,
115         ALC660_3ST,
116         ALC861_3ST_DIG,
117         ALC861_6ST_DIG,
118         ALC861_UNIWILL_M31,
119         ALC861_TOSHIBA,
120         ALC861_ASUS,
121         ALC861_ASUS_LAPTOP,
122         ALC861_AUTO,
123         ALC861_MODEL_LAST,
124 };
125
126 /* ALC861-VD models */
127 enum {
128         ALC660VD_3ST,
129         ALC660VD_3ST_DIG,
130         ALC861VD_3ST,
131         ALC861VD_3ST_DIG,
132         ALC861VD_6ST_DIG,
133         ALC861VD_LENOVO,
134         ALC861VD_DALLAS,
135         ALC861VD_HP,
136         ALC861VD_AUTO,
137         ALC861VD_MODEL_LAST,
138 };
139
140 /* ALC662 models */
141 enum {
142         ALC662_3ST_2ch_DIG,
143         ALC662_3ST_6ch_DIG,
144         ALC662_3ST_6ch,
145         ALC662_5ST_DIG,
146         ALC662_LENOVO_101E,
147         ALC662_ASUS_EEEPC_P701,
148         ALC662_AUTO,
149         ALC662_MODEL_LAST,
150 };
151
152 /* ALC882 models */
153 enum {
154         ALC882_3ST_DIG,
155         ALC882_6ST_DIG,
156         ALC882_ARIMA,
157         ALC882_W2JC,
158         ALC882_TARGA,
159         ALC882_ASUS_A7J,
160         ALC882_ASUS_A7M,
161         ALC885_MACPRO,
162         ALC885_MBP3,
163         ALC885_IMAC24,
164         ALC882_AUTO,
165         ALC882_MODEL_LAST,
166 };
167
168 /* ALC883 models */
169 enum {
170         ALC883_3ST_2ch_DIG,
171         ALC883_3ST_6ch_DIG,
172         ALC883_3ST_6ch,
173         ALC883_6ST_DIG,
174         ALC883_TARGA_DIG,
175         ALC883_TARGA_2ch_DIG,
176         ALC883_ACER,
177         ALC883_ACER_ASPIRE,
178         ALC883_MEDION,
179         ALC883_MEDION_MD2,      
180         ALC883_LAPTOP_EAPD,
181         ALC883_LENOVO_101E_2ch,
182         ALC883_LENOVO_NB0763,
183         ALC888_LENOVO_MS7195_DIG,
184         ALC883_HAIER_W66,               
185         ALC888_6ST_HP,
186         ALC888_3ST_HP,
187         ALC883_AUTO,
188         ALC883_MODEL_LAST,
189 };
190
191 /* for GPIO Poll */
192 #define GPIO_MASK       0x03
193
194 struct alc_spec {
195         /* codec parameterization */
196         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
197         unsigned int num_mixers;
198
199         const struct hda_verb *init_verbs[5];   /* initialization verbs
200                                                  * don't forget NULL
201                                                  * termination!
202                                                  */
203         unsigned int num_init_verbs;
204
205         char *stream_name_analog;       /* analog PCM stream */
206         struct hda_pcm_stream *stream_analog_playback;
207         struct hda_pcm_stream *stream_analog_capture;
208
209         char *stream_name_digital;      /* digital PCM stream */
210         struct hda_pcm_stream *stream_digital_playback;
211         struct hda_pcm_stream *stream_digital_capture;
212
213         /* playback */
214         struct hda_multi_out multiout;  /* playback set-up
215                                          * max_channels, dacs must be set
216                                          * dig_out_nid and hp_nid are optional
217                                          */
218
219         /* capture */
220         unsigned int num_adc_nids;
221         hda_nid_t *adc_nids;
222         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
223
224         /* capture source */
225         unsigned int num_mux_defs;
226         const struct hda_input_mux *input_mux;
227         unsigned int cur_mux[3];
228
229         /* channel model */
230         const struct hda_channel_mode *channel_mode;
231         int num_channel_mode;
232         int need_dac_fix;
233
234         /* PCM information */
235         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
236
237         /* dynamic controls, init_verbs and input_mux */
238         struct auto_pin_cfg autocfg;
239         unsigned int num_kctl_alloc, num_kctl_used;
240         struct snd_kcontrol_new *kctl_alloc;
241         struct hda_input_mux private_imux;
242         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
243
244         /* hooks */
245         void (*init_hook)(struct hda_codec *codec);
246         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
247
248         /* for pin sensing */
249         unsigned int sense_updated: 1;
250         unsigned int jack_present: 1;
251
252 #ifdef CONFIG_SND_HDA_POWER_SAVE
253         struct hda_loopback_check loopback;
254 #endif
255 };
256
257 /*
258  * configuration template - to be copied to the spec instance
259  */
260 struct alc_config_preset {
261         struct snd_kcontrol_new *mixers[5]; /* should be identical size
262                                              * with spec
263                                              */
264         const struct hda_verb *init_verbs[5];
265         unsigned int num_dacs;
266         hda_nid_t *dac_nids;
267         hda_nid_t dig_out_nid;          /* optional */
268         hda_nid_t hp_nid;               /* optional */
269         unsigned int num_adc_nids;
270         hda_nid_t *adc_nids;
271         hda_nid_t dig_in_nid;
272         unsigned int num_channel_mode;
273         const struct hda_channel_mode *channel_mode;
274         int need_dac_fix;
275         unsigned int num_mux_defs;
276         const struct hda_input_mux *input_mux;
277         void (*unsol_event)(struct hda_codec *, unsigned int);
278         void (*init_hook)(struct hda_codec *);
279 #ifdef CONFIG_SND_HDA_POWER_SAVE
280         struct hda_amp_list *loopbacks;
281 #endif
282 };
283
284
285 /*
286  * input MUX handling
287  */
288 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
289                              struct snd_ctl_elem_info *uinfo)
290 {
291         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
292         struct alc_spec *spec = codec->spec;
293         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
294         if (mux_idx >= spec->num_mux_defs)
295                 mux_idx = 0;
296         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
297 }
298
299 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
300                             struct snd_ctl_elem_value *ucontrol)
301 {
302         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
303         struct alc_spec *spec = codec->spec;
304         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
305
306         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
307         return 0;
308 }
309
310 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
311                             struct snd_ctl_elem_value *ucontrol)
312 {
313         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
314         struct alc_spec *spec = codec->spec;
315         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
316         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
317         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
318                                      spec->adc_nids[adc_idx],
319                                      &spec->cur_mux[adc_idx]);
320 }
321
322
323 /*
324  * channel mode setting
325  */
326 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
327                             struct snd_ctl_elem_info *uinfo)
328 {
329         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
330         struct alc_spec *spec = codec->spec;
331         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
332                                     spec->num_channel_mode);
333 }
334
335 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
336                            struct snd_ctl_elem_value *ucontrol)
337 {
338         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
339         struct alc_spec *spec = codec->spec;
340         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
341                                    spec->num_channel_mode,
342                                    spec->multiout.max_channels);
343 }
344
345 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
346                            struct snd_ctl_elem_value *ucontrol)
347 {
348         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
349         struct alc_spec *spec = codec->spec;
350         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
351                                       spec->num_channel_mode,
352                                       &spec->multiout.max_channels);
353         if (err >= 0 && spec->need_dac_fix)
354                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
355         return err;
356 }
357
358 /*
359  * Control the mode of pin widget settings via the mixer.  "pc" is used
360  * instead of "%" to avoid consequences of accidently treating the % as 
361  * being part of a format specifier.  Maximum allowed length of a value is
362  * 63 characters plus NULL terminator.
363  *
364  * Note: some retasking pin complexes seem to ignore requests for input
365  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
366  * are requested.  Therefore order this list so that this behaviour will not
367  * cause problems when mixer clients move through the enum sequentially.
368  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
369  * March 2006.
370  */
371 static char *alc_pin_mode_names[] = {
372         "Mic 50pc bias", "Mic 80pc bias",
373         "Line in", "Line out", "Headphone out",
374 };
375 static unsigned char alc_pin_mode_values[] = {
376         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
377 };
378 /* The control can present all 5 options, or it can limit the options based
379  * in the pin being assumed to be exclusively an input or an output pin.  In
380  * addition, "input" pins may or may not process the mic bias option
381  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
382  * accept requests for bias as of chip versions up to March 2006) and/or
383  * wiring in the computer.
384  */
385 #define ALC_PIN_DIR_IN              0x00
386 #define ALC_PIN_DIR_OUT             0x01
387 #define ALC_PIN_DIR_INOUT           0x02
388 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
389 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
390
391 /* Info about the pin modes supported by the different pin direction modes. 
392  * For each direction the minimum and maximum values are given.
393  */
394 static signed char alc_pin_mode_dir_info[5][2] = {
395         { 0, 2 },    /* ALC_PIN_DIR_IN */
396         { 3, 4 },    /* ALC_PIN_DIR_OUT */
397         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
398         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
399         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
400 };
401 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
402 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
403 #define alc_pin_mode_n_items(_dir) \
404         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
405
406 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
407                              struct snd_ctl_elem_info *uinfo)
408 {
409         unsigned int item_num = uinfo->value.enumerated.item;
410         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
411
412         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
413         uinfo->count = 1;
414         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
415
416         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
417                 item_num = alc_pin_mode_min(dir);
418         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
419         return 0;
420 }
421
422 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
423                             struct snd_ctl_elem_value *ucontrol)
424 {
425         unsigned int i;
426         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
427         hda_nid_t nid = kcontrol->private_value & 0xffff;
428         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
429         long *valp = ucontrol->value.integer.value;
430         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
431                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
432                                                  0x00);
433
434         /* Find enumerated value for current pinctl setting */
435         i = alc_pin_mode_min(dir);
436         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
437                 i++;
438         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
439         return 0;
440 }
441
442 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
443                             struct snd_ctl_elem_value *ucontrol)
444 {
445         signed int change;
446         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
447         hda_nid_t nid = kcontrol->private_value & 0xffff;
448         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
449         long val = *ucontrol->value.integer.value;
450         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
451                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
452                                                  0x00);
453
454         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
455                 val = alc_pin_mode_min(dir);
456
457         change = pinctl != alc_pin_mode_values[val];
458         if (change) {
459                 /* Set pin mode to that requested */
460                 snd_hda_codec_write_cache(codec, nid, 0,
461                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
462                                           alc_pin_mode_values[val]);
463
464                 /* Also enable the retasking pin's input/output as required 
465                  * for the requested pin mode.  Enum values of 2 or less are
466                  * input modes.
467                  *
468                  * Dynamically switching the input/output buffers probably
469                  * reduces noise slightly (particularly on input) so we'll
470                  * do it.  However, having both input and output buffers
471                  * enabled simultaneously doesn't seem to be problematic if
472                  * this turns out to be necessary in the future.
473                  */
474                 if (val <= 2) {
475                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
476                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
477                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
478                                                  HDA_AMP_MUTE, 0);
479                 } else {
480                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
481                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
482                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
483                                                  HDA_AMP_MUTE, 0);
484                 }
485         }
486         return change;
487 }
488
489 #define ALC_PIN_MODE(xname, nid, dir) \
490         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
491           .info = alc_pin_mode_info, \
492           .get = alc_pin_mode_get, \
493           .put = alc_pin_mode_put, \
494           .private_value = nid | (dir<<16) }
495
496 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
497  * together using a mask with more than one bit set.  This control is
498  * currently used only by the ALC260 test model.  At this stage they are not
499  * needed for any "production" models.
500  */
501 #ifdef CONFIG_SND_DEBUG
502 #define alc_gpio_data_info      snd_ctl_boolean_mono_info
503
504 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
505                              struct snd_ctl_elem_value *ucontrol)
506 {
507         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
508         hda_nid_t nid = kcontrol->private_value & 0xffff;
509         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
510         long *valp = ucontrol->value.integer.value;
511         unsigned int val = snd_hda_codec_read(codec, nid, 0,
512                                               AC_VERB_GET_GPIO_DATA, 0x00);
513
514         *valp = (val & mask) != 0;
515         return 0;
516 }
517 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
518                              struct snd_ctl_elem_value *ucontrol)
519 {
520         signed int change;
521         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
522         hda_nid_t nid = kcontrol->private_value & 0xffff;
523         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
524         long val = *ucontrol->value.integer.value;
525         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
526                                                     AC_VERB_GET_GPIO_DATA,
527                                                     0x00);
528
529         /* Set/unset the masked GPIO bit(s) as needed */
530         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
531         if (val == 0)
532                 gpio_data &= ~mask;
533         else
534                 gpio_data |= mask;
535         snd_hda_codec_write_cache(codec, nid, 0,
536                                   AC_VERB_SET_GPIO_DATA, gpio_data);
537
538         return change;
539 }
540 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
541         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
542           .info = alc_gpio_data_info, \
543           .get = alc_gpio_data_get, \
544           .put = alc_gpio_data_put, \
545           .private_value = nid | (mask<<16) }
546 #endif   /* CONFIG_SND_DEBUG */
547
548 /* A switch control to allow the enabling of the digital IO pins on the
549  * ALC260.  This is incredibly simplistic; the intention of this control is
550  * to provide something in the test model allowing digital outputs to be
551  * identified if present.  If models are found which can utilise these
552  * outputs a more complete mixer control can be devised for those models if
553  * necessary.
554  */
555 #ifdef CONFIG_SND_DEBUG
556 #define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
557
558 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
559                               struct snd_ctl_elem_value *ucontrol)
560 {
561         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
562         hda_nid_t nid = kcontrol->private_value & 0xffff;
563         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
564         long *valp = ucontrol->value.integer.value;
565         unsigned int val = snd_hda_codec_read(codec, nid, 0,
566                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
567
568         *valp = (val & mask) != 0;
569         return 0;
570 }
571 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
572                               struct snd_ctl_elem_value *ucontrol)
573 {
574         signed int change;
575         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
576         hda_nid_t nid = kcontrol->private_value & 0xffff;
577         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
578         long val = *ucontrol->value.integer.value;
579         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
580                                                     AC_VERB_GET_DIGI_CONVERT,
581                                                     0x00);
582
583         /* Set/unset the masked control bit(s) as needed */
584         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
585         if (val==0)
586                 ctrl_data &= ~mask;
587         else
588                 ctrl_data |= mask;
589         snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
590                                   ctrl_data);
591
592         return change;
593 }
594 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
595         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
596           .info = alc_spdif_ctrl_info, \
597           .get = alc_spdif_ctrl_get, \
598           .put = alc_spdif_ctrl_put, \
599           .private_value = nid | (mask<<16) }
600 #endif   /* CONFIG_SND_DEBUG */
601
602 /*
603  * set up from the preset table
604  */
605 static void setup_preset(struct alc_spec *spec,
606                          const struct alc_config_preset *preset)
607 {
608         int i;
609
610         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
611                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
612         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
613              i++)
614                 spec->init_verbs[spec->num_init_verbs++] =
615                         preset->init_verbs[i];
616         
617         spec->channel_mode = preset->channel_mode;
618         spec->num_channel_mode = preset->num_channel_mode;
619         spec->need_dac_fix = preset->need_dac_fix;
620
621         spec->multiout.max_channels = spec->channel_mode[0].channels;
622
623         spec->multiout.num_dacs = preset->num_dacs;
624         spec->multiout.dac_nids = preset->dac_nids;
625         spec->multiout.dig_out_nid = preset->dig_out_nid;
626         spec->multiout.hp_nid = preset->hp_nid;
627         
628         spec->num_mux_defs = preset->num_mux_defs;
629         if (!spec->num_mux_defs)
630                 spec->num_mux_defs = 1;
631         spec->input_mux = preset->input_mux;
632
633         spec->num_adc_nids = preset->num_adc_nids;
634         spec->adc_nids = preset->adc_nids;
635         spec->dig_in_nid = preset->dig_in_nid;
636
637         spec->unsol_event = preset->unsol_event;
638         spec->init_hook = preset->init_hook;
639 #ifdef CONFIG_SND_HDA_POWER_SAVE
640         spec->loopback.amplist = preset->loopbacks;
641 #endif
642 }
643
644 /* Enable GPIO mask and set output */
645 static struct hda_verb alc_gpio1_init_verbs[] = {
646         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
647         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
648         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
649         { }
650 };
651
652 static struct hda_verb alc_gpio2_init_verbs[] = {
653         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
654         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
655         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
656         { }
657 };
658
659 static struct hda_verb alc_gpio3_init_verbs[] = {
660         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
661         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
662         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
663         { }
664 };
665
666 static void alc_sku_automute(struct hda_codec *codec)
667 {
668         struct alc_spec *spec = codec->spec;
669         unsigned int mute;
670         unsigned int present;
671         unsigned int hp_nid = spec->autocfg.hp_pins[0];
672         unsigned int sp_nid = spec->autocfg.speaker_pins[0];
673
674         /* need to execute and sync at first */
675         snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
676         present = snd_hda_codec_read(codec, hp_nid, 0,
677                                      AC_VERB_GET_PIN_SENSE, 0);
678         spec->jack_present = (present & 0x80000000) != 0;
679         if (spec->jack_present) {
680                 /* mute internal speaker */
681                 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
682                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
683         } else {
684                 /* unmute internal speaker if necessary */
685                 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
686                 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
687                                          HDA_AMP_MUTE, mute);
688         }
689 }
690
691 /* unsolicited event for HP jack sensing */
692 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
693 {
694         if (codec->vendor_id == 0x10ec0880)
695                 res >>= 28;
696         else
697                 res >>= 26;
698         if (res != ALC880_HP_EVENT)
699                 return;
700
701         alc_sku_automute(codec);
702 }
703
704 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
705  *      31 ~ 16 :       Manufacture ID
706  *      15 ~ 8  :       SKU ID
707  *      7  ~ 0  :       Assembly ID
708  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
709  */
710 static void alc_subsystem_id(struct hda_codec *codec,
711                              unsigned int porta, unsigned int porte,
712                              unsigned int portd)
713 {
714         unsigned int ass, tmp, i;
715         unsigned nid;
716         struct alc_spec *spec = codec->spec;
717
718         ass = codec->subsystem_id & 0xffff;
719         if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
720                 goto do_sku;
721
722         /*      
723          * 31~30        : port conetcivity
724          * 29~21        : reserve
725          * 20           : PCBEEP input
726          * 19~16        : Check sum (15:1)
727          * 15~1         : Custom
728          * 0            : override
729         */
730         nid = 0x1d;
731         if (codec->vendor_id == 0x10ec0260)
732                 nid = 0x17;
733         ass = snd_hda_codec_read(codec, nid, 0,
734                                  AC_VERB_GET_CONFIG_DEFAULT, 0);
735         if (!(ass & 1) && !(ass & 0x100000))
736                 return;
737         if ((ass >> 30) != 1)   /* no physical connection */
738                 return;
739
740         /* check sum */
741         tmp = 0;
742         for (i = 1; i < 16; i++) {
743                 if ((ass >> i) && 1)
744                         tmp++;
745         }
746         if (((ass >> 16) & 0xf) != tmp)
747                 return;
748 do_sku:
749         /*
750          * 0 : override
751          * 1 :  Swap Jack
752          * 2 : 0 --> Desktop, 1 --> Laptop
753          * 3~5 : External Amplifier control
754          * 7~6 : Reserved
755         */
756         tmp = (ass & 0x38) >> 3;        /* external Amp control */
757         switch (tmp) {
758         case 1:
759                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
760                 break;
761         case 3:
762                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
763                 break;
764         case 7:
765                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
766                 break;
767         case 5: /* set EAPD output high */
768                 switch (codec->vendor_id) {
769                 case 0x10ec0260:
770                         snd_hda_codec_write(codec, 0x0f, 0,
771                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
772                         snd_hda_codec_write(codec, 0x10, 0,
773                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
774                         break;
775                 case 0x10ec0262:
776                 case 0x10ec0267:
777                 case 0x10ec0268:
778                 case 0x10ec0269:
779                 case 0x10ec0862:
780                 case 0x10ec0662:        
781                         snd_hda_codec_write(codec, 0x14, 0,
782                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
783                         snd_hda_codec_write(codec, 0x15, 0,
784                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
785                         break;
786                 }
787                 switch (codec->vendor_id) {
788                 case 0x10ec0260:
789                         snd_hda_codec_write(codec, 0x1a, 0,
790                                             AC_VERB_SET_COEF_INDEX, 7);
791                         tmp = snd_hda_codec_read(codec, 0x1a, 0,
792                                                  AC_VERB_GET_PROC_COEF, 0);
793                         snd_hda_codec_write(codec, 0x1a, 0,
794                                             AC_VERB_SET_COEF_INDEX, 7);
795                         snd_hda_codec_write(codec, 0x1a, 0,
796                                             AC_VERB_SET_PROC_COEF,
797                                             tmp | 0x2010);
798                         break;
799                 case 0x10ec0262:
800                 case 0x10ec0880:
801                 case 0x10ec0882:
802                 case 0x10ec0883:
803                 case 0x10ec0885:
804                 case 0x10ec0888:
805                         snd_hda_codec_write(codec, 0x20, 0,
806                                             AC_VERB_SET_COEF_INDEX, 7);
807                         tmp = snd_hda_codec_read(codec, 0x20, 0,
808                                                  AC_VERB_GET_PROC_COEF, 0);
809                         snd_hda_codec_write(codec, 0x20, 0,
810                                             AC_VERB_SET_COEF_INDEX, 7); 
811                         snd_hda_codec_write(codec, 0x20, 0,
812                                             AC_VERB_SET_PROC_COEF,
813                                             tmp | 0x2010);
814                         break;
815                 case 0x10ec0267:
816                 case 0x10ec0268:
817                         snd_hda_codec_write(codec, 0x20, 0,
818                                             AC_VERB_SET_COEF_INDEX, 7);
819                         tmp = snd_hda_codec_read(codec, 0x20, 0,
820                                                  AC_VERB_GET_PROC_COEF, 0);
821                         snd_hda_codec_write(codec, 0x20, 0,
822                                             AC_VERB_SET_COEF_INDEX, 7); 
823                         snd_hda_codec_write(codec, 0x20, 0,
824                                             AC_VERB_SET_PROC_COEF,
825                                             tmp | 0x3000);
826                         break;
827                 }
828         default:
829                 break;
830         }
831         
832         /* is laptop and enable the function "Mute internal speaker
833          * when the external headphone out jack is plugged"
834          */
835         if (!(ass & 0x4) || !(ass & 0x8000))
836                 return;
837         /*
838          * 10~8 : Jack location
839          * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
840          * 14~13: Resvered
841          * 15   : 1 --> enable the function "Mute internal speaker
842          *              when the external headphone out jack is plugged"
843          */
844         if (!spec->autocfg.speaker_pins[0]) {
845                 if (spec->multiout.dac_nids[0])
846                         spec->autocfg.speaker_pins[0] =
847                                 spec->multiout.dac_nids[0];
848                 else
849                         return;
850         }
851
852         if (!spec->autocfg.hp_pins[0]) {
853                 tmp = (ass >> 11) & 0x3;        /* HP to chassis */
854                 if (tmp == 0)
855                         spec->autocfg.hp_pins[0] = porta;
856                 else if (tmp == 1)
857                         spec->autocfg.hp_pins[0] = porte;
858                 else if (tmp == 2)
859                         spec->autocfg.hp_pins[0] = portd;
860                 else
861                         return;
862         }
863
864         snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
865                             AC_VERB_SET_UNSOLICITED_ENABLE,
866                             AC_USRSP_EN | ALC880_HP_EVENT);
867         spec->unsol_event = alc_sku_unsol_event;
868         spec->init_hook = alc_sku_automute;     
869 }
870
871 /*
872  * Fix-up pin default configurations
873  */
874
875 struct alc_pincfg {
876         hda_nid_t nid;
877         u32 val;
878 };
879
880 static void alc_fix_pincfg(struct hda_codec *codec,
881                            const struct snd_pci_quirk *quirk,
882                            const struct alc_pincfg **pinfix)
883 {
884         const struct alc_pincfg *cfg;
885
886         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
887         if (!quirk)
888                 return;
889
890         cfg = pinfix[quirk->value];
891         for (; cfg->nid; cfg++) {
892                 int i;
893                 u32 val = cfg->val;
894                 for (i = 0; i < 4; i++) {
895                         snd_hda_codec_write(codec, cfg->nid, 0,
896                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
897                                     val & 0xff);
898                         val >>= 8;
899                 }
900         }
901 }
902
903 /*
904  * ALC880 3-stack model
905  *
906  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
907  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
908  *                 F-Mic = 0x1b, HP = 0x19
909  */
910
911 static hda_nid_t alc880_dac_nids[4] = {
912         /* front, rear, clfe, rear_surr */
913         0x02, 0x05, 0x04, 0x03
914 };
915
916 static hda_nid_t alc880_adc_nids[3] = {
917         /* ADC0-2 */
918         0x07, 0x08, 0x09,
919 };
920
921 /* The datasheet says the node 0x07 is connected from inputs,
922  * but it shows zero connection in the real implementation on some devices.
923  * Note: this is a 915GAV bug, fixed on 915GLV
924  */
925 static hda_nid_t alc880_adc_nids_alt[2] = {
926         /* ADC1-2 */
927         0x08, 0x09,
928 };
929
930 #define ALC880_DIGOUT_NID       0x06
931 #define ALC880_DIGIN_NID        0x0a
932
933 static struct hda_input_mux alc880_capture_source = {
934         .num_items = 4,
935         .items = {
936                 { "Mic", 0x0 },
937                 { "Front Mic", 0x3 },
938                 { "Line", 0x2 },
939                 { "CD", 0x4 },
940         },
941 };
942
943 /* channel source setting (2/6 channel selection for 3-stack) */
944 /* 2ch mode */
945 static struct hda_verb alc880_threestack_ch2_init[] = {
946         /* set line-in to input, mute it */
947         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
948         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
949         /* set mic-in to input vref 80%, mute it */
950         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
951         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
952         { } /* end */
953 };
954
955 /* 6ch mode */
956 static struct hda_verb alc880_threestack_ch6_init[] = {
957         /* set line-in to output, unmute it */
958         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
959         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
960         /* set mic-in to output, unmute it */
961         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
962         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
963         { } /* end */
964 };
965
966 static struct hda_channel_mode alc880_threestack_modes[2] = {
967         { 2, alc880_threestack_ch2_init },
968         { 6, alc880_threestack_ch6_init },
969 };
970
971 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
972         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
973         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
974         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
975         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
976         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
977         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
978         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
979         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
980         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
981         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
982         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
983         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
984         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
985         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
986         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
987         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
988         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
989         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
990         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
991         {
992                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
993                 .name = "Channel Mode",
994                 .info = alc_ch_mode_info,
995                 .get = alc_ch_mode_get,
996                 .put = alc_ch_mode_put,
997         },
998         { } /* end */
999 };
1000
1001 /* capture mixer elements */
1002 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1003         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1004         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1005         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1006         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1007         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1008         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1009         {
1010                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1011                 /* The multiple "Capture Source" controls confuse alsamixer
1012                  * So call somewhat different..
1013                  * FIXME: the controls appear in the "playback" view!
1014                  */
1015                 /* .name = "Capture Source", */
1016                 .name = "Input Source",
1017                 .count = 3,
1018                 .info = alc_mux_enum_info,
1019                 .get = alc_mux_enum_get,
1020                 .put = alc_mux_enum_put,
1021         },
1022         { } /* end */
1023 };
1024
1025 /* capture mixer elements (in case NID 0x07 not available) */
1026 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1027         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1028         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1029         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1030         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1031         {
1032                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1033                 /* The multiple "Capture Source" controls confuse alsamixer
1034                  * So call somewhat different..
1035                  * FIXME: the controls appear in the "playback" view!
1036                  */
1037                 /* .name = "Capture Source", */
1038                 .name = "Input Source",
1039                 .count = 2,
1040                 .info = alc_mux_enum_info,
1041                 .get = alc_mux_enum_get,
1042                 .put = alc_mux_enum_put,
1043         },
1044         { } /* end */
1045 };
1046
1047
1048
1049 /*
1050  * ALC880 5-stack model
1051  *
1052  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1053  *      Side = 0x02 (0xd)
1054  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1055  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1056  */
1057
1058 /* additional mixers to alc880_three_stack_mixer */
1059 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1060         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1061         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1062         { } /* end */
1063 };
1064
1065 /* channel source setting (6/8 channel selection for 5-stack) */
1066 /* 6ch mode */
1067 static struct hda_verb alc880_fivestack_ch6_init[] = {
1068         /* set line-in to input, mute it */
1069         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1070         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1071         { } /* end */
1072 };
1073
1074 /* 8ch mode */
1075 static struct hda_verb alc880_fivestack_ch8_init[] = {
1076         /* set line-in to output, unmute it */
1077         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1078         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1079         { } /* end */
1080 };
1081
1082 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1083         { 6, alc880_fivestack_ch6_init },
1084         { 8, alc880_fivestack_ch8_init },
1085 };
1086
1087
1088 /*
1089  * ALC880 6-stack model
1090  *
1091  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1092  *      Side = 0x05 (0x0f)
1093  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1094  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1095  */
1096
1097 static hda_nid_t alc880_6st_dac_nids[4] = {
1098         /* front, rear, clfe, rear_surr */
1099         0x02, 0x03, 0x04, 0x05
1100 };
1101
1102 static struct hda_input_mux alc880_6stack_capture_source = {
1103         .num_items = 4,
1104         .items = {
1105                 { "Mic", 0x0 },
1106                 { "Front Mic", 0x1 },
1107                 { "Line", 0x2 },
1108                 { "CD", 0x4 },
1109         },
1110 };
1111
1112 /* fixed 8-channels */
1113 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1114         { 8, NULL },
1115 };
1116
1117 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1118         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1119         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1120         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1121         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1122         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1123         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1124         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1125         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1126         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1127         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1128         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1129         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1130         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1131         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1132         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1133         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1134         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1135         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1136         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1137         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1138         {
1139                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1140                 .name = "Channel Mode",
1141                 .info = alc_ch_mode_info,
1142                 .get = alc_ch_mode_get,
1143                 .put = alc_ch_mode_put,
1144         },
1145         { } /* end */
1146 };
1147
1148
1149 /*
1150  * ALC880 W810 model
1151  *
1152  * W810 has rear IO for:
1153  * Front (DAC 02)
1154  * Surround (DAC 03)
1155  * Center/LFE (DAC 04)
1156  * Digital out (06)
1157  *
1158  * The system also has a pair of internal speakers, and a headphone jack.
1159  * These are both connected to Line2 on the codec, hence to DAC 02.
1160  * 
1161  * There is a variable resistor to control the speaker or headphone
1162  * volume. This is a hardware-only device without a software API.
1163  *
1164  * Plugging headphones in will disable the internal speakers. This is
1165  * implemented in hardware, not via the driver using jack sense. In
1166  * a similar fashion, plugging into the rear socket marked "front" will
1167  * disable both the speakers and headphones.
1168  *
1169  * For input, there's a microphone jack, and an "audio in" jack.
1170  * These may not do anything useful with this driver yet, because I
1171  * haven't setup any initialization verbs for these yet...
1172  */
1173
1174 static hda_nid_t alc880_w810_dac_nids[3] = {
1175         /* front, rear/surround, clfe */
1176         0x02, 0x03, 0x04
1177 };
1178
1179 /* fixed 6 channels */
1180 static struct hda_channel_mode alc880_w810_modes[1] = {
1181         { 6, NULL }
1182 };
1183
1184 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1185 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1186         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1187         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1188         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1189         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1190         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1191         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1192         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1193         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1194         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1195         { } /* end */
1196 };
1197
1198
1199 /*
1200  * Z710V model
1201  *
1202  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1203  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1204  *                 Line = 0x1a
1205  */
1206
1207 static hda_nid_t alc880_z71v_dac_nids[1] = {
1208         0x02
1209 };
1210 #define ALC880_Z71V_HP_DAC      0x03
1211
1212 /* fixed 2 channels */
1213 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1214         { 2, NULL }
1215 };
1216
1217 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1218         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1219         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1220         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1221         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1222         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1223         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1224         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1225         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1226         { } /* end */
1227 };
1228
1229
1230 /* FIXME! */
1231 /*
1232  * ALC880 F1734 model
1233  *
1234  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1235  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1236  */
1237
1238 static hda_nid_t alc880_f1734_dac_nids[1] = {
1239         0x03
1240 };
1241 #define ALC880_F1734_HP_DAC     0x02
1242
1243 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1244         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1245         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1246         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1247         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1248         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1249         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1250         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1251         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1252         { } /* end */
1253 };
1254
1255
1256 /* FIXME! */
1257 /*
1258  * ALC880 ASUS model
1259  *
1260  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1261  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1262  *  Mic = 0x18, Line = 0x1a
1263  */
1264
1265 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1266 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1267
1268 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1269         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1270         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1271         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1272         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1273         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1274         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1275         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1276         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1277         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1278         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1279         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1280         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1281         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1282         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1283         {
1284                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1285                 .name = "Channel Mode",
1286                 .info = alc_ch_mode_info,
1287                 .get = alc_ch_mode_get,
1288                 .put = alc_ch_mode_put,
1289         },
1290         { } /* end */
1291 };
1292
1293 /* FIXME! */
1294 /*
1295  * ALC880 ASUS W1V model
1296  *
1297  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1298  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1299  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1300  */
1301
1302 /* additional mixers to alc880_asus_mixer */
1303 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1304         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1305         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1306         { } /* end */
1307 };
1308
1309 /* additional mixers to alc880_asus_mixer */
1310 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1311         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1312         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1313         { } /* end */
1314 };
1315
1316 /* TCL S700 */
1317 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1318         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1319         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1320         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1321         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1322         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1323         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1324         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1325         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1326         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1327         {
1328                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1329                 /* The multiple "Capture Source" controls confuse alsamixer
1330                  * So call somewhat different..
1331                  * FIXME: the controls appear in the "playback" view!
1332                  */
1333                 /* .name = "Capture Source", */
1334                 .name = "Input Source",
1335                 .count = 1,
1336                 .info = alc_mux_enum_info,
1337                 .get = alc_mux_enum_get,
1338                 .put = alc_mux_enum_put,
1339         },
1340         { } /* end */
1341 };
1342
1343 /* Uniwill */
1344 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1345         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1346         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1347         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1348         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1349         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1350         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1351         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1352         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1353         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1354         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1355         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1356         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1357         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1358         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1359         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1360         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1361         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1362         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1363         {
1364                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1365                 .name = "Channel Mode",
1366                 .info = alc_ch_mode_info,
1367                 .get = alc_ch_mode_get,
1368                 .put = alc_ch_mode_put,
1369         },
1370         { } /* end */
1371 };
1372
1373 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1374         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1375         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1376         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1377         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1378         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1379         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1380         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1381         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1382         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1383         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1384         { } /* end */
1385 };
1386
1387 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1388         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1389         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1390         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1391         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1392         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1393         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1394         { } /* end */
1395 };
1396
1397 /*
1398  * build control elements
1399  */
1400 static int alc_build_controls(struct hda_codec *codec)
1401 {
1402         struct alc_spec *spec = codec->spec;
1403         int err;
1404         int i;
1405
1406         for (i = 0; i < spec->num_mixers; i++) {
1407                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1408                 if (err < 0)
1409                         return err;
1410         }
1411
1412         if (spec->multiout.dig_out_nid) {
1413                 err = snd_hda_create_spdif_out_ctls(codec,
1414                                                     spec->multiout.dig_out_nid);
1415                 if (err < 0)
1416                         return err;
1417         }
1418         if (spec->dig_in_nid) {
1419                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1420                 if (err < 0)
1421                         return err;
1422         }
1423         return 0;
1424 }
1425
1426
1427 /*
1428  * initialize the codec volumes, etc
1429  */
1430
1431 /*
1432  * generic initialization of ADC, input mixers and output mixers
1433  */
1434 static struct hda_verb alc880_volume_init_verbs[] = {
1435         /*
1436          * Unmute ADC0-2 and set the default input to mic-in
1437          */
1438         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1439         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1440         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1441         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1442         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1443         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1444
1445         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1446          * mixer widget
1447          * Note: PASD motherboards uses the Line In 2 as the input for front
1448          * panel mic (mic 2)
1449          */
1450         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1451         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1452         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1453         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1454         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1455         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1456         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1457         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1458
1459         /*
1460          * Set up output mixers (0x0c - 0x0f)
1461          */
1462         /* set vol=0 to output mixers */
1463         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1464         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1465         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1466         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1467         /* set up input amps for analog loopback */
1468         /* Amp Indices: DAC = 0, mixer = 1 */
1469         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1470         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1471         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1472         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1473         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1474         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1475         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1476         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1477
1478         { }
1479 };
1480
1481 /*
1482  * 3-stack pin configuration:
1483  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1484  */
1485 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1486         /*
1487          * preset connection lists of input pins
1488          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1489          */
1490         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1491         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1492         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1493
1494         /*
1495          * Set pin mode and muting
1496          */
1497         /* set front pin widgets 0x14 for output */
1498         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1499         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1500         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1501         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1502         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1503         /* Mic2 (as headphone out) for HP output */
1504         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1505         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1506         /* Line In pin widget for input */
1507         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1508         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1509         /* Line2 (as front mic) pin widget for input and vref at 80% */
1510         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1511         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1512         /* CD pin widget for input */
1513         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1514
1515         { }
1516 };
1517
1518 /*
1519  * 5-stack pin configuration:
1520  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1521  * line-in/side = 0x1a, f-mic = 0x1b
1522  */
1523 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1524         /*
1525          * preset connection lists of input pins
1526          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1527          */
1528         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1529         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1530
1531         /*
1532          * Set pin mode and muting
1533          */
1534         /* set pin widgets 0x14-0x17 for output */
1535         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1536         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1537         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1538         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1539         /* unmute pins for output (no gain on this amp) */
1540         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1541         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1542         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1543         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1544
1545         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1546         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1547         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1548         /* Mic2 (as headphone out) for HP output */
1549         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1550         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1551         /* Line In pin widget for input */
1552         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1553         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1554         /* Line2 (as front mic) pin widget for input and vref at 80% */
1555         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1556         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1557         /* CD pin widget for input */
1558         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1559
1560         { }
1561 };
1562
1563 /*
1564  * W810 pin configuration:
1565  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1566  */
1567 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1568         /* hphone/speaker input selector: front DAC */
1569         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1570
1571         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1572         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1573         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1574         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1575         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1576         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1577
1578         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1579         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1580
1581         { }
1582 };
1583
1584 /*
1585  * Z71V pin configuration:
1586  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1587  */
1588 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1589         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1590         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1591         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1592         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1593
1594         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1595         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1596         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1597         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1598
1599         { }
1600 };
1601
1602 /*
1603  * 6-stack pin configuration:
1604  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1605  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1606  */
1607 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1608         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1609
1610         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1611         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1612         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1613         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1614         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1615         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1616         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1617         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1618
1619         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1620         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1621         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1622         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1623         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1624         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1625         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1626         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1627         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1628         
1629         { }
1630 };
1631
1632 /*
1633  * Uniwill pin configuration:
1634  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1635  * line = 0x1a
1636  */
1637 static struct hda_verb alc880_uniwill_init_verbs[] = {
1638         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1639
1640         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1641         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1642         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1643         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1644         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1645         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1646         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1647         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1648         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1649         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1650         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1651         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1652         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1653         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1654
1655         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1656         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1657         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1658         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1659         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1660         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1661         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1662         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1663         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1664
1665         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1666         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1667
1668         { }
1669 };
1670
1671 /*
1672 * Uniwill P53
1673 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1674  */
1675 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1676         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1677
1678         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1679         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1681         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1682         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1683         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1684         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1685         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1686         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1687         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1688         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1689         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1690
1691         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1692         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1693         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1694         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1695         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1696         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1697
1698         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1699         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1700
1701         { }
1702 };
1703
1704 static struct hda_verb alc880_beep_init_verbs[] = {
1705         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1706         { }
1707 };
1708
1709 /* toggle speaker-output according to the hp-jack state */
1710 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1711 {
1712         unsigned int present;
1713         unsigned char bits;
1714
1715         present = snd_hda_codec_read(codec, 0x14, 0,
1716                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1717         bits = present ? HDA_AMP_MUTE : 0;
1718         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1719                                  HDA_AMP_MUTE, bits);
1720         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1721                                  HDA_AMP_MUTE, bits);
1722 }
1723
1724 /* auto-toggle front mic */
1725 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1726 {
1727         unsigned int present;
1728         unsigned char bits;
1729
1730         present = snd_hda_codec_read(codec, 0x18, 0,
1731                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1732         bits = present ? HDA_AMP_MUTE : 0;
1733         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1734 }
1735
1736 static void alc880_uniwill_automute(struct hda_codec *codec)
1737 {
1738         alc880_uniwill_hp_automute(codec);
1739         alc880_uniwill_mic_automute(codec);
1740 }
1741
1742 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1743                                        unsigned int res)
1744 {
1745         /* Looks like the unsol event is incompatible with the standard
1746          * definition.  4bit tag is placed at 28 bit!
1747          */
1748         switch (res >> 28) {
1749         case ALC880_HP_EVENT:
1750                 alc880_uniwill_hp_automute(codec);
1751                 break;
1752         case ALC880_MIC_EVENT:
1753                 alc880_uniwill_mic_automute(codec);
1754                 break;
1755         }
1756 }
1757
1758 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1759 {
1760         unsigned int present;
1761         unsigned char bits;
1762
1763         present = snd_hda_codec_read(codec, 0x14, 0,
1764                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1765         bits = present ? HDA_AMP_MUTE : 0;
1766         snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1767 }
1768
1769 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1770 {
1771         unsigned int present;
1772         
1773         present = snd_hda_codec_read(codec, 0x21, 0,
1774                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1775         present &= HDA_AMP_VOLMASK;
1776         snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1777                                  HDA_AMP_VOLMASK, present);
1778         snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1779                                  HDA_AMP_VOLMASK, present);
1780 }
1781
1782 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1783                                            unsigned int res)
1784 {
1785         /* Looks like the unsol event is incompatible with the standard
1786          * definition.  4bit tag is placed at 28 bit!
1787          */
1788         if ((res >> 28) == ALC880_HP_EVENT)
1789                 alc880_uniwill_p53_hp_automute(codec);
1790         if ((res >> 28) == ALC880_DCVOL_EVENT)
1791                 alc880_uniwill_p53_dcvol_automute(codec);
1792 }
1793
1794 /* FIXME! */
1795 /*
1796  * F1734 pin configuration:
1797  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1798  */
1799 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1800         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1801         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1802         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1803         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1804
1805         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1806         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1807         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1808         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1809
1810         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1811         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1812         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1813         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1814         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1815         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1816         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1817         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1818         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1819
1820         { }
1821 };
1822
1823 /* FIXME! */
1824 /*
1825  * ASUS pin configuration:
1826  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1827  */
1828 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1829         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1830         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1831         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1832         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1833
1834         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1835         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1836         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1837         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1838         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1839         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1840         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1841         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1842
1843         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1844         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1845         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1846         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1847         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1848         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1849         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1850         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1851         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1852         
1853         { }
1854 };
1855
1856 /* Enable GPIO mask and set output */
1857 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1858 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1859
1860 /* Clevo m520g init */
1861 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1862         /* headphone output */
1863         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1864         /* line-out */
1865         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1866         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1867         /* Line-in */
1868         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1869         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870         /* CD */
1871         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1872         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1873         /* Mic1 (rear panel) */
1874         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1875         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1876         /* Mic2 (front panel) */
1877         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1878         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1879         /* headphone */
1880         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1881         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1882         /* change to EAPD mode */
1883         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1884         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1885
1886         { }
1887 };
1888
1889 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1890         /* change to EAPD mode */
1891         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1892         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1893
1894         /* Headphone output */
1895         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1896         /* Front output*/
1897         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1898         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1899
1900         /* Line In pin widget for input */
1901         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1902         /* CD pin widget for input */
1903         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1904         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1905         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1906
1907         /* change to EAPD mode */
1908         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1909         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1910
1911         { }
1912 };
1913
1914 /*
1915  * LG m1 express dual
1916  *
1917  * Pin assignment:
1918  *   Rear Line-In/Out (blue): 0x14
1919  *   Build-in Mic-In: 0x15
1920  *   Speaker-out: 0x17
1921  *   HP-Out (green): 0x1b
1922  *   Mic-In/Out (red): 0x19
1923  *   SPDIF-Out: 0x1e
1924  */
1925
1926 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1927 static hda_nid_t alc880_lg_dac_nids[3] = {
1928         0x05, 0x02, 0x03
1929 };
1930
1931 /* seems analog CD is not working */
1932 static struct hda_input_mux alc880_lg_capture_source = {
1933         .num_items = 3,
1934         .items = {
1935                 { "Mic", 0x1 },
1936                 { "Line", 0x5 },
1937                 { "Internal Mic", 0x6 },
1938         },
1939 };
1940
1941 /* 2,4,6 channel modes */
1942 static struct hda_verb alc880_lg_ch2_init[] = {
1943         /* set line-in and mic-in to input */
1944         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1945         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1946         { }
1947 };
1948
1949 static struct hda_verb alc880_lg_ch4_init[] = {
1950         /* set line-in to out and mic-in to input */
1951         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1952         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1953         { }
1954 };
1955
1956 static struct hda_verb alc880_lg_ch6_init[] = {
1957         /* set line-in and mic-in to output */
1958         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1959         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1960         { }
1961 };
1962
1963 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1964         { 2, alc880_lg_ch2_init },
1965         { 4, alc880_lg_ch4_init },
1966         { 6, alc880_lg_ch6_init },
1967 };
1968
1969 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1970         /* FIXME: it's not really "master" but front channels */
1971         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1972         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1973         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1974         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1975         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1976         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1977         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1978         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1979         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1980         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1981         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1982         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1983         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1984         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1985         {
1986                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1987                 .name = "Channel Mode",
1988                 .info = alc_ch_mode_info,
1989                 .get = alc_ch_mode_get,
1990                 .put = alc_ch_mode_put,
1991         },
1992         { } /* end */
1993 };
1994
1995 static struct hda_verb alc880_lg_init_verbs[] = {
1996         /* set capture source to mic-in */
1997         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1998         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1999         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2000         /* mute all amp mixer inputs */
2001         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2002         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2003         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2004         /* line-in to input */
2005         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2006         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2007         /* built-in mic */
2008         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2009         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2010         /* speaker-out */
2011         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2012         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2013         /* mic-in to input */
2014         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2015         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2016         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2017         /* HP-out */
2018         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2019         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2020         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2021         /* jack sense */
2022         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2023         { }
2024 };
2025
2026 /* toggle speaker-output according to the hp-jack state */
2027 static void alc880_lg_automute(struct hda_codec *codec)
2028 {
2029         unsigned int present;
2030         unsigned char bits;
2031
2032         present = snd_hda_codec_read(codec, 0x1b, 0,
2033                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2034         bits = present ? HDA_AMP_MUTE : 0;
2035         snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2036                                  HDA_AMP_MUTE, bits);
2037 }
2038
2039 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2040 {
2041         /* Looks like the unsol event is incompatible with the standard
2042          * definition.  4bit tag is placed at 28 bit!
2043          */
2044         if ((res >> 28) == 0x01)
2045                 alc880_lg_automute(codec);
2046 }
2047
2048 /*
2049  * LG LW20
2050  *
2051  * Pin assignment:
2052  *   Speaker-out: 0x14
2053  *   Mic-In: 0x18
2054  *   Built-in Mic-In: 0x19
2055  *   Line-In: 0x1b
2056  *   HP-Out: 0x1a
2057  *   SPDIF-Out: 0x1e
2058  */
2059
2060 static struct hda_input_mux alc880_lg_lw_capture_source = {
2061         .num_items = 3,
2062         .items = {
2063                 { "Mic", 0x0 },
2064                 { "Internal Mic", 0x1 },
2065                 { "Line In", 0x2 },
2066         },
2067 };
2068
2069 #define alc880_lg_lw_modes alc880_threestack_modes
2070
2071 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2072         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2073         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2074         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2075         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2076         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2077         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2078         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2079         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2080         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2081         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2082         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2083         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2084         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2085         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2086         {
2087                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2088                 .name = "Channel Mode",
2089                 .info = alc_ch_mode_info,
2090                 .get = alc_ch_mode_get,
2091                 .put = alc_ch_mode_put,
2092         },
2093         { } /* end */
2094 };
2095
2096 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2097         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2098         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2099         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2100
2101         /* set capture source to mic-in */
2102         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2103         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2104         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2105         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2106         /* speaker-out */
2107         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2108         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2109         /* HP-out */
2110         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2111         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2112         /* mic-in to input */
2113         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2114         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2115         /* built-in mic */
2116         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2117         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2118         /* jack sense */
2119         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2120         { }
2121 };
2122
2123 /* toggle speaker-output according to the hp-jack state */
2124 static void alc880_lg_lw_automute(struct hda_codec *codec)
2125 {
2126         unsigned int present;
2127         unsigned char bits;
2128
2129         present = snd_hda_codec_read(codec, 0x1b, 0,
2130                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2131         bits = present ? HDA_AMP_MUTE : 0;
2132         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2133                                  HDA_AMP_MUTE, bits);
2134 }
2135
2136 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2137 {
2138         /* Looks like the unsol event is incompatible with the standard
2139          * definition.  4bit tag is placed at 28 bit!
2140          */
2141         if ((res >> 28) == 0x01)
2142                 alc880_lg_lw_automute(codec);
2143 }
2144
2145 #ifdef CONFIG_SND_HDA_POWER_SAVE
2146 static struct hda_amp_list alc880_loopbacks[] = {
2147         { 0x0b, HDA_INPUT, 0 },
2148         { 0x0b, HDA_INPUT, 1 },
2149         { 0x0b, HDA_INPUT, 2 },
2150         { 0x0b, HDA_INPUT, 3 },
2151         { 0x0b, HDA_INPUT, 4 },
2152         { } /* end */
2153 };
2154
2155 static struct hda_amp_list alc880_lg_loopbacks[] = {
2156         { 0x0b, HDA_INPUT, 1 },
2157         { 0x0b, HDA_INPUT, 6 },
2158         { 0x0b, HDA_INPUT, 7 },
2159         { } /* end */
2160 };
2161 #endif
2162
2163 /*
2164  * Common callbacks
2165  */
2166
2167 static int alc_init(struct hda_codec *codec)
2168 {
2169         struct alc_spec *spec = codec->spec;
2170         unsigned int i;
2171
2172         for (i = 0; i < spec->num_init_verbs; i++)
2173                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2174
2175         if (spec->init_hook)
2176                 spec->init_hook(codec);
2177
2178         return 0;
2179 }
2180
2181 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2182 {
2183         struct alc_spec *spec = codec->spec;
2184
2185         if (spec->unsol_event)
2186                 spec->unsol_event(codec, res);
2187 }
2188
2189 #ifdef CONFIG_SND_HDA_POWER_SAVE
2190 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2191 {
2192         struct alc_spec *spec = codec->spec;
2193         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2194 }
2195 #endif
2196
2197 /*
2198  * Analog playback callbacks
2199  */
2200 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2201                                     struct hda_codec *codec,
2202                                     struct snd_pcm_substream *substream)
2203 {
2204         struct alc_spec *spec = codec->spec;
2205         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2206 }
2207
2208 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2209                                        struct hda_codec *codec,
2210                                        unsigned int stream_tag,
2211                                        unsigned int format,
2212                                        struct snd_pcm_substream *substream)
2213 {
2214         struct alc_spec *spec = codec->spec;
2215         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2216                                                 stream_tag, format, substream);
2217 }
2218
2219 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2220                                        struct hda_codec *codec,
2221                                        struct snd_pcm_substream *substream)
2222 {
2223         struct alc_spec *spec = codec->spec;
2224         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2225 }
2226
2227 /*
2228  * Digital out
2229  */
2230 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2231                                         struct hda_codec *codec,
2232                                         struct snd_pcm_substream *substream)
2233 {
2234         struct alc_spec *spec = codec->spec;
2235         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2236 }
2237
2238 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2239                                            struct hda_codec *codec,
2240                                            unsigned int stream_tag,
2241                                            unsigned int format,
2242                                            struct snd_pcm_substream *substream)
2243 {
2244         struct alc_spec *spec = codec->spec;
2245         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2246                                              stream_tag, format, substream);
2247 }
2248
2249 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2250                                          struct hda_codec *codec,
2251                                          struct snd_pcm_substream *substream)
2252 {
2253         struct alc_spec *spec = codec->spec;
2254         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2255 }
2256
2257 /*
2258  * Analog capture
2259  */
2260 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2261                                       struct hda_codec *codec,
2262                                       unsigned int stream_tag,
2263                                       unsigned int format,
2264                                       struct snd_pcm_substream *substream)
2265 {
2266         struct alc_spec *spec = codec->spec;
2267
2268         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2269                                    stream_tag, 0, format);
2270         return 0;
2271 }
2272
2273 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2274                                       struct hda_codec *codec,
2275                                       struct snd_pcm_substream *substream)
2276 {
2277         struct alc_spec *spec = codec->spec;
2278
2279         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2280                                    0, 0, 0);
2281         return 0;
2282 }
2283
2284
2285 /*
2286  */
2287 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2288         .substreams = 1,
2289         .channels_min = 2,
2290         .channels_max = 8,
2291         /* NID is set in alc_build_pcms */
2292         .ops = {
2293                 .open = alc880_playback_pcm_open,
2294                 .prepare = alc880_playback_pcm_prepare,
2295                 .cleanup = alc880_playback_pcm_cleanup
2296         },
2297 };
2298
2299 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2300         .substreams = 2,
2301         .channels_min = 2,
2302         .channels_max = 2,
2303         /* NID is set in alc_build_pcms */
2304         .ops = {
2305                 .prepare = alc880_capture_pcm_prepare,
2306                 .cleanup = alc880_capture_pcm_cleanup
2307         },
2308 };
2309
2310 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2311         .substreams = 1,
2312         .channels_min = 2,
2313         .channels_max = 2,
2314         /* NID is set in alc_build_pcms */
2315         .ops = {
2316                 .open = alc880_dig_playback_pcm_open,
2317                 .close = alc880_dig_playback_pcm_close,
2318                 .prepare = alc880_dig_playback_pcm_prepare
2319         },
2320 };
2321
2322 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2323         .substreams = 1,
2324         .channels_min = 2,
2325         .channels_max = 2,
2326         /* NID is set in alc_build_pcms */
2327 };
2328
2329 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2330 static struct hda_pcm_stream alc_pcm_null_playback = {
2331         .substreams = 0,
2332         .channels_min = 0,
2333         .channels_max = 0,
2334 };
2335
2336 static int alc_build_pcms(struct hda_codec *codec)
2337 {
2338         struct alc_spec *spec = codec->spec;
2339         struct hda_pcm *info = spec->pcm_rec;
2340         int i;
2341
2342         codec->num_pcms = 1;
2343         codec->pcm_info = info;
2344
2345         info->name = spec->stream_name_analog;
2346         if (spec->stream_analog_playback) {
2347                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2348                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2349                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2350         }
2351         if (spec->stream_analog_capture) {
2352                 snd_assert(spec->adc_nids, return -EINVAL);
2353                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2354                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2355         }
2356
2357         if (spec->channel_mode) {
2358                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2359                 for (i = 0; i < spec->num_channel_mode; i++) {
2360                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2361                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2362                         }
2363                 }
2364         }
2365
2366         /* SPDIF for stream index #1 */
2367         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2368                 codec->num_pcms = 2;
2369                 info = spec->pcm_rec + 1;
2370                 info->name = spec->stream_name_digital;
2371                 if (spec->multiout.dig_out_nid &&
2372                     spec->stream_digital_playback) {
2373                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2374                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2375                 }
2376                 if (spec->dig_in_nid &&
2377                     spec->stream_digital_capture) {
2378                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2379                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2380                 }
2381         }
2382
2383         /* If the use of more than one ADC is requested for the current
2384          * model, configure a second analog capture-only PCM.
2385          */
2386         /* Additional Analaog capture for index #2 */
2387         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2388             spec->adc_nids) {
2389                 codec->num_pcms = 3;
2390                 info = spec->pcm_rec + 2;
2391                 info->name = spec->stream_name_analog;
2392                 /* No playback stream for second PCM */
2393                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2394                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2395                 if (spec->stream_analog_capture) {
2396                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2397                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2398                 }
2399         }
2400
2401         return 0;
2402 }
2403
2404 static void alc_free(struct hda_codec *codec)
2405 {
2406         struct alc_spec *spec = codec->spec;
2407         unsigned int i;
2408
2409         if (!spec)
2410                 return;
2411
2412         if (spec->kctl_alloc) {
2413                 for (i = 0; i < spec->num_kctl_used; i++)
2414                         kfree(spec->kctl_alloc[i].name);
2415                 kfree(spec->kctl_alloc);
2416         }
2417         kfree(spec);
2418 }
2419
2420 /*
2421  */
2422 static struct hda_codec_ops alc_patch_ops = {
2423         .build_controls = alc_build_controls,
2424         .build_pcms = alc_build_pcms,
2425         .init = alc_init,
2426         .free = alc_free,
2427         .unsol_event = alc_unsol_event,
2428 #ifdef CONFIG_SND_HDA_POWER_SAVE
2429         .check_power_status = alc_check_power_status,
2430 #endif
2431 };
2432
2433
2434 /*
2435  * Test configuration for debugging
2436  *
2437  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2438  * enum controls.
2439  */
2440 #ifdef CONFIG_SND_DEBUG
2441 static hda_nid_t alc880_test_dac_nids[4] = {
2442         0x02, 0x03, 0x04, 0x05
2443 };
2444
2445 static struct hda_input_mux alc880_test_capture_source = {
2446         .num_items = 7,
2447         .items = {
2448                 { "In-1", 0x0 },
2449                 { "In-2", 0x1 },
2450                 { "In-3", 0x2 },
2451                 { "In-4", 0x3 },
2452                 { "CD", 0x4 },
2453                 { "Front", 0x5 },
2454                 { "Surround", 0x6 },
2455         },
2456 };
2457
2458 static struct hda_channel_mode alc880_test_modes[4] = {
2459         { 2, NULL },
2460         { 4, NULL },
2461         { 6, NULL },
2462         { 8, NULL },
2463 };
2464
2465 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2466                                  struct snd_ctl_elem_info *uinfo)
2467 {
2468         static char *texts[] = {
2469                 "N/A", "Line Out", "HP Out",
2470                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2471         };
2472         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2473         uinfo->count = 1;
2474         uinfo->value.enumerated.items = 8;
2475         if (uinfo->value.enumerated.item >= 8)
2476                 uinfo->value.enumerated.item = 7;
2477         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2478         return 0;
2479 }
2480
2481 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2482                                 struct snd_ctl_elem_value *ucontrol)
2483 {
2484         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2485         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2486         unsigned int pin_ctl, item = 0;
2487
2488         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2489                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2490         if (pin_ctl & AC_PINCTL_OUT_EN) {
2491                 if (pin_ctl & AC_PINCTL_HP_EN)
2492                         item = 2;
2493                 else
2494                         item = 1;
2495         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2496                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2497                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2498                 case AC_PINCTL_VREF_50:  item = 4; break;
2499                 case AC_PINCTL_VREF_GRD: item = 5; break;
2500                 case AC_PINCTL_VREF_80:  item = 6; break;
2501                 case AC_PINCTL_VREF_100: item = 7; break;
2502                 }
2503         }
2504         ucontrol->value.enumerated.item[0] = item;
2505         return 0;
2506 }
2507
2508 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2509                                 struct snd_ctl_elem_value *ucontrol)
2510 {
2511         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2512         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2513         static unsigned int ctls[] = {
2514                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2515                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2516                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2517                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2518                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2519                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2520         };
2521         unsigned int old_ctl, new_ctl;
2522
2523         old_ctl = snd_hda_codec_read(codec, nid, 0,
2524                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2525         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2526         if (old_ctl != new_ctl) {
2527                 int val;
2528                 snd_hda_codec_write_cache(codec, nid, 0,
2529                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
2530                                           new_ctl);
2531                 val = ucontrol->value.enumerated.item[0] >= 3 ?
2532                         HDA_AMP_MUTE : 0;
2533                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2534                                          HDA_AMP_MUTE, val);
2535                 return 1;
2536         }
2537         return 0;
2538 }
2539
2540 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2541                                  struct snd_ctl_elem_info *uinfo)
2542 {
2543         static char *texts[] = {
2544                 "Front", "Surround", "CLFE", "Side"
2545         };
2546         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2547         uinfo->count = 1;
2548         uinfo->value.enumerated.items = 4;
2549         if (uinfo->value.enumerated.item >= 4)
2550                 uinfo->value.enumerated.item = 3;
2551         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2552         return 0;
2553 }
2554
2555 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2556                                 struct snd_ctl_elem_value *ucontrol)
2557 {
2558         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2559         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2560         unsigned int sel;
2561
2562         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2563         ucontrol->value.enumerated.item[0] = sel & 3;
2564         return 0;
2565 }
2566
2567 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2568                                 struct snd_ctl_elem_value *ucontrol)
2569 {
2570         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2571         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2572         unsigned int sel;
2573
2574         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2575         if (ucontrol->value.enumerated.item[0] != sel) {
2576                 sel = ucontrol->value.enumerated.item[0] & 3;
2577                 snd_hda_codec_write_cache(codec, nid, 0,
2578                                           AC_VERB_SET_CONNECT_SEL, sel);
2579                 return 1;
2580         }
2581         return 0;
2582 }
2583
2584 #define PIN_CTL_TEST(xname,nid) {                       \
2585                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2586                         .name = xname,                 \
2587                         .info = alc_test_pin_ctl_info, \
2588                         .get = alc_test_pin_ctl_get,   \
2589                         .put = alc_test_pin_ctl_put,   \
2590                         .private_value = nid           \
2591                         }
2592
2593 #define PIN_SRC_TEST(xname,nid) {                       \
2594                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2595                         .name = xname,                 \
2596                         .info = alc_test_pin_src_info, \
2597                         .get = alc_test_pin_src_get,   \
2598                         .put = alc_test_pin_src_put,   \
2599                         .private_value = nid           \
2600                         }
2601
2602 static struct snd_kcontrol_new alc880_test_mixer[] = {
2603         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2604         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2605         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2606         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2607         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2608         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2609         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2610         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2611         PIN_CTL_TEST("Front Pin Mode", 0x14),
2612         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2613         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2614         PIN_CTL_TEST("Side Pin Mode", 0x17),
2615         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2616         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2617         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2618         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2619         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2620         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2621         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2622         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2623         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2624         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2625         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2626         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2627         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2628         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2629         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2630         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2631         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2632         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2633         {
2634                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2635                 .name = "Channel Mode",
2636                 .info = alc_ch_mode_info,
2637                 .get = alc_ch_mode_get,
2638                 .put = alc_ch_mode_put,
2639         },
2640         { } /* end */
2641 };
2642
2643 static struct hda_verb alc880_test_init_verbs[] = {
2644         /* Unmute inputs of 0x0c - 0x0f */
2645         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2646         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2647         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2648         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2649         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2650         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2651         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2652         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2653         /* Vol output for 0x0c-0x0f */
2654         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2655         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2656         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2657         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2658         /* Set output pins 0x14-0x17 */
2659         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2660         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2661         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2662         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2663         /* Unmute output pins 0x14-0x17 */
2664         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2665         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2666         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2667         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2668         /* Set input pins 0x18-0x1c */
2669         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2670         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2671         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2672         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2673         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2674         /* Mute input pins 0x18-0x1b */
2675         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2676         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2677         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2678         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2679         /* ADC set up */
2680         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2681         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2682         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2683         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2684         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2685         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2686         /* Analog input/passthru */
2687         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2688         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2689         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2690         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2691         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2692         { }
2693 };
2694 #endif
2695
2696 /*
2697  */
2698
2699 static const char *alc880_models[ALC880_MODEL_LAST] = {
2700         [ALC880_3ST]            = "3stack",
2701         [ALC880_TCL_S700]       = "tcl",
2702         [ALC880_3ST_DIG]        = "3stack-digout",
2703         [ALC880_CLEVO]          = "clevo",
2704         [ALC880_5ST]            = "5stack",
2705         [ALC880_5ST_DIG]        = "5stack-digout",
2706         [ALC880_W810]           = "w810",
2707         [ALC880_Z71V]           = "z71v",
2708         [ALC880_6ST]            = "6stack",
2709         [ALC880_6ST_DIG]        = "6stack-digout",
2710         [ALC880_ASUS]           = "asus",
2711         [ALC880_ASUS_W1V]       = "asus-w1v",
2712         [ALC880_ASUS_DIG]       = "asus-dig",
2713         [ALC880_ASUS_DIG2]      = "asus-dig2",
2714         [ALC880_UNIWILL_DIG]    = "uniwill",
2715         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2716         [ALC880_FUJITSU]        = "fujitsu",
2717         [ALC880_F1734]          = "F1734",
2718         [ALC880_LG]             = "lg",
2719         [ALC880_LG_LW]          = "lg-lw",
2720 #ifdef CONFIG_SND_DEBUG
2721         [ALC880_TEST]           = "test",
2722 #endif
2723         [ALC880_AUTO]           = "auto",
2724 };
2725
2726 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2727         /* Broken BIOS configuration */
2728         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2729         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2730
2731         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2732         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2733         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2734         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2735         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2736         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2737         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2738         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2739         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2740
2741         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2742         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2743
2744         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2745         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2746         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2747         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2748         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2749         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2750         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2751         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2752         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2753         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2754         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2755         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2756         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2757         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2758         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2759
2760         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2761         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2762         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2763         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2764         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2765         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2766         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2767         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2768         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2769         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2770         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2771         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2772         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2773         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2774         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2775         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2776         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2777         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2778
2779         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2780         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2781         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2782         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2783
2784         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2785         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2786         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2787         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2788
2789         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2790         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2791         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2792         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2793
2794         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2795         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2796         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2797         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2798         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2799         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2800         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2801         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2802         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2803         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2804         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2805
2806         {}
2807 };
2808
2809 /*
2810  * ALC880 codec presets
2811  */
2812 static struct alc_config_preset alc880_presets[] = {
2813         [ALC880_3ST] = {
2814                 .mixers = { alc880_three_stack_mixer },
2815                 .init_verbs = { alc880_volume_init_verbs,
2816                                 alc880_pin_3stack_init_verbs },
2817                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2818                 .dac_nids = alc880_dac_nids,
2819                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2820                 .channel_mode = alc880_threestack_modes,
2821                 .need_dac_fix = 1,
2822                 .input_mux = &alc880_capture_source,
2823         },
2824         [ALC880_3ST_DIG] = {
2825                 .mixers = { alc880_three_stack_mixer },
2826                 .init_verbs = { alc880_volume_init_verbs,
2827                                 alc880_pin_3stack_init_verbs },
2828                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2829                 .dac_nids = alc880_dac_nids,
2830                 .dig_out_nid = ALC880_DIGOUT_NID,
2831                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2832                 .channel_mode = alc880_threestack_modes,
2833                 .need_dac_fix = 1,
2834                 .input_mux = &alc880_capture_source,
2835         },
2836         [ALC880_TCL_S700] = {
2837                 .mixers = { alc880_tcl_s700_mixer },
2838                 .init_verbs = { alc880_volume_init_verbs,
2839                                 alc880_pin_tcl_S700_init_verbs,
2840                                 alc880_gpio2_init_verbs },
2841                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2842                 .dac_nids = alc880_dac_nids,
2843                 .hp_nid = 0x03,
2844                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2845                 .channel_mode = alc880_2_jack_modes,
2846                 .input_mux = &alc880_capture_source,
2847         },
2848         [ALC880_5ST] = {
2849                 .mixers = { alc880_three_stack_mixer,
2850                             alc880_five_stack_mixer},
2851                 .init_verbs = { alc880_volume_init_verbs,
2852                                 alc880_pin_5stack_init_verbs },
2853                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2854                 .dac_nids = alc880_dac_nids,
2855                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2856                 .channel_mode = alc880_fivestack_modes,
2857                 .input_mux = &alc880_capture_source,
2858         },
2859         [ALC880_5ST_DIG] = {
2860                 .mixers = { alc880_three_stack_mixer,
2861                             alc880_five_stack_mixer },
2862                 .init_verbs = { alc880_volume_init_verbs,
2863                                 alc880_pin_5stack_init_verbs },
2864                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2865                 .dac_nids = alc880_dac_nids,
2866                 .dig_out_nid = ALC880_DIGOUT_NID,
2867                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2868                 .channel_mode = alc880_fivestack_modes,
2869                 .input_mux = &alc880_capture_source,
2870         },
2871         [ALC880_6ST] = {
2872                 .mixers = { alc880_six_stack_mixer },
2873                 .init_verbs = { alc880_volume_init_verbs,
2874                                 alc880_pin_6stack_init_verbs },
2875                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2876                 .dac_nids = alc880_6st_dac_nids,
2877                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2878                 .channel_mode = alc880_sixstack_modes,
2879                 .input_mux = &alc880_6stack_capture_source,
2880         },
2881         [ALC880_6ST_DIG] = {
2882                 .mixers = { alc880_six_stack_mixer },
2883                 .init_verbs = { alc880_volume_init_verbs,
2884                                 alc880_pin_6stack_init_verbs },
2885                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2886                 .dac_nids = alc880_6st_dac_nids,
2887                 .dig_out_nid = ALC880_DIGOUT_NID,
2888                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2889                 .channel_mode = alc880_sixstack_modes,
2890                 .input_mux = &alc880_6stack_capture_source,
2891         },
2892         [ALC880_W810] = {
2893                 .mixers = { alc880_w810_base_mixer },
2894                 .init_verbs = { alc880_volume_init_verbs,
2895                                 alc880_pin_w810_init_verbs,
2896                                 alc880_gpio2_init_verbs },
2897                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2898                 .dac_nids = alc880_w810_dac_nids,
2899                 .dig_out_nid = ALC880_DIGOUT_NID,
2900                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2901                 .channel_mode = alc880_w810_modes,
2902                 .input_mux = &alc880_capture_source,
2903         },
2904         [ALC880_Z71V] = {
2905                 .mixers = { alc880_z71v_mixer },
2906                 .init_verbs = { alc880_volume_init_verbs,
2907                                 alc880_pin_z71v_init_verbs },
2908                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2909                 .dac_nids = alc880_z71v_dac_nids,
2910                 .dig_out_nid = ALC880_DIGOUT_NID,
2911                 .hp_nid = 0x03,
2912                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2913                 .channel_mode = alc880_2_jack_modes,
2914                 .input_mux = &alc880_capture_source,
2915         },
2916         [ALC880_F1734] = {
2917                 .mixers = { alc880_f1734_mixer },
2918                 .init_verbs = { alc880_volume_init_verbs,
2919                                 alc880_pin_f1734_init_verbs },
2920                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2921                 .dac_nids = alc880_f1734_dac_nids,
2922                 .hp_nid = 0x02,
2923                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2924                 .channel_mode = alc880_2_jack_modes,
2925                 .input_mux = &alc880_capture_source,
2926         },
2927         [ALC880_ASUS] = {
2928                 .mixers = { alc880_asus_mixer },
2929                 .init_verbs = { alc880_volume_init_verbs,
2930                                 alc880_pin_asus_init_verbs,
2931                                 alc880_gpio1_init_verbs },
2932                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2933                 .dac_nids = alc880_asus_dac_nids,
2934                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2935                 .channel_mode = alc880_asus_modes,
2936                 .need_dac_fix = 1,
2937                 .input_mux = &alc880_capture_source,
2938         },
2939         [ALC880_ASUS_DIG] = {
2940                 .mixers = { alc880_asus_mixer },
2941                 .init_verbs = { alc880_volume_init_verbs,
2942                                 alc880_pin_asus_init_verbs,
2943                                 alc880_gpio1_init_verbs },
2944                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2945                 .dac_nids = alc880_asus_dac_nids,
2946                 .dig_out_nid = ALC880_DIGOUT_NID,
2947                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2948                 .channel_mode = alc880_asus_modes,
2949                 .need_dac_fix = 1,
2950                 .input_mux = &alc880_capture_source,
2951         },
2952         [ALC880_ASUS_DIG2] = {
2953                 .mixers = { alc880_asus_mixer },
2954                 .init_verbs = { alc880_volume_init_verbs,
2955                                 alc880_pin_asus_init_verbs,
2956                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2957                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2958                 .dac_nids = alc880_asus_dac_nids,
2959                 .dig_out_nid = ALC880_DIGOUT_NID,
2960                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2961                 .channel_mode = alc880_asus_modes,
2962                 .need_dac_fix = 1,
2963                 .input_mux = &alc880_capture_source,
2964         },
2965         [ALC880_ASUS_W1V] = {
2966                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2967                 .init_verbs = { alc880_volume_init_verbs,
2968                                 alc880_pin_asus_init_verbs,
2969                                 alc880_gpio1_init_verbs },
2970                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2971                 .dac_nids = alc880_asus_dac_nids,
2972                 .dig_out_nid = ALC880_DIGOUT_NID,
2973                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2974                 .channel_mode = alc880_asus_modes,
2975                 .need_dac_fix = 1,
2976                 .input_mux = &alc880_capture_source,
2977         },
2978         [ALC880_UNIWILL_DIG] = {
2979                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2980                 .init_verbs = { alc880_volume_init_verbs,
2981                                 alc880_pin_asus_init_verbs },
2982                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2983                 .dac_nids = alc880_asus_dac_nids,
2984                 .dig_out_nid = ALC880_DIGOUT_NID,
2985                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2986                 .channel_mode = alc880_asus_modes,
2987                 .need_dac_fix = 1,
2988                 .input_mux = &alc880_capture_source,
2989         },
2990         [ALC880_UNIWILL] = {
2991                 .mixers = { alc880_uniwill_mixer },
2992                 .init_verbs = { alc880_volume_init_verbs,
2993                                 alc880_uniwill_init_verbs },
2994                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2995                 .dac_nids = alc880_asus_dac_nids,
2996                 .dig_out_nid = ALC880_DIGOUT_NID,
2997                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2998                 .channel_mode = alc880_threestack_modes,
2999                 .need_dac_fix = 1,
3000                 .input_mux = &alc880_capture_source,
3001                 .unsol_event = alc880_uniwill_unsol_event,
3002                 .init_hook = alc880_uniwill_automute,
3003         },
3004         [ALC880_UNIWILL_P53] = {
3005                 .mixers = { alc880_uniwill_p53_mixer },
3006                 .init_verbs = { alc880_volume_init_verbs,
3007                                 alc880_uniwill_p53_init_verbs },
3008                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3009                 .dac_nids = alc880_asus_dac_nids,
3010                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3011                 .channel_mode = alc880_threestack_modes,
3012                 .input_mux = &alc880_capture_source,
3013                 .unsol_event = alc880_uniwill_p53_unsol_event,
3014                 .init_hook = alc880_uniwill_p53_hp_automute,
3015         },
3016         [ALC880_FUJITSU] = {
3017                 .mixers = { alc880_fujitsu_mixer,
3018                             alc880_pcbeep_mixer, },
3019                 .init_verbs = { alc880_volume_init_verbs,
3020                                 alc880_uniwill_p53_init_verbs,
3021                                 alc880_beep_init_verbs },
3022                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3023                 .dac_nids = alc880_dac_nids,
3024                 .dig_out_nid = ALC880_DIGOUT_NID,
3025                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3026                 .channel_mode = alc880_2_jack_modes,
3027                 .input_mux = &alc880_capture_source,
3028                 .unsol_event = alc880_uniwill_p53_unsol_event,
3029                 .init_hook = alc880_uniwill_p53_hp_automute,
3030         },
3031         [ALC880_CLEVO] = {
3032                 .mixers = { alc880_three_stack_mixer },
3033                 .init_verbs = { alc880_volume_init_verbs,
3034                                 alc880_pin_clevo_init_verbs },
3035                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3036                 .dac_nids = alc880_dac_nids,
3037                 .hp_nid = 0x03,
3038                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3039                 .channel_mode = alc880_threestack_modes,
3040                 .need_dac_fix = 1,
3041                 .input_mux = &alc880_capture_source,
3042         },
3043         [ALC880_LG] = {
3044                 .mixers = { alc880_lg_mixer },
3045                 .init_verbs = { alc880_volume_init_verbs,
3046                                 alc880_lg_init_verbs },
3047                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3048                 .dac_nids = alc880_lg_dac_nids,
3049                 .dig_out_nid = ALC880_DIGOUT_NID,
3050                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3051                 .channel_mode = alc880_lg_ch_modes,
3052                 .need_dac_fix = 1,
3053                 .input_mux = &alc880_lg_capture_source,
3054                 .unsol_event = alc880_lg_unsol_event,
3055                 .init_hook = alc880_lg_automute,
3056 #ifdef CONFIG_SND_HDA_POWER_SAVE
3057                 .loopbacks = alc880_lg_loopbacks,
3058 #endif
3059         },
3060         [ALC880_LG_LW] = {
3061                 .mixers = { alc880_lg_lw_mixer },
3062                 .init_verbs = { alc880_volume_init_verbs,
3063                                 alc880_lg_lw_init_verbs },
3064                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3065                 .dac_nids = alc880_dac_nids,
3066                 .dig_out_nid = ALC880_DIGOUT_NID,
3067                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3068                 .channel_mode = alc880_lg_lw_modes,
3069                 .input_mux = &alc880_lg_lw_capture_source,
3070                 .unsol_event = alc880_lg_lw_unsol_event,
3071                 .init_hook = alc880_lg_lw_automute,
3072         },
3073 #ifdef CONFIG_SND_DEBUG
3074         [ALC880_TEST] = {
3075                 .mixers = { alc880_test_mixer },
3076                 .init_verbs = { alc880_test_init_verbs },
3077                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3078                 .dac_nids = alc880_test_dac_nids,
3079                 .dig_out_nid = ALC880_DIGOUT_NID,
3080                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3081                 .channel_mode = alc880_test_modes,
3082                 .input_mux = &alc880_test_capture_source,
3083         },
3084 #endif
3085 };
3086
3087 /*
3088  * Automatic parse of I/O pins from the BIOS configuration
3089  */
3090
3091 #define NUM_CONTROL_ALLOC       32
3092 #define NUM_VERB_ALLOC          32
3093
3094 enum {
3095         ALC_CTL_WIDGET_VOL,
3096         ALC_CTL_WIDGET_MUTE,
3097         ALC_CTL_BIND_MUTE,
3098 };
3099 static struct snd_kcontrol_new alc880_control_templates[] = {
3100         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3101         HDA_CODEC_MUTE(NULL, 0, 0, 0),
3102         HDA_BIND_MUTE(NULL, 0, 0, 0),
3103 };
3104
3105 /* add dynamic controls */
3106 static int add_control(struct alc_spec *spec, int type, const char *name,
3107                        unsigned long val)
3108 {
3109         struct snd_kcontrol_new *knew;
3110
3111         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3112                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3113
3114                 /* array + terminator */
3115                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3116                 if (!knew)
3117                         return -ENOMEM;
3118                 if (spec->kctl_alloc) {
3119                         memcpy(knew, spec->kctl_alloc,
3120                                sizeof(*knew) * spec->num_kctl_alloc);
3121                         kfree(spec->kctl_alloc);
3122                 }
3123                 spec->kctl_alloc = knew;
3124                 spec->num_kctl_alloc = num;
3125         }
3126
3127         knew = &spec->kctl_alloc[spec->num_kctl_used];
3128         *knew = alc880_control_templates[type];
3129         knew->name = kstrdup(name, GFP_KERNEL);
3130         if (!knew->name)
3131                 return -ENOMEM;
3132         knew->private_value = val;
3133         spec->num_kctl_used++;
3134         return 0;
3135 }
3136
3137 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
3138 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
3139 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
3140 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
3141 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
3142 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
3143 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
3144 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
3145 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
3146 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
3147 #define ALC880_PIN_CD_NID               0x1c
3148
3149 /* fill in the dac_nids table from the parsed pin configuration */
3150 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3151                                      const struct auto_pin_cfg *cfg)
3152 {
3153         hda_nid_t nid;
3154         int assigned[4];
3155         int i, j;
3156
3157         memset(assigned, 0, sizeof(assigned));
3158         spec->multiout.dac_nids = spec->private_dac_nids;
3159
3160         /* check the pins hardwired to audio widget */
3161         for (i = 0; i < cfg->line_outs; i++) {
3162                 nid = cfg->line_out_pins[i];
3163                 if (alc880_is_fixed_pin(nid)) {
3164                         int idx = alc880_fixed_pin_idx(nid);
3165                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3166                         assigned[idx] = 1;
3167                 }
3168         }
3169         /* left pins can be connect to any audio widget */
3170         for (i = 0; i < cfg->line_outs; i++) {
3171                 nid = cfg->line_out_pins[i];
3172                 if (alc880_is_fixed_pin(nid))
3173                         continue;
3174                 /* search for an empty channel */
3175                 for (j = 0; j < cfg->line_outs; j++) {
3176                         if (!assigned[j]) {
3177                                 spec->multiout.dac_nids[i] =
3178                                         alc880_idx_to_dac(j);
3179                                 assigned[j] = 1;
3180                                 break;
3181                         }
3182                 }
3183         }
3184         spec->multiout.num_dacs = cfg->line_outs;
3185         return 0;
3186 }
3187
3188 /* add playback controls from the parsed DAC table */
3189 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3190                                              const struct auto_pin_cfg *cfg)
3191 {
3192         char name[32];
3193         static const char *chname[4] = {
3194                 "Front", "Surround", NULL /*CLFE*/, "Side"
3195         };
3196         hda_nid_t nid;
3197         int i, err;
3198
3199         for (i = 0; i < cfg->line_outs; i++) {
3200                 if (!spec->multiout.dac_nids[i])
3201                         continue;
3202                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3203                 if (i == 2) {
3204                         /* Center/LFE */
3205                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3206                                           "Center Playback Volume",
3207                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3208                                                               HDA_OUTPUT));
3209                         if (err < 0)
3210                                 return err;
3211                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3212                                           "LFE Playback Volume",
3213                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3214                                                               HDA_OUTPUT));
3215                         if (err < 0)
3216                                 return err;
3217                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3218                                           "Center Playback Switch",
3219                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3220                                                               HDA_INPUT));
3221                         if (err < 0)
3222                                 return err;
3223                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3224                                           "LFE Playback Switch",
3225                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3226                                                               HDA_INPUT));
3227                         if (err < 0)
3228                                 return err;
3229                 } else {
3230                         sprintf(name, "%s Playback Volume", chname[i]);
3231                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3232                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3233                                                               HDA_OUTPUT));
3234                         if (err < 0)
3235                                 return err;
3236                         sprintf(name, "%s Playback Switch", chname[i]);
3237                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3238                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3239                                                               HDA_INPUT));
3240                         if (err < 0)
3241                                 return err;
3242                 }
3243         }
3244         return 0;
3245 }
3246
3247 /* add playback controls for speaker and HP outputs */
3248 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3249                                         const char *pfx)
3250 {
3251         hda_nid_t nid;
3252         int err;
3253         char name[32];
3254
3255         if (!pin)
3256                 return 0;
3257
3258         if (alc880_is_fixed_pin(pin)) {
3259                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3260                 /* specify the DAC as the extra output */
3261                 if (!spec->multiout.hp_nid)
3262                         spec->multiout.hp_nid = nid;
3263                 else
3264                         spec->multiout.extra_out_nid[0] = nid;
3265                 /* control HP volume/switch on the output mixer amp */
3266                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3267                 sprintf(name, "%s Playback Volume", pfx);
3268                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3269                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3270                 if (err < 0)
3271                         return err;
3272                 sprintf(name, "%s Playback Switch", pfx);
3273                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3274                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3275                 if (err < 0)
3276                         return err;
3277         } else if (alc880_is_multi_pin(pin)) {
3278                 /* set manual connection */
3279                 /* we have only a switch on HP-out PIN */
3280                 sprintf(name, "%s Playback Switch", pfx);
3281                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3282                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3283                 if (err < 0)
3284                         return err;
3285         }
3286         return 0;
3287 }
3288
3289 /* create input playback/capture controls for the given pin */
3290 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3291                             const char *ctlname,
3292                             int idx, hda_nid_t mix_nid)
3293 {
3294         char name[32];
3295         int err;
3296
3297         sprintf(name, "%s Playback Volume", ctlname);
3298         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3299                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3300         if (err < 0)
3301                 return err;
3302         sprintf(name, "%s Playback Switch", ctlname);
3303         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3304                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3305         if (err < 0)
3306                 return err;
3307         return 0;
3308 }
3309
3310 /* create playback/capture controls for input pins */
3311 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3312                                                 const struct auto_pin_cfg *cfg)
3313 {
3314         struct hda_input_mux *imux = &spec->private_imux;
3315         int i, err, idx;
3316
3317         for (i = 0; i < AUTO_PIN_LAST; i++) {
3318                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3319                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3320                         err = new_analog_input(spec, cfg->input_pins[i],
3321                                                auto_pin_cfg_labels[i],
3322                                                idx, 0x0b);
3323                         if (err < 0)
3324                                 return err;
3325                         imux->items[imux->num_items].label =
3326                                 auto_pin_cfg_labels[i];
3327                         imux->items[imux->num_items].index =
3328                                 alc880_input_pin_idx(cfg->input_pins[i]);
3329                         imux->num_items++;
3330                 }
3331         }
3332         return 0;
3333 }
3334
3335 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3336                                               hda_nid_t nid, int pin_type,
3337                                               int dac_idx)
3338 {
3339         /* set as output */
3340         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3341                             pin_type);
3342         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3343                             AMP_OUT_UNMUTE);
3344         /* need the manual connection? */
3345         if (alc880_is_multi_pin(nid)) {
3346                 struct alc_spec *spec = codec->spec;
3347                 int idx = alc880_multi_pin_idx(nid);
3348                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3349                                     AC_VERB_SET_CONNECT_SEL,
3350                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3351         }
3352 }
3353
3354 static int get_pin_type(int line_out_type)
3355 {
3356         if (line_out_type == AUTO_PIN_HP_OUT)
3357                 return PIN_HP;
3358         else
3359                 return PIN_OUT;
3360 }
3361
3362 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3363 {
3364         struct alc_spec *spec = codec->spec;
3365         int i;
3366         
3367         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3368         for (i = 0; i < spec->autocfg.line_outs; i++) {
3369                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3370                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3371                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3372         }
3373 }
3374
3375 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3376 {
3377         struct alc_spec *spec = codec->spec;
3378         hda_nid_t pin;
3379
3380         pin = spec->autocfg.speaker_pins[0];
3381         if (pin) /* connect to front */
3382                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3383         pin = spec->autocfg.hp_pins[0];
3384         if (pin) /* connect to front */
3385                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3386 }
3387
3388 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3389 {
3390         struct alc_spec *spec = codec->spec;
3391         int i;
3392
3393         for (i = 0; i < AUTO_PIN_LAST; i++) {
3394                 hda_nid_t nid = spec->autocfg.input_pins[i];
3395                 if (alc880_is_input_pin(nid)) {
3396                         snd_hda_codec_write(codec, nid, 0,
3397                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3398                                             i <= AUTO_PIN_FRONT_MIC ?
3399                                             PIN_VREF80 : PIN_IN);
3400                         if (nid != ALC880_PIN_CD_NID)
3401                                 snd_hda_codec_write(codec, nid, 0,
3402                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3403                                                     AMP_OUT_MUTE);
3404                 }
3405         }
3406 }
3407
3408 /* parse the BIOS configuration and set up the alc_spec */
3409 /* return 1 if successful, 0 if the proper config is not found,
3410  * or a negative error code
3411  */
3412 static int alc880_parse_auto_config(struct hda_codec *codec)
3413 {
3414         struct alc_spec *spec = codec->spec;
3415         int err;
3416         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3417
3418         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3419                                            alc880_ignore);
3420         if (err < 0)
3421                 return err;
3422         if (!spec->autocfg.line_outs)
3423                 return 0; /* can't find valid BIOS pin config */
3424
3425         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3426         if (err < 0)
3427                 return err;
3428         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3429         if (err < 0)
3430                 return err;
3431         err = alc880_auto_create_extra_out(spec,
3432                                            spec->autocfg.speaker_pins[0],
3433                                            "Speaker");
3434         if (err < 0)
3435                 return err;
3436         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3437                                            "Headphone");
3438         if (err < 0)
3439                 return err;
3440         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3441         if (err < 0)
3442                 return err;
3443
3444         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3445
3446         if (spec->autocfg.dig_out_pin)
3447                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3448         if (spec->autocfg.dig_in_pin)
3449                 spec->dig_in_nid = ALC880_DIGIN_NID;
3450
3451         if (spec->kctl_alloc)
3452                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3453
3454         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3455
3456         spec->num_mux_defs = 1;
3457         spec->input_mux = &spec->private_imux;
3458
3459         return 1;
3460 }
3461
3462 /* additional initialization for auto-configuration model */
3463 static void alc880_auto_init(struct hda_codec *codec)
3464 {
3465         alc880_auto_init_multi_out(codec);
3466         alc880_auto_init_extra_out(codec);
3467         alc880_auto_init_analog_input(codec);
3468 }
3469
3470 /*
3471  * OK, here we have finally the patch for ALC880
3472  */
3473
3474 static int patch_alc880(struct hda_codec *codec)
3475 {
3476         struct alc_spec *spec;
3477         int board_config;
3478         int err;
3479
3480         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3481         if (spec == NULL)
3482                 return -ENOMEM;
3483
3484         codec->spec = spec;
3485
3486         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3487                                                   alc880_models,
3488                                                   alc880_cfg_tbl);
3489         if (board_config < 0) {
3490                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3491                        "trying auto-probe from BIOS...\n");
3492                 board_config = ALC880_AUTO;
3493         }
3494
3495         if (board_config == ALC880_AUTO) {
3496                 /* automatic parse from the BIOS config */
3497                 err = alc880_parse_auto_config(codec);
3498                 if (err < 0) {
3499                         alc_free(codec);
3500                         return err;
3501                 } else if (!err) {
3502                         printk(KERN_INFO
3503                                "hda_codec: Cannot set up configuration "
3504                                "from BIOS.  Using 3-stack mode...\n");
3505                         board_config = ALC880_3ST;
3506                 }
3507         }
3508
3509         if (board_config != ALC880_AUTO)
3510                 setup_preset(spec, &alc880_presets[board_config]);
3511
3512         spec->stream_name_analog = "ALC880 Analog";
3513         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3514         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3515
3516         spec->stream_name_digital = "ALC880 Digital";
3517         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3518         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3519
3520         if (!spec->adc_nids && spec->input_mux) {
3521                 /* check whether NID 0x07 is valid */
3522                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3523                 /* get type */
3524                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3525                 if (wcap != AC_WID_AUD_IN) {
3526                         spec->adc_nids = alc880_adc_nids_alt;
3527                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3528                         spec->mixers[spec->num_mixers] =
3529                                 alc880_capture_alt_mixer;
3530                         spec->num_mixers++;
3531                 } else {
3532                         spec->adc_nids = alc880_adc_nids;
3533                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3534                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3535                         spec->num_mixers++;
3536                 }
3537         }
3538
3539         codec->patch_ops = alc_patch_ops;
3540         if (board_config == ALC880_AUTO)
3541                 spec->init_hook = alc880_auto_init;
3542 #ifdef CONFIG_SND_HDA_POWER_SAVE
3543         if (!spec->loopback.amplist)
3544                 spec->loopback.amplist = alc880_loopbacks;
3545 #endif
3546
3547         return 0;
3548 }
3549
3550
3551 /*
3552  * ALC260 support
3553  */
3554
3555 static hda_nid_t alc260_dac_nids[1] = {
3556         /* front */
3557         0x02,
3558 };
3559
3560 static hda_nid_t alc260_adc_nids[1] = {
3561         /* ADC0 */
3562         0x04,
3563 };
3564
3565 static hda_nid_t alc260_adc_nids_alt[1] = {
3566         /* ADC1 */
3567         0x05,
3568 };
3569
3570 static hda_nid_t alc260_hp_adc_nids[2] = {
3571         /* ADC1, 0 */
3572         0x05, 0x04
3573 };
3574
3575 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3576  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3577  */
3578 static hda_nid_t alc260_dual_adc_nids[2] = {
3579         /* ADC0, ADC1 */
3580         0x04, 0x05
3581 };
3582
3583 #define ALC260_DIGOUT_NID       0x03
3584 #define ALC260_DIGIN_NID        0x06
3585
3586 static struct hda_input_mux alc260_capture_source = {
3587         .num_items = 4,
3588         .items = {
3589                 { "Mic", 0x0 },
3590                 { "Front Mic", 0x1 },
3591                 { "Line", 0x2 },
3592                 { "CD", 0x4 },
3593         },
3594 };
3595
3596 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3597  * headphone jack and the internal CD lines since these are the only pins at
3598  * which audio can appear.  For flexibility, also allow the option of
3599  * recording the mixer output on the second ADC (ADC0 doesn't have a
3600  * connection to the mixer output).
3601  */
3602 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3603         {
3604                 .num_items = 3,
3605                 .items = {
3606                         { "Mic/Line", 0x0 },
3607                         { "CD", 0x4 },
3608                         { "Headphone", 0x2 },
3609                 },
3610         },
3611         {
3612                 .num_items = 4,
3613                 .items = {
3614                         { "Mic/Line", 0x0 },
3615                         { "CD", 0x4 },
3616                         { "Headphone", 0x2 },
3617                         { "Mixer", 0x5 },
3618                 },
3619         },
3620
3621 };
3622
3623 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3624  * the Fujitsu S702x, but jacks are marked differently.
3625  */
3626 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3627         {
3628                 .num_items = 4,
3629                 .items = {
3630                         { "Mic", 0x0 },
3631                         { "Line", 0x2 },
3632                         { "CD", 0x4 },
3633                         { "Headphone", 0x5 },
3634                 },
3635         },
3636         {
3637                 .num_items = 5,
3638                 .items = {
3639                         { "Mic", 0x0 },
3640                         { "Line", 0x2 },
3641                         { "CD", 0x4 },
3642                         { "Headphone", 0x6 },
3643                         { "Mixer", 0x5 },
3644                 },
3645         },
3646 };
3647 /*
3648  * This is just place-holder, so there's something for alc_build_pcms to look
3649  * at when it calculates the maximum number of channels. ALC260 has no mixer
3650  * element which allows changing the channel mode, so the verb list is
3651  * never used.
3652  */
3653 static struct hda_channel_mode alc260_modes[1] = {
3654         { 2, NULL },
3655 };
3656
3657
3658 /* Mixer combinations
3659  *
3660  * basic: base_output + input + pc_beep + capture
3661  * HP: base_output + input + capture_alt
3662  * HP_3013: hp_3013 + input + capture
3663  * fujitsu: fujitsu + capture
3664  * acer: acer + capture
3665  */
3666
3667 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3668         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3669         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3670         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3671         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3672         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3673         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3674         { } /* end */
3675 };
3676
3677 static struct snd_kcontrol_new alc260_input_mixer[] = {
3678         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3679         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3680         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3681         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3682         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3683         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3684         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3685         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3686         { } /* end */
3687 };
3688
3689 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3690         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3691         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3692         { } /* end */
3693 };
3694
3695 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3696         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3697         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3698         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3699         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3700         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3701         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3702         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3703         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3704         { } /* end */
3705 };
3706
3707 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3708  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3709  */
3710 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3711         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3712         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3713         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3714         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3715         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3716         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3717         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3718         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3719         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3720         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3721         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3722         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3723         { } /* end */
3724 };
3725
3726 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3727  * versions of the ALC260 don't act on requests to enable mic bias from NID
3728  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3729  * datasheet doesn't mention this restriction.  At this stage it's not clear
3730  * whether this behaviour is intentional or is a hardware bug in chip
3731  * revisions available in early 2006.  Therefore for now allow the
3732  * "Headphone Jack Mode" control to span all choices, but if it turns out
3733  * that the lack of mic bias for this NID is intentional we could change the
3734  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3735  *
3736  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3737  * don't appear to make the mic bias available from the "line" jack, even
3738  * though the NID used for this jack (0x14) can supply it.  The theory is
3739  * that perhaps Acer have included blocking capacitors between the ALC260
3740  * and the output jack.  If this turns out to be the case for all such
3741  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3742  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3743  *
3744  * The C20x Tablet series have a mono internal speaker which is controlled
3745  * via the chip's Mono sum widget and pin complex, so include the necessary
3746  * controls for such models.  On models without a "mono speaker" the control
3747  * won't do anything.
3748  */
3749 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3750         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3751         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3752         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3753         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3754                               HDA_OUTPUT),
3755         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3756                            HDA_INPUT),
3757         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3758         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3759         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3760         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3761         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3762         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3763         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3764         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3765         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3766         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3767         { } /* end */
3768 };
3769
3770 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3771  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3772  */
3773 static struct snd_kcontrol_new alc260_will_mixer[] = {
3774         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3775         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3776         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3777         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3778         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3779         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3780         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3781         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3782         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3783         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3784         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3785         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3786         { } /* end */
3787 };
3788
3789 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3790  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3791  */
3792 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3793         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3794         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3795         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3796         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3797         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3798         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3799         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3800         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3801         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3802         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3803         { } /* end */
3804 };
3805
3806 /* capture mixer elements */
3807 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3808         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3809         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3810         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3811         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3812         {
3813                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3814                 /* The multiple "Capture Source" controls confuse alsamixer
3815                  * So call somewhat different..
3816                  * FIXME: the controls appear in the "playback" view!
3817                  */
3818                 /* .name = "Capture Source", */
3819                 .name = "Input Source",
3820                 .count = 2,
3821                 .info = alc_mux_enum_info,
3822                 .get = alc_mux_enum_get,
3823                 .put = alc_mux_enum_put,
3824         },
3825         { } /* end */
3826 };
3827
3828 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3829         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3830         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3831         {
3832                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3833                 /* The multiple "Capture Source" controls confuse alsamixer
3834                  * So call somewhat different..
3835                  * FIXME: the controls appear in the "playback" view!
3836                  */
3837                 /* .name = "Capture Source", */
3838                 .name = "Input Source",
3839                 .count = 1,
3840                 .info = alc_mux_enum_info,
3841                 .get = alc_mux_enum_get,
3842                 .put = alc_mux_enum_put,
3843         },
3844         { } /* end */
3845 };
3846
3847 /*
3848  * initialization verbs
3849  */
3850 static struct hda_verb alc260_init_verbs[] = {
3851         /* Line In pin widget for input */
3852         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3853         /* CD pin widget for input */
3854         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3855         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3856         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3857         /* Mic2 (front panel) pin widget for input and vref at 80% */
3858         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3859         /* LINE-2 is used for line-out in rear */
3860         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3861         /* select line-out */
3862         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3863         /* LINE-OUT pin */
3864         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3865         /* enable HP */
3866         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3867         /* enable Mono */
3868         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3869         /* mute capture amp left and right */
3870         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3871         /* set connection select to line in (default select for this ADC) */
3872         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3873         /* mute capture amp left and right */
3874         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3875         /* set connection select to line in (default select for this ADC) */
3876         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3877         /* set vol=0 Line-Out mixer amp left and right */
3878         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3879         /* unmute pin widget amp left and right (no gain on this amp) */
3880         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3881         /* set vol=0 HP mixer amp left and right */
3882         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3883         /* unmute pin widget amp left and right (no gain on this amp) */
3884         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3885         /* set vol=0 Mono mixer amp left and right */
3886         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3887         /* unmute pin widget amp left and right (no gain on this amp) */
3888         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3889         /* unmute LINE-2 out pin */
3890         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3891         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3892          * Line In 2 = 0x03
3893          */
3894         /* mute analog inputs */
3895         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3896         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3897         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3898         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3899         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3900         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3901         /* mute Front out path */
3902         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3903         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3904         /* mute Headphone out path */
3905         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3906         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3907         /* mute Mono out path */
3908         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3909         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3910         { }
3911 };
3912
3913 #if 0 /* should be identical with alc260_init_verbs? */
3914 static struct hda_verb alc260_hp_init_verbs[] = {
3915         /* Headphone and output */
3916         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3917         /* mono output */
3918         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3919         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3920         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3921         /* Mic2 (front panel) pin widget for input and vref at 80% */
3922         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3923         /* Line In pin widget for input */
3924         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3925         /* Line-2 pin widget for output */
3926         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3927         /* CD pin widget for input */
3928         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3929         /* unmute amp left and right */
3930         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3931         /* set connection select to line in (default select for this ADC) */
3932         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3933         /* unmute Line-Out mixer amp left and right (volume = 0) */
3934         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3935         /* mute pin widget amp left and right (no gain on this amp) */
3936         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3937         /* unmute HP mixer amp left and right (volume = 0) */
3938         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3939         /* mute pin widget amp left and right (no gain on this amp) */
3940         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3941         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3942          * Line In 2 = 0x03
3943          */
3944         /* mute analog inputs */
3945         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3946         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3947         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3948         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3949         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3950         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3951         /* Unmute Front out path */
3952         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3953         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3954         /* Unmute Headphone out path */
3955         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3956         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3957         /* Unmute Mono out path */
3958         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3959         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3960         { }
3961 };
3962 #endif
3963
3964 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3965         /* Line out and output */
3966         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3967         /* mono output */
3968         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3969         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3970         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3971         /* Mic2 (front panel) pin widget for input and vref at 80% */
3972         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3973         /* Line In pin widget for input */
3974         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3975         /* Headphone pin widget for output */
3976         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3977         /* CD pin widget for input */
3978         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3979         /* unmute amp left and right */
3980         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3981         /* set connection select to line in (default select for this ADC) */
3982         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3983         /* unmute Line-Out mixer amp left and right (volume = 0) */
3984         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3985         /* mute pin widget amp left and right (no gain on this amp) */
3986         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3987         /* unmute HP mixer amp left and right (volume = 0) */
3988         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3989         /* mute pin widget amp left and right (no gain on this amp) */
3990         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3991         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3992          * Line In 2 = 0x03
3993          */
3994         /* mute analog inputs */
3995         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3996         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3997         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3998         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3999         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4000         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4001         /* Unmute Front out path */
4002         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4003         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4004         /* Unmute Headphone out path */
4005         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4006         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4007         /* Unmute Mono out path */
4008         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4009         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4010         { }
4011 };
4012
4013 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4014  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4015  * audio = 0x16, internal speaker = 0x10.
4016  */
4017 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4018         /* Disable all GPIOs */
4019         {0x01, AC_VERB_SET_GPIO_MASK, 0},
4020         /* Internal speaker is connected to headphone pin */
4021         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4022         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4023         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4024         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4025         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4026         /* Ensure all other unused pins are disabled and muted. */
4027         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4028         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4029         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4030         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4031         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4032         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4033         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4034         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4035
4036         /* Disable digital (SPDIF) pins */
4037         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4038         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4039
4040         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
4041          * when acting as an output.
4042          */
4043         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4044
4045         /* Start with output sum widgets muted and their output gains at min */
4046         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4047         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4048         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4049         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4050         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4051         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4052         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4053         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4054         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4055
4056         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4057         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4058         /* Unmute Line1 pin widget output buffer since it starts as an output.
4059          * If the pin mode is changed by the user the pin mode control will
4060          * take care of enabling the pin's input/output buffers as needed.
4061          * Therefore there's no need to enable the input buffer at this
4062          * stage.
4063          */
4064         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4065         /* Unmute input buffer of pin widget used for Line-in (no equiv 
4066          * mixer ctrl)
4067          */
4068         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4069
4070         /* Mute capture amp left and right */
4071         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4072         /* Set ADC connection select to match default mixer setting - line 
4073          * in (on mic1 pin)
4074          */
4075         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4076
4077         /* Do the same for the second ADC: mute capture input amp and
4078          * set ADC connection to line in (on mic1 pin)
4079          */
4080         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4081         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4082
4083         /* Mute all inputs to mixer widget (even unconnected ones) */
4084         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4085         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4086         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4087         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4088         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4089         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4090         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4091         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4092
4093         { }
4094 };
4095
4096 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4097  * similar laptops (adapted from Fujitsu init verbs).
4098  */
4099 static struct hda_verb alc260_acer_init_verbs[] = {
4100         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4101          * the headphone jack.  Turn this on and rely on the standard mute
4102          * methods whenever the user wants to turn these outputs off.
4103          */
4104         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4105         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4106         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4107         /* Internal speaker/Headphone jack is connected to Line-out pin */
4108         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4109         /* Internal microphone/Mic jack is connected to Mic1 pin */
4110         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4111         /* Line In jack is connected to Line1 pin */
4112         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4113         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4114         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4115         /* Ensure all other unused pins are disabled and muted. */
4116         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4117         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4118         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4119         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4120         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4121         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4122         /* Disable digital (SPDIF) pins */
4123         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4124         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4125
4126         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
4127          * bus when acting as outputs.
4128          */
4129         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4130         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4131
4132         /* Start with output sum widgets muted and their output gains at min */
4133         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4134         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4135         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4136         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4137         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4138         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4139         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4140         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4141         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4142
4143         /* Unmute Line-out pin widget amp left and right
4144          * (no equiv mixer ctrl)
4145          */
4146         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4147         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4148         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4149         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4150          * inputs. If the pin mode is changed by the user the pin mode control
4151          * will take care of enabling the pin's input/output buffers as needed.
4152          * Therefore there's no need to enable the input buffer at this
4153          * stage.
4154          */
4155         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4156         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4157
4158         /* Mute capture amp left and right */
4159         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4160         /* Set ADC connection select to match default mixer setting - mic
4161          * (on mic1 pin)
4162          */
4163         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4164
4165         /* Do similar with the second ADC: mute capture input amp and
4166          * set ADC connection to mic to match ALSA's default state.
4167          */
4168         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4169         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4170
4171         /* Mute all inputs to mixer widget (even unconnected ones) */
4172         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4173         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4174         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4175         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4176         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4177         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4178         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4179         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4180
4181         { }
4182 };
4183
4184 static struct hda_verb alc260_will_verbs[] = {
4185         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4186         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4187         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4188         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4189         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4190         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4191         {}
4192 };
4193
4194 static struct hda_verb alc260_replacer_672v_verbs[] = {
4195         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4196         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4197         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4198
4199         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4200         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4201         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4202
4203         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4204         {}
4205 };
4206
4207 /* toggle speaker-output according to the hp-jack state */
4208 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4209 {
4210         unsigned int present;
4211
4212         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4213         present = snd_hda_codec_read(codec, 0x0f, 0,
4214                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4215         if (present) {
4216                 snd_hda_codec_write_cache(codec, 0x01, 0,
4217                                           AC_VERB_SET_GPIO_DATA, 1);
4218                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4219                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4220                                           PIN_HP);
4221         } else {
4222                 snd_hda_codec_write_cache(codec, 0x01, 0,
4223                                           AC_VERB_SET_GPIO_DATA, 0);
4224                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4225                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4226                                           PIN_OUT);
4227         }
4228 }
4229
4230 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4231                                        unsigned int res)
4232 {
4233         if ((res >> 26) == ALC880_HP_EVENT)
4234                 alc260_replacer_672v_automute(codec);
4235 }
4236
4237 /* Test configuration for debugging, modelled after the ALC880 test
4238  * configuration.
4239  */
4240 #ifdef CONFIG_SND_DEBUG
4241 static hda_nid_t alc260_test_dac_nids[1] = {
4242         0x02,
4243 };
4244 static hda_nid_t alc260_test_adc_nids[2] = {
4245         0x04, 0x05,
4246 };
4247 /* For testing the ALC260, each input MUX needs its own definition since
4248  * the signal assignments are different.  This assumes that the first ADC 
4249  * is NID 0x04.
4250  */
4251 static struct hda_input_mux alc260_test_capture_sources[2] = {
4252         {
4253                 .num_items = 7,
4254                 .items = {
4255                         { "MIC1 pin", 0x0 },
4256                         { "MIC2 pin", 0x1 },
4257                         { "LINE1 pin", 0x2 },
4258                         { "LINE2 pin", 0x3 },
4259                         { "CD pin", 0x4 },
4260                         { "LINE-OUT pin", 0x5 },
4261                         { "HP-OUT pin", 0x6 },
4262                 },
4263         },
4264         {
4265                 .num_items = 8,
4266                 .items = {
4267                         { "MIC1 pin", 0x0 },
4268                         { "MIC2 pin", 0x1 },
4269                         { "LINE1 pin", 0x2 },
4270                         { "LINE2 pin", 0x3 },
4271                         { "CD pin", 0x4 },
4272                         { "Mixer", 0x5 },
4273                         { "LINE-OUT pin", 0x6 },
4274                         { "HP-OUT pin", 0x7 },
4275                 },
4276         },
4277 };
4278 static struct snd_kcontrol_new alc260_test_mixer[] = {
4279         /* Output driver widgets */
4280         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4281         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4282         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4283         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4284         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4285         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4286
4287         /* Modes for retasking pin widgets
4288          * Note: the ALC260 doesn't seem to act on requests to enable mic
4289          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4290          * mention this restriction.  At this stage it's not clear whether
4291          * this behaviour is intentional or is a hardware bug in chip
4292          * revisions available at least up until early 2006.  Therefore for
4293          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4294          * choices, but if it turns out that the lack of mic bias for these
4295          * NIDs is intentional we could change their modes from
4296          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4297          */
4298         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4299         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4300         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4301         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4302         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4303         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4304
4305         /* Loopback mixer controls */
4306         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4307         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4308         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4309         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4310         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4311         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4312         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4313         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4314         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4315         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4316         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4317         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4318         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4319         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4320         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4321         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4322
4323         /* Controls for GPIO pins, assuming they are configured as outputs */
4324         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4325         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4326         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4327         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4328
4329         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4330          * is ambigious as to which NID is which; testing on laptops which
4331          * make this output available should provide clarification. 
4332          */
4333         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4334         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4335
4336         { } /* end */
4337 };
4338 static struct hda_verb alc260_test_init_verbs[] = {
4339         /* Enable all GPIOs as outputs with an initial value of 0 */
4340         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4341         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4342         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4343
4344         /* Enable retasking pins as output, initially without power amp */
4345         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4346         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4347         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4348         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4349         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4350         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4351
4352         /* Disable digital (SPDIF) pins initially, but users can enable
4353          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4354          * payload also sets the generation to 0, output to be in "consumer"
4355          * PCM format, copyright asserted, no pre-emphasis and no validity
4356          * control.
4357          */
4358         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4359         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4360
4361         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4362          * OUT1 sum bus when acting as an output.
4363          */
4364         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4365         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4366         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4367         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4368
4369         /* Start with output sum widgets muted and their output gains at min */
4370         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4371         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4372         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4373         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4374         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4375         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4376         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4377         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4378         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4379
4380         /* Unmute retasking pin widget output buffers since the default
4381          * state appears to be output.  As the pin mode is changed by the
4382          * user the pin mode control will take care of enabling the pin's
4383          * input/output buffers as needed.
4384          */
4385         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4386         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4387         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4388         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4389         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4390         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4391         /* Also unmute the mono-out pin widget */
4392         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4393
4394         /* Mute capture amp left and right */
4395         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4396         /* Set ADC connection select to match default mixer setting (mic1
4397          * pin)
4398          */
4399         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4400
4401         /* Do the same for the second ADC: mute capture input amp and
4402          * set ADC connection to mic1 pin
4403          */
4404         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4405         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4406
4407         /* Mute all inputs to mixer widget (even unconnected ones) */
4408         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4409         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4410         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4411         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4412         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4413         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4414         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4415         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4416
4417         { }
4418 };
4419 #endif
4420
4421 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4422         .substreams = 1,
4423         .channels_min = 2,
4424         .channels_max = 2,
4425 };
4426
4427 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4428         .substreams = 1,
4429         .channels_min = 2,
4430         .channels_max = 2,
4431 };
4432
4433 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4434 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4435
4436 /*
4437  * for BIOS auto-configuration
4438  */
4439
4440 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4441                                         const char *pfx)
4442 {
4443         hda_nid_t nid_vol;
4444         unsigned long vol_val, sw_val;
4445         char name[32];
4446         int err;
4447
4448         if (nid >= 0x0f && nid < 0x11) {
4449                 nid_vol = nid - 0x7;
4450                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4451                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4452         } else if (nid == 0x11) {
4453                 nid_vol = nid - 0x7;
4454                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4455                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4456         } else if (nid >= 0x12 && nid <= 0x15) {
4457                 nid_vol = 0x08;
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
4461                 return 0; /* N/A */
4462         
4463         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4464         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4465         if (err < 0)
4466                 return err;
4467         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4468         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4469         if (err < 0)
4470                 return err;
4471         return 1;
4472 }
4473
4474 /* add playback controls from the parsed DAC table */
4475 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4476                                              const struct auto_pin_cfg *cfg)
4477 {
4478         hda_nid_t nid;
4479         int err;
4480
4481         spec->multiout.num_dacs = 1;
4482         spec->multiout.dac_nids = spec->private_dac_nids;
4483         spec->multiout.dac_nids[0] = 0x02;
4484
4485         nid = cfg->line_out_pins[0];
4486         if (nid) {
4487                 err = alc260_add_playback_controls(spec, nid, "Front");
4488                 if (err < 0)
4489                         return err;
4490         }
4491
4492         nid = cfg->speaker_pins[0];
4493         if (nid) {
4494                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4495                 if (err < 0)
4496                         return err;
4497         }
4498
4499         nid = cfg->hp_pins[0];
4500         if (nid) {
4501                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4502                 if (err < 0)
4503                         return err;
4504         }
4505         return 0;
4506 }
4507
4508 /* create playback/capture controls for input pins */
4509 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4510                                                 const struct auto_pin_cfg *cfg)
4511 {
4512         struct hda_input_mux *imux = &spec->private_imux;
4513         int i, err, idx;
4514
4515         for (i = 0; i < AUTO_PIN_LAST; i++) {
4516                 if (cfg->input_pins[i] >= 0x12) {
4517                         idx = cfg->input_pins[i] - 0x12;
4518                         err = new_analog_input(spec, cfg->input_pins[i],
4519                                                auto_pin_cfg_labels[i], idx,
4520                                                0x07);
4521                         if (err < 0)
4522                                 return err;
4523                         imux->items[imux->num_items].label =
4524                                 auto_pin_cfg_labels[i];
4525                         imux->items[imux->num_items].index = idx;
4526                         imux->num_items++;
4527                 }
4528                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4529                         idx = cfg->input_pins[i] - 0x09;
4530                         err = new_analog_input(spec, cfg->input_pins[i],
4531                                                auto_pin_cfg_labels[i], idx,
4532                                                0x07);
4533                         if (err < 0)
4534                                 return err;
4535                         imux->items[imux->num_items].label =
4536                                 auto_pin_cfg_labels[i];
4537                         imux->items[imux->num_items].index = idx;
4538                         imux->num_items++;
4539                 }
4540         }
4541         return 0;
4542 }
4543
4544 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4545                                               hda_nid_t nid, int pin_type,
4546                                               int sel_idx)
4547 {
4548         /* set as output */
4549         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4550                             pin_type);
4551         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4552                             AMP_OUT_UNMUTE);
4553         /* need the manual connection? */
4554         if (nid >= 0x12) {
4555                 int idx = nid - 0x12;
4556                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4557                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4558         }
4559 }
4560
4561 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4562 {
4563         struct alc_spec *spec = codec->spec;
4564         hda_nid_t nid;
4565
4566         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4567         nid = spec->autocfg.line_out_pins[0];
4568         if (nid) {
4569                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4570                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4571         }
4572         
4573         nid = spec->autocfg.speaker_pins[0];
4574         if (nid)
4575                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4576
4577         nid = spec->autocfg.hp_pins[0];
4578         if (nid)
4579                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4580 }
4581
4582 #define ALC260_PIN_CD_NID               0x16
4583 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4584 {
4585         struct alc_spec *spec = codec->spec;
4586         int i;
4587
4588         for (i = 0; i < AUTO_PIN_LAST; i++) {
4589                 hda_nid_t nid = spec->autocfg.input_pins[i];
4590                 if (nid >= 0x12) {
4591                         snd_hda_codec_write(codec, nid, 0,
4592                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4593                                             i <= AUTO_PIN_FRONT_MIC ?
4594                                             PIN_VREF80 : PIN_IN);
4595                         if (nid != ALC260_PIN_CD_NID)
4596                                 snd_hda_codec_write(codec, nid, 0,
4597                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4598                                                     AMP_OUT_MUTE);
4599                 }
4600         }
4601 }
4602
4603 /*
4604  * generic initialization of ADC, input mixers and output mixers
4605  */
4606 static struct hda_verb alc260_volume_init_verbs[] = {
4607         /*
4608          * Unmute ADC0-1 and set the default input to mic-in
4609          */
4610         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4611         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4612         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4613         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4614         
4615         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4616          * mixer widget
4617          * Note: PASD motherboards uses the Line In 2 as the input for
4618          * front panel mic (mic 2)
4619          */
4620         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4621         /* mute analog inputs */
4622         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4623         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4624         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4625         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4626         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4627
4628         /*
4629          * Set up output mixers (0x08 - 0x0a)
4630          */
4631         /* set vol=0 to output mixers */
4632         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4633         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4634         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4635         /* set up input amps for analog loopback */
4636         /* Amp Indices: DAC = 0, mixer = 1 */
4637         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4638         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4639         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4640         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4641         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4642         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4643         
4644         { }
4645 };
4646
4647 static int alc260_parse_auto_config(struct hda_codec *codec)
4648 {
4649         struct alc_spec *spec = codec->spec;
4650         unsigned int wcap;
4651         int err;
4652         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4653
4654         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4655                                            alc260_ignore);
4656         if (err < 0)
4657                 return err;
4658         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4659         if (err < 0)
4660                 return err;
4661         if (!spec->kctl_alloc)
4662                 return 0; /* can't find valid BIOS pin config */
4663         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4664         if (err < 0)
4665                 return err;
4666
4667         spec->multiout.max_channels = 2;
4668
4669         if (spec->autocfg.dig_out_pin)
4670                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4671         if (spec->kctl_alloc)
4672                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4673
4674         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4675
4676         spec->num_mux_defs = 1;
4677         spec->input_mux = &spec->private_imux;
4678
4679         /* check whether NID 0x04 is valid */
4680         wcap = get_wcaps(codec, 0x04);
4681         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4682         if (wcap != AC_WID_AUD_IN) {
4683                 spec->adc_nids = alc260_adc_nids_alt;
4684                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4685                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4686         } else {
4687                 spec->adc_nids = alc260_adc_nids;
4688                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4689                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4690         }
4691         spec->num_mixers++;
4692
4693         return 1;
4694 }
4695
4696 /* additional initialization for auto-configuration model */
4697 static void alc260_auto_init(struct hda_codec *codec)
4698 {
4699         alc260_auto_init_multi_out(codec);
4700         alc260_auto_init_analog_input(codec);
4701 }
4702
4703 #ifdef CONFIG_SND_HDA_POWER_SAVE
4704 static struct hda_amp_list alc260_loopbacks[] = {
4705         { 0x07, HDA_INPUT, 0 },
4706         { 0x07, HDA_INPUT, 1 },
4707         { 0x07, HDA_INPUT, 2 },
4708         { 0x07, HDA_INPUT, 3 },
4709         { 0x07, HDA_INPUT, 4 },
4710         { } /* end */
4711 };
4712 #endif
4713
4714 /*
4715  * ALC260 configurations
4716  */
4717 static const char *alc260_models[ALC260_MODEL_LAST] = {
4718         [ALC260_BASIC]          = "basic",
4719         [ALC260_HP]             = "hp",
4720         [ALC260_HP_3013]        = "hp-3013",
4721         [ALC260_FUJITSU_S702X]  = "fujitsu",
4722         [ALC260_ACER]           = "acer",
4723         [ALC260_WILL]           = "will",
4724         [ALC260_REPLACER_672V]  = "replacer",
4725 #ifdef CONFIG_SND_DEBUG
4726         [ALC260_TEST]           = "test",
4727 #endif
4728         [ALC260_AUTO]           = "auto",
4729 };
4730
4731 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4732         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4733         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4734         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4735         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4736         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4737         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4738         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4739         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4740         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4741         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4742         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4743         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4744         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4745         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4746         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4747         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4748         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4749         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4750         {}
4751 };
4752
4753 static struct alc_config_preset alc260_presets[] = {
4754         [ALC260_BASIC] = {
4755                 .mixers = { alc260_base_output_mixer,
4756                             alc260_input_mixer,
4757                             alc260_pc_beep_mixer,
4758                             alc260_capture_mixer },
4759                 .init_verbs = { alc260_init_verbs },
4760                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4761                 .dac_nids = alc260_dac_nids,
4762                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4763                 .adc_nids = alc260_adc_nids,
4764                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4765                 .channel_mode = alc260_modes,
4766                 .input_mux = &alc260_capture_source,
4767         },
4768         [ALC260_HP] = {
4769                 .mixers = { alc260_base_output_mixer,
4770                             alc260_input_mixer,
4771                             alc260_capture_alt_mixer },
4772                 .init_verbs = { alc260_init_verbs },
4773                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4774                 .dac_nids = alc260_dac_nids,
4775                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4776                 .adc_nids = alc260_hp_adc_nids,
4777                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4778                 .channel_mode = alc260_modes,
4779                 .input_mux = &alc260_capture_source,
4780         },
4781         [ALC260_HP_3013] = {
4782                 .mixers = { alc260_hp_3013_mixer,
4783                             alc260_input_mixer,
4784                             alc260_capture_alt_mixer },
4785                 .init_verbs = { alc260_hp_3013_init_verbs },
4786                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4787                 .dac_nids = alc260_dac_nids,
4788                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4789                 .adc_nids = alc260_hp_adc_nids,
4790                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4791                 .channel_mode = alc260_modes,
4792                 .input_mux = &alc260_capture_source,
4793         },
4794         [ALC260_FUJITSU_S702X] = {
4795                 .mixers = { alc260_fujitsu_mixer,
4796                             alc260_capture_mixer },
4797                 .init_verbs = { alc260_fujitsu_init_verbs },
4798                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4799                 .dac_nids = alc260_dac_nids,
4800                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4801                 .adc_nids = alc260_dual_adc_nids,
4802                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4803                 .channel_mode = alc260_modes,
4804                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4805                 .input_mux = alc260_fujitsu_capture_sources,
4806         },
4807         [ALC260_ACER] = {
4808                 .mixers = { alc260_acer_mixer,
4809                             alc260_capture_mixer },
4810                 .init_verbs = { alc260_acer_init_verbs },
4811                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4812                 .dac_nids = alc260_dac_nids,
4813                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4814                 .adc_nids = alc260_dual_adc_nids,
4815                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4816                 .channel_mode = alc260_modes,
4817                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4818                 .input_mux = alc260_acer_capture_sources,
4819         },
4820         [ALC260_WILL] = {
4821                 .mixers = { alc260_will_mixer,
4822                             alc260_capture_mixer },
4823                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4824                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4825                 .dac_nids = alc260_dac_nids,
4826                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4827                 .adc_nids = alc260_adc_nids,
4828                 .dig_out_nid = ALC260_DIGOUT_NID,
4829                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4830                 .channel_mode = alc260_modes,
4831                 .input_mux = &alc260_capture_source,
4832         },
4833         [ALC260_REPLACER_672V] = {
4834                 .mixers = { alc260_replacer_672v_mixer,
4835                             alc260_capture_mixer },
4836                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4837                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4838                 .dac_nids = alc260_dac_nids,
4839                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4840                 .adc_nids = alc260_adc_nids,
4841                 .dig_out_nid = ALC260_DIGOUT_NID,
4842                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4843                 .channel_mode = alc260_modes,
4844                 .input_mux = &alc260_capture_source,
4845                 .unsol_event = alc260_replacer_672v_unsol_event,
4846                 .init_hook = alc260_replacer_672v_automute,
4847         },
4848 #ifdef CONFIG_SND_DEBUG
4849         [ALC260_TEST] = {
4850                 .mixers = { alc260_test_mixer,
4851                             alc260_capture_mixer },
4852                 .init_verbs = { alc260_test_init_verbs },
4853                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4854                 .dac_nids = alc260_test_dac_nids,
4855                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4856                 .adc_nids = alc260_test_adc_nids,
4857                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4858                 .channel_mode = alc260_modes,
4859                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4860                 .input_mux = alc260_test_capture_sources,
4861         },
4862 #endif
4863 };
4864
4865 static int patch_alc260(struct hda_codec *codec)
4866 {
4867         struct alc_spec *spec;
4868         int err, board_config;
4869
4870         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4871         if (spec == NULL)
4872                 return -ENOMEM;
4873
4874         codec->spec = spec;
4875
4876         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4877                                                   alc260_models,
4878                                                   alc260_cfg_tbl);
4879         if (board_config < 0) {
4880                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4881                            "trying auto-probe from BIOS...\n");
4882                 board_config = ALC260_AUTO;
4883         }
4884
4885         if (board_config == ALC260_AUTO) {
4886                 /* automatic parse from the BIOS config */
4887                 err = alc260_parse_auto_config(codec);
4888                 if (err < 0) {
4889                         alc_free(codec);
4890                         return err;
4891                 } else if (!err) {
4892                         printk(KERN_INFO
4893                                "hda_codec: Cannot set up configuration "
4894                                "from BIOS.  Using base mode...\n");
4895                         board_config = ALC260_BASIC;
4896                 }
4897         }
4898
4899         if (board_config != ALC260_AUTO)
4900                 setup_preset(spec, &alc260_presets[board_config]);
4901
4902         spec->stream_name_analog = "ALC260 Analog";
4903         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4904         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4905
4906         spec->stream_name_digital = "ALC260 Digital";
4907         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4908         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4909
4910         codec->patch_ops = alc_patch_ops;
4911         if (board_config == ALC260_AUTO)
4912                 spec->init_hook = alc260_auto_init;
4913 #ifdef CONFIG_SND_HDA_POWER_SAVE
4914         if (!spec->loopback.amplist)
4915                 spec->loopback.amplist = alc260_loopbacks;
4916 #endif
4917
4918         return 0;
4919 }
4920
4921
4922 /*
4923  * ALC882 support
4924  *
4925  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4926  * configuration.  Each pin widget can choose any input DACs and a mixer.
4927  * Each ADC is connected from a mixer of all inputs.  This makes possible
4928  * 6-channel independent captures.
4929  *
4930  * In addition, an independent DAC for the multi-playback (not used in this
4931  * driver yet).
4932  */
4933 #define ALC882_DIGOUT_NID       0x06
4934 #define ALC882_DIGIN_NID        0x0a
4935
4936 static struct hda_channel_mode alc882_ch_modes[1] = {
4937         { 8, NULL }
4938 };
4939
4940 static hda_nid_t alc882_dac_nids[4] = {
4941         /* front, rear, clfe, rear_surr */
4942         0x02, 0x03, 0x04, 0x05
4943 };
4944
4945 /* identical with ALC880 */
4946 #define alc882_adc_nids         alc880_adc_nids
4947 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4948
4949 /* input MUX */
4950 /* FIXME: should be a matrix-type input source selection */
4951
4952 static struct hda_input_mux alc882_capture_source = {
4953         .num_items = 4,
4954         .items = {
4955                 { "Mic", 0x0 },
4956                 { "Front Mic", 0x1 },
4957                 { "Line", 0x2 },
4958                 { "CD", 0x4 },
4959         },
4960 };
4961 #define alc882_mux_enum_info alc_mux_enum_info
4962 #define alc882_mux_enum_get alc_mux_enum_get
4963
4964 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4965                                struct snd_ctl_elem_value *ucontrol)
4966 {
4967         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4968         struct alc_spec *spec = codec->spec;
4969         const struct hda_input_mux *imux = spec->input_mux;
4970         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4971         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4972         hda_nid_t nid = capture_mixers[adc_idx];
4973         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4974         unsigned int i, idx;
4975
4976         idx = ucontrol->value.enumerated.item[0];
4977         if (idx >= imux->num_items)
4978                 idx = imux->num_items - 1;
4979         if (*cur_val == idx)
4980                 return 0;
4981         for (i = 0; i < imux->num_items; i++) {
4982                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4983                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4984                                          imux->items[i].index,
4985                                          HDA_AMP_MUTE, v);
4986         }
4987         *cur_val = idx;
4988         return 1;
4989 }
4990
4991 /*
4992  * 2ch mode
4993  */
4994 static struct hda_verb alc882_3ST_ch2_init[] = {
4995         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4996         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4997         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4998         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4999         { } /* end */
5000 };
5001
5002 /*
5003  * 6ch mode
5004  */
5005 static struct hda_verb alc882_3ST_ch6_init[] = {
5006         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5007         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5008         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5009         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5010         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5011         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5012         { } /* end */
5013 };
5014
5015 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5016         { 2, alc882_3ST_ch2_init },
5017         { 6, alc882_3ST_ch6_init },
5018 };
5019
5020 /*
5021  * 6ch mode
5022  */
5023 static struct hda_verb alc882_sixstack_ch6_init[] = {
5024         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5025         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5026         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5027         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5028         { } /* end */
5029 };
5030
5031 /*
5032  * 8ch mode
5033  */
5034 static struct hda_verb alc882_sixstack_ch8_init[] = {
5035         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5036         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5037         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5038         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5039         { } /* end */
5040 };
5041
5042 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5043         { 6, alc882_sixstack_ch6_init },
5044         { 8, alc882_sixstack_ch8_init },
5045 };
5046
5047 /*
5048  * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5049  */
5050
5051 /*
5052  * 2ch mode
5053  */
5054 static struct hda_verb alc885_mbp_ch2_init[] = {
5055         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5056         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5057         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5058         { } /* end */
5059 };
5060
5061 /*
5062  * 6ch mode
5063  */
5064 static struct hda_verb alc885_mbp_ch6_init[] = {
5065         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5066         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5067         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5068         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5069         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5070         { } /* end */
5071 };
5072
5073 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5074         { 2, alc885_mbp_ch2_init },
5075         { 6, alc885_mbp_ch6_init },
5076 };
5077
5078
5079 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5080  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5081  */
5082 static struct snd_kcontrol_new alc882_base_mixer[] = {
5083         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5084         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5085         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5086         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5087         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5088         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5089         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5090         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5091         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5092         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5093         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5094         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5095         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5096         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5097         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5098         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5099         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5100         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5101         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5102         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5103         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5104         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5105         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5106         { } /* end */
5107 };
5108
5109 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5110         HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5111         HDA_BIND_MUTE   ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5112         HDA_CODEC_MUTE  ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5113         HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5114         HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5115         HDA_CODEC_MUTE  ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5116         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5117         HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5118         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5119         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5120         { } /* end */
5121 };
5122 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5123         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5124         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5125         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5126         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5127         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5128         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5129         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5130         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5131         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5132         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5133         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5134         { } /* end */
5135 };
5136
5137 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5138         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5139         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5140         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5141         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5142         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5143         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5144         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5145         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5146         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5147         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5148         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5149         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5150         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5151         { } /* end */
5152 };
5153
5154 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5155  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5156  */
5157 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5158         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5159         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5160         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5161         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5162         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5163         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5164         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5165         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5166         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5167         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5168         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5169         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5170         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5171         { } /* end */
5172 };
5173
5174 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5175         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5176         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5177         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5178         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5179         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5180         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5181         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5182         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5183         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5184         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5185         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5186         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5187         { } /* end */
5188 };
5189
5190 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5191         {
5192                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5193                 .name = "Channel Mode",
5194                 .info = alc_ch_mode_info,
5195                 .get = alc_ch_mode_get,
5196                 .put = alc_ch_mode_put,
5197         },
5198         { } /* end */
5199 };
5200
5201 static struct hda_verb alc882_init_verbs[] = {
5202         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5203         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5204         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5205         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5206         /* Rear mixer */
5207         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5208         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5209         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5210         /* CLFE mixer */
5211         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5212         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5213         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5214         /* Side mixer */
5215         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5216         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5217         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5218
5219         /* Front Pin: output 0 (0x0c) */
5220         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5221         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5222         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5223         /* Rear Pin: output 1 (0x0d) */
5224         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5225         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5226         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5227         /* CLFE Pin: output 2 (0x0e) */
5228         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5229         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5230         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5231         /* Side Pin: output 3 (0x0f) */
5232         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5233         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5234         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5235         /* Mic (rear) pin: input vref at 80% */
5236         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5237         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5238         /* Front Mic pin: input vref at 80% */
5239         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5240         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5241         /* Line In pin: input */
5242         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5243         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5244         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5245         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5246         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5247         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5248         /* CD pin widget for input */
5249         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5250
5251         /* FIXME: use matrix-type input source selection */
5252         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5253         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5254         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5255         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5256         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5257         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5258         /* Input mixer2 */
5259         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5260         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5261         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5262         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5263         /* Input mixer3 */
5264         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5265         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5266         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5267         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5268         /* ADC1: mute amp left and right */
5269         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5270         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5271         /* ADC2: mute amp left and right */
5272         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5273         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5274         /* ADC3: mute amp left and right */
5275         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5276         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5277
5278         { }
5279 };
5280
5281 static struct hda_verb alc882_eapd_verbs[] = {
5282         /* change to EAPD mode */
5283         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5284         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5285         { }
5286 };
5287
5288 /* Mac Pro test */
5289 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5290         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5291         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5292         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5293         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5294         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5295         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5296         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5297         { } /* end */
5298 };
5299
5300 static struct hda_verb alc882_macpro_init_verbs[] = {
5301         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5302         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5303         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5304         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5305         /* Front Pin: output 0 (0x0c) */
5306         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5307         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5308         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5309         /* Front Mic pin: input vref at 80% */
5310         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5311         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5312         /* Speaker:  output */
5313         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5314         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5315         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5316         /* Headphone output (output 0 - 0x0c) */
5317         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5318         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5319         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5320
5321         /* FIXME: use matrix-type input source selection */
5322         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5323         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5324         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5325         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5326         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5327         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5328         /* Input mixer2 */
5329         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5330         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5331         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5332         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5333         /* Input mixer3 */
5334         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5335         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5336         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5337         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5338         /* ADC1: mute amp left and right */
5339         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5340         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5341         /* ADC2: mute amp left and right */
5342         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5343         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5344         /* ADC3: mute amp left and right */
5345         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5346         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5347
5348         { }
5349 };
5350
5351 /* Macbook Pro rev3 */
5352 static struct hda_verb alc885_mbp3_init_verbs[] = {
5353         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5354         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5355         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5356         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5357         /* Rear mixer */
5358         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5359         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5360         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5361         /* Front Pin: output 0 (0x0c) */
5362         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5363         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5364         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5365         /* HP Pin: output 0 (0x0d) */
5366         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5367         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5368         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5369         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5370         /* Mic (rear) pin: input vref at 80% */
5371         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5372         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5373         /* Front Mic pin: input vref at 80% */
5374         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5375         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5376         /* Line In pin: use output 1 when in LineOut mode */
5377         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5378         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5379         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5380
5381         /* FIXME: use matrix-type input source selection */
5382         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5383         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5384         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5385         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5386         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5387         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5388         /* Input mixer2 */
5389         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5390         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5391         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5392         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5393         /* Input mixer3 */
5394         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5395         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5396         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5397         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5398         /* ADC1: mute amp left and right */
5399         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5400         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5401         /* ADC2: mute amp left and right */
5402         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5403         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5404         /* ADC3: mute amp left and right */
5405         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5406         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5407
5408         { }
5409 };
5410
5411 /* iMac 24 mixer. */
5412 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5413         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5414         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5415         { } /* end */
5416 };
5417
5418 /* iMac 24 init verbs. */
5419 static struct hda_verb alc885_imac24_init_verbs[] = {
5420         /* Internal speakers: output 0 (0x0c) */
5421         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5422         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5423         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5424         /* Internal speakers: output 0 (0x0c) */
5425         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5426         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5427         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5428         /* Headphone: output 0 (0x0c) */
5429         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5430         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5431         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5432         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5433         /* Front Mic: input vref at 80% */
5434         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5435         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5436         { }
5437 };
5438
5439 /* Toggle speaker-output according to the hp-jack state */
5440 static void alc885_imac24_automute(struct hda_codec *codec)
5441 {
5442         unsigned int present;
5443
5444         present = snd_hda_codec_read(codec, 0x14, 0,
5445                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5446         snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5447                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5448         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5449                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5450 }
5451
5452 /* Processes unsolicited events. */
5453 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5454                                       unsigned int res)
5455 {
5456         /* Headphone insertion or removal. */
5457         if ((res >> 26) == ALC880_HP_EVENT)
5458                 alc885_imac24_automute(codec);
5459 }
5460
5461 static void alc885_mbp3_automute(struct hda_codec *codec)
5462 {
5463         unsigned int present;
5464
5465         present = snd_hda_codec_read(codec, 0x15, 0,
5466                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5467         snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5468                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5469         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5470                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5471
5472 }
5473 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5474                                     unsigned int res)
5475 {
5476         /* Headphone insertion or removal. */
5477         if ((res >> 26) == ALC880_HP_EVENT)
5478                 alc885_mbp3_automute(codec);
5479 }
5480
5481
5482 static struct hda_verb alc882_targa_verbs[] = {
5483         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5484         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5485
5486         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5487         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5488         
5489         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5490         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5491         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5492
5493         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5494         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5495         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5496         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5497         { } /* end */
5498 };
5499
5500 /* toggle speaker-output according to the hp-jack state */
5501 static void alc882_targa_automute(struct hda_codec *codec)
5502 {
5503         unsigned int present;
5504  
5505         present = snd_hda_codec_read(codec, 0x14, 0,
5506                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5507         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5508                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5509         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5510                                   present ? 1 : 3);
5511 }
5512
5513 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5514 {
5515         /* Looks like the unsol event is incompatible with the standard
5516          * definition.  4bit tag is placed at 26 bit!
5517          */
5518         if (((res >> 26) == ALC880_HP_EVENT)) {
5519                 alc882_targa_automute(codec);
5520         }
5521 }
5522
5523 static struct hda_verb alc882_asus_a7j_verbs[] = {
5524         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5525         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5526
5527         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5528         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5529         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5530         
5531         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5532         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5533         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5534
5535         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5536         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5537         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5538         { } /* end */
5539 };
5540
5541 static struct hda_verb alc882_asus_a7m_verbs[] = {
5542         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5543         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5544
5545         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5546         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5547         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5548         
5549         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5550         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5551         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5552
5553         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5554         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5555         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5556         { } /* end */
5557 };
5558
5559 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5560 {
5561         unsigned int gpiostate, gpiomask, gpiodir;
5562
5563         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5564                                        AC_VERB_GET_GPIO_DATA, 0);
5565
5566         if (!muted)
5567                 gpiostate |= (1 << pin);
5568         else
5569                 gpiostate &= ~(1 << pin);
5570
5571         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5572                                       AC_VERB_GET_GPIO_MASK, 0);
5573         gpiomask |= (1 << pin);
5574
5575         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5576                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5577         gpiodir |= (1 << pin);
5578
5579
5580         snd_hda_codec_write(codec, codec->afg, 0,
5581                             AC_VERB_SET_GPIO_MASK, gpiomask);
5582         snd_hda_codec_write(codec, codec->afg, 0,
5583                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5584
5585         msleep(1);
5586
5587         snd_hda_codec_write(codec, codec->afg, 0,
5588                             AC_VERB_SET_GPIO_DATA, gpiostate);
5589 }
5590
5591 /* set up GPIO at initialization */
5592 static void alc885_macpro_init_hook(struct hda_codec *codec)
5593 {
5594         alc882_gpio_mute(codec, 0, 0);
5595         alc882_gpio_mute(codec, 1, 0);
5596 }
5597
5598 /* set up GPIO and update auto-muting at initialization */
5599 static void alc885_imac24_init_hook(struct hda_codec *codec)
5600 {
5601         alc885_macpro_init_hook(codec);
5602         alc885_imac24_automute(codec);
5603 }
5604
5605 /*
5606  * generic initialization of ADC, input mixers and output mixers
5607  */
5608 static struct hda_verb alc882_auto_init_verbs[] = {
5609         /*
5610          * Unmute ADC0-2 and set the default input to mic-in
5611          */
5612         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5613         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5614         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5615         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5616         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5617         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5618
5619         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5620          * mixer widget
5621          * Note: PASD motherboards uses the Line In 2 as the input for
5622          * front panel mic (mic 2)
5623          */
5624         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5625         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5626         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5627         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5628         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5629         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5630
5631         /*
5632          * Set up output mixers (0x0c - 0x0f)
5633          */
5634         /* set vol=0 to output mixers */
5635         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5636         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5637         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5638         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5639         /* set up input amps for analog loopback */
5640         /* Amp Indices: DAC = 0, mixer = 1 */
5641         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5642         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5643         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5644         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5645         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5646         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5647         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5648         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5649         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5650         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5651
5652         /* FIXME: use matrix-type input source selection */
5653         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5654         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5655         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5656         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5657         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5658         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5659         /* Input mixer2 */
5660         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5661         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5662         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5663         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5664         /* Input mixer3 */
5665         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5666         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5667         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5668         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5669
5670         { }
5671 };
5672
5673 /* capture mixer elements */
5674 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5675         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5676         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5677         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5678         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5679         {
5680                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5681                 /* The multiple "Capture Source" controls confuse alsamixer
5682                  * So call somewhat different..
5683                  * FIXME: the controls appear in the "playback" view!
5684                  */
5685                 /* .name = "Capture Source", */
5686                 .name = "Input Source",
5687                 .count = 2,
5688                 .info = alc882_mux_enum_info,
5689                 .get = alc882_mux_enum_get,
5690                 .put = alc882_mux_enum_put,
5691         },
5692         { } /* end */
5693 };
5694
5695 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5696         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5697         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5698         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5699         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5700         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5701         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5702         {
5703                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5704                 /* The multiple "Capture Source" controls confuse alsamixer
5705                  * So call somewhat different..
5706                  * FIXME: the controls appear in the "playback" view!
5707                  */
5708                 /* .name = "Capture Source", */
5709                 .name = "Input Source",
5710                 .count = 3,
5711                 .info = alc882_mux_enum_info,
5712                 .get = alc882_mux_enum_get,
5713                 .put = alc882_mux_enum_put,
5714         },
5715         { } /* end */
5716 };
5717
5718 #ifdef CONFIG_SND_HDA_POWER_SAVE
5719 #define alc882_loopbacks        alc880_loopbacks
5720 #endif
5721
5722 /* pcm configuration: identiacal with ALC880 */
5723 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5724 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5725 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5726 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5727
5728 /*
5729  * configuration and preset
5730  */
5731 static const char *alc882_models[ALC882_MODEL_LAST] = {
5732         [ALC882_3ST_DIG]        = "3stack-dig",
5733         [ALC882_6ST_DIG]        = "6stack-dig",
5734         [ALC882_ARIMA]          = "arima",
5735         [ALC882_W2JC]           = "w2jc",
5736         [ALC882_TARGA]          = "targa",
5737         [ALC882_ASUS_A7J]       = "asus-a7j",
5738         [ALC882_ASUS_A7M]       = "asus-a7m",
5739         [ALC885_MACPRO]         = "macpro",
5740         [ALC885_MBP3]           = "mbp3",
5741         [ALC885_IMAC24]         = "imac24",
5742         [ALC882_AUTO]           = "auto",
5743 };
5744
5745 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5746         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5747         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5748         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5749         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5750         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5751         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5752         SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
5753         SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
5754         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5755         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5756         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5757         {}
5758 };
5759
5760 static struct alc_config_preset alc882_presets[] = {
5761         [ALC882_3ST_DIG] = {
5762                 .mixers = { alc882_base_mixer },
5763                 .init_verbs = { alc882_init_verbs },
5764                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5765                 .dac_nids = alc882_dac_nids,
5766                 .dig_out_nid = ALC882_DIGOUT_NID,
5767                 .dig_in_nid = ALC882_DIGIN_NID,
5768                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5769                 .channel_mode = alc882_ch_modes,
5770                 .need_dac_fix = 1,
5771                 .input_mux = &alc882_capture_source,
5772         },
5773         [ALC882_6ST_DIG] = {
5774                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5775                 .init_verbs = { alc882_init_verbs },
5776                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5777                 .dac_nids = alc882_dac_nids,
5778                 .dig_out_nid = ALC882_DIGOUT_NID,
5779                 .dig_in_nid = ALC882_DIGIN_NID,
5780                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5781                 .channel_mode = alc882_sixstack_modes,
5782                 .input_mux = &alc882_capture_source,
5783         },
5784         [ALC882_ARIMA] = {
5785                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5786                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5787                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5788                 .dac_nids = alc882_dac_nids,
5789                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5790                 .channel_mode = alc882_sixstack_modes,
5791                 .input_mux = &alc882_capture_source,
5792         },
5793         [ALC882_W2JC] = {
5794                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5795                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5796                                 alc880_gpio1_init_verbs },
5797                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5798                 .dac_nids = alc882_dac_nids,
5799                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5800                 .channel_mode = alc880_threestack_modes,
5801                 .need_dac_fix = 1,
5802                 .input_mux = &alc882_capture_source,
5803                 .dig_out_nid = ALC882_DIGOUT_NID,
5804         },
5805         [ALC885_MBP3] = {
5806                 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5807                 .init_verbs = { alc885_mbp3_init_verbs,
5808                                 alc880_gpio1_init_verbs },
5809                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5810                 .dac_nids = alc882_dac_nids,
5811                 .channel_mode = alc885_mbp_6ch_modes,
5812                 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5813                 .input_mux = &alc882_capture_source,
5814                 .dig_out_nid = ALC882_DIGOUT_NID,
5815                 .dig_in_nid = ALC882_DIGIN_NID,
5816                 .unsol_event = alc885_mbp3_unsol_event,
5817                 .init_hook = alc885_mbp3_automute,
5818         },
5819         [ALC885_MACPRO] = {
5820                 .mixers = { alc882_macpro_mixer },
5821                 .init_verbs = { alc882_macpro_init_verbs },
5822                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5823                 .dac_nids = alc882_dac_nids,
5824                 .dig_out_nid = ALC882_DIGOUT_NID,
5825                 .dig_in_nid = ALC882_DIGIN_NID,
5826                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5827                 .channel_mode = alc882_ch_modes,
5828                 .input_mux = &alc882_capture_source,
5829                 .init_hook = alc885_macpro_init_hook,
5830         },
5831         [ALC885_IMAC24] = {
5832                 .mixers = { alc885_imac24_mixer },
5833                 .init_verbs = { alc885_imac24_init_verbs },
5834                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5835                 .dac_nids = alc882_dac_nids,
5836                 .dig_out_nid = ALC882_DIGOUT_NID,
5837                 .dig_in_nid = ALC882_DIGIN_NID,
5838                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5839                 .channel_mode = alc882_ch_modes,
5840                 .input_mux = &alc882_capture_source,
5841                 .unsol_event = alc885_imac24_unsol_event,
5842                 .init_hook = alc885_imac24_init_hook,
5843         },
5844         [ALC882_TARGA] = {
5845                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5846                             alc882_capture_mixer },
5847                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5848                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5849                 .dac_nids = alc882_dac_nids,
5850                 .dig_out_nid = ALC882_DIGOUT_NID,
5851                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5852                 .adc_nids = alc882_adc_nids,
5853                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5854                 .channel_mode = alc882_3ST_6ch_modes,
5855                 .need_dac_fix = 1,
5856                 .input_mux = &alc882_capture_source,
5857                 .unsol_event = alc882_targa_unsol_event,
5858                 .init_hook = alc882_targa_automute,
5859         },
5860         [ALC882_ASUS_A7J] = {
5861                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5862                             alc882_capture_mixer },
5863                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5864                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5865                 .dac_nids = alc882_dac_nids,
5866                 .dig_out_nid = ALC882_DIGOUT_NID,
5867                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5868                 .adc_nids = alc882_adc_nids,
5869                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5870                 .channel_mode = alc882_3ST_6ch_modes,
5871                 .need_dac_fix = 1,
5872                 .input_mux = &alc882_capture_source,
5873         },      
5874         [ALC882_ASUS_A7M] = {
5875                 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5876                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5877                                 alc880_gpio1_init_verbs,
5878                                 alc882_asus_a7m_verbs },
5879                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5880                 .dac_nids = alc882_dac_nids,
5881                 .dig_out_nid = ALC882_DIGOUT_NID,
5882                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5883                 .channel_mode = alc880_threestack_modes,
5884                 .need_dac_fix = 1,
5885                 .input_mux = &alc882_capture_source,
5886         },      
5887 };
5888
5889
5890 /*
5891  * Pin config fixes
5892  */
5893 enum { 
5894         PINFIX_ABIT_AW9D_MAX
5895 };
5896
5897 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5898         { 0x15, 0x01080104 }, /* side */
5899         { 0x16, 0x01011012 }, /* rear */
5900         { 0x17, 0x01016011 }, /* clfe */
5901         { }
5902 };
5903
5904 static const struct alc_pincfg *alc882_pin_fixes[] = {
5905         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5906 };
5907
5908 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5909         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5910         {}
5911 };
5912
5913 /*
5914  * BIOS auto configuration
5915  */
5916 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5917                                               hda_nid_t nid, int pin_type,
5918                                               int dac_idx)
5919 {
5920         /* set as output */
5921         struct alc_spec *spec = codec->spec;
5922         int idx;
5923
5924         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5925                 idx = 4;
5926         else
5927                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5928
5929         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5930                             pin_type);
5931         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5932                             AMP_OUT_UNMUTE);
5933         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5934
5935 }
5936
5937 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5938 {
5939         struct alc_spec *spec = codec->spec;
5940         int i;
5941
5942         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5943         for (i = 0; i <= HDA_SIDE; i++) {
5944                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5945                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5946                 if (nid)
5947                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5948                                                           i);
5949         }
5950 }
5951
5952 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5953 {
5954         struct alc_spec *spec = codec->spec;
5955         hda_nid_t pin;
5956
5957         pin = spec->autocfg.hp_pins[0];
5958         if (pin) /* connect to front */
5959                 /* use dac 0 */
5960                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5961 }
5962
5963 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5964 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5965
5966 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5967 {
5968         struct alc_spec *spec = codec->spec;
5969         int i;
5970
5971         for (i = 0; i < AUTO_PIN_LAST; i++) {
5972                 hda_nid_t nid = spec->autocfg.input_pins[i];
5973                 if (alc882_is_input_pin(nid)) {
5974                         snd_hda_codec_write(codec, nid, 0,
5975                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5976                                             i <= AUTO_PIN_FRONT_MIC ?
5977                                             PIN_VREF80 : PIN_IN);
5978                         if (nid != ALC882_PIN_CD_NID)
5979                                 snd_hda_codec_write(codec, nid, 0,
5980                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5981                                                     AMP_OUT_MUTE);
5982                 }
5983         }
5984 }
5985
5986 /* add mic boosts if needed */
5987 static int alc_auto_add_mic_boost(struct hda_codec *codec)
5988 {
5989         struct alc_spec *spec = codec->spec;
5990         int err;
5991         hda_nid_t nid;
5992
5993         nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
5994         if (nid) {
5995                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
5996                                   "Mic Boost",
5997                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
5998                 if (err < 0)
5999                         return err;
6000         }
6001         nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6002         if (nid) {
6003                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6004                                   "Front Mic Boost",
6005                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6006                 if (err < 0)
6007                         return err;
6008         }
6009         return 0;
6010 }
6011
6012 /* almost identical with ALC880 parser... */
6013 static int alc882_parse_auto_config(struct hda_codec *codec)
6014 {
6015         struct alc_spec *spec = codec->spec;
6016         int err = alc880_parse_auto_config(codec);
6017
6018         if (err < 0)
6019                 return err;
6020         else if (!err)
6021                 return 0; /* no config found */
6022
6023         err = alc_auto_add_mic_boost(codec);
6024         if (err < 0)
6025                 return err;
6026
6027         /* hack - override the init verbs */
6028         spec->init_verbs[0] = alc882_auto_init_verbs;
6029
6030         return 1; /* config found */
6031 }
6032
6033 /* additional initialization for auto-configuration model */
6034 static void alc882_auto_init(struct hda_codec *codec)
6035 {
6036         alc882_auto_init_multi_out(codec);
6037         alc882_auto_init_hp_out(codec);
6038         alc882_auto_init_analog_input(codec);
6039 }
6040
6041 static int patch_alc882(struct hda_codec *codec)
6042 {
6043         struct alc_spec *spec;
6044         int err, board_config;
6045
6046         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6047         if (spec == NULL)
6048                 return -ENOMEM;
6049
6050         codec->spec = spec;
6051
6052         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6053                                                   alc882_models,
6054                                                   alc882_cfg_tbl);
6055
6056         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6057                 /* Pick up systems that don't supply PCI SSID */
6058                 switch (codec->subsystem_id) {
6059                 case 0x106b0c00: /* Mac Pro */
6060                         board_config = ALC885_MACPRO;
6061                         break;
6062                 case 0x106b1000: /* iMac 24 */
6063                         board_config = ALC885_IMAC24;
6064                         break;
6065                 case 0x106b2c00: /* Macbook Pro rev3 */
6066                         board_config = ALC885_MBP3;
6067                         break;
6068                 default:
6069                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6070                                          "trying auto-probe from BIOS...\n");
6071                         board_config = ALC882_AUTO;
6072                 }
6073         }
6074
6075         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6076
6077         if (board_config == ALC882_AUTO) {
6078                 /* automatic parse from the BIOS config */
6079                 err = alc882_parse_auto_config(codec);
6080                 if (err < 0) {
6081                         alc_free(codec);
6082                         return err;
6083                 } else if (!err) {
6084                         printk(KERN_INFO
6085                                "hda_codec: Cannot set up configuration "
6086                                "from BIOS.  Using base mode...\n");
6087                         board_config = ALC882_3ST_DIG;
6088                 }
6089         }
6090
6091         if (board_config != ALC882_AUTO)
6092                 setup_preset(spec, &alc882_presets[board_config]);
6093
6094         spec->stream_name_analog = "ALC882 Analog";
6095         spec->stream_analog_playback = &alc882_pcm_analog_playback;
6096         spec->stream_analog_capture = &alc882_pcm_analog_capture;
6097
6098         spec->stream_name_digital = "ALC882 Digital";
6099         spec->stream_digital_playback = &alc882_pcm_digital_playback;
6100         spec->stream_digital_capture = &alc882_pcm_digital_capture;
6101
6102         if (!spec->adc_nids && spec->input_mux) {
6103                 /* check whether NID 0x07 is valid */
6104                 unsigned int wcap = get_wcaps(codec, 0x07);
6105                 /* get type */
6106                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6107                 if (wcap != AC_WID_AUD_IN) {
6108                         spec->adc_nids = alc882_adc_nids_alt;
6109                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6110                         spec->mixers[spec->num_mixers] =
6111                                 alc882_capture_alt_mixer;
6112                         spec->num_mixers++;
6113                 } else {
6114                         spec->adc_nids = alc882_adc_nids;
6115                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6116                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6117                         spec->num_mixers++;
6118                 }
6119         }
6120
6121         codec->patch_ops = alc_patch_ops;
6122         if (board_config == ALC882_AUTO)
6123                 spec->init_hook = alc882_auto_init;
6124 #ifdef CONFIG_SND_HDA_POWER_SAVE
6125         if (!spec->loopback.amplist)
6126                 spec->loopback.amplist = alc882_loopbacks;
6127 #endif
6128
6129         return 0;
6130 }
6131
6132 /*
6133  * ALC883 support
6134  *
6135  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6136  * configuration.  Each pin widget can choose any input DACs and a mixer.
6137  * Each ADC is connected from a mixer of all inputs.  This makes possible
6138  * 6-channel independent captures.
6139  *
6140  * In addition, an independent DAC for the multi-playback (not used in this
6141  * driver yet).
6142  */
6143 #define ALC883_DIGOUT_NID       0x06
6144 #define ALC883_DIGIN_NID        0x0a
6145
6146 static hda_nid_t alc883_dac_nids[4] = {
6147         /* front, rear, clfe, rear_surr */
6148         0x02, 0x04, 0x03, 0x05
6149 };
6150
6151 static hda_nid_t alc883_adc_nids[2] = {
6152         /* ADC1-2 */
6153         0x08, 0x09,
6154 };
6155
6156 /* input MUX */
6157 /* FIXME: should be a matrix-type input source selection */
6158
6159 static struct hda_input_mux alc883_capture_source = {
6160         .num_items = 4,
6161         .items = {
6162                 { "Mic", 0x0 },
6163                 { "Front Mic", 0x1 },
6164                 { "Line", 0x2 },
6165                 { "CD", 0x4 },
6166         },
6167 };
6168
6169 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6170         .num_items = 2,
6171         .items = {
6172                 { "Mic", 0x1 },
6173                 { "Line", 0x2 },
6174         },
6175 };
6176
6177 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6178         .num_items = 4,
6179         .items = {
6180                 { "Mic", 0x0 },
6181                 { "iMic", 0x1 },
6182                 { "Line", 0x2 },
6183                 { "CD", 0x4 },
6184         },
6185 };
6186
6187 #define alc883_mux_enum_info alc_mux_enum_info
6188 #define alc883_mux_enum_get alc_mux_enum_get
6189
6190 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6191                                struct snd_ctl_elem_value *ucontrol)
6192 {
6193         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6194         struct alc_spec *spec = codec->spec;
6195         const struct hda_input_mux *imux = spec->input_mux;
6196         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6197         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6198         hda_nid_t nid = capture_mixers[adc_idx];
6199         unsigned int *cur_val = &spec->cur_mux[adc_idx];
6200         unsigned int i, idx;
6201
6202         idx = ucontrol->value.enumerated.item[0];
6203         if (idx >= imux->num_items)
6204                 idx = imux->num_items - 1;
6205         if (*cur_val == idx)
6206                 return 0;
6207         for (i = 0; i < imux->num_items; i++) {
6208                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6209                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6210                                          imux->items[i].index,
6211                                          HDA_AMP_MUTE, v);
6212         }
6213         *cur_val = idx;
6214         return 1;
6215 }
6216
6217 /*
6218  * 2ch mode
6219  */
6220 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6221         { 2, NULL }
6222 };
6223
6224 /*
6225  * 2ch mode
6226  */
6227 static struct hda_verb alc883_3ST_ch2_init[] = {
6228         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6229         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6230         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6231         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6232         { } /* end */
6233 };
6234
6235 /*
6236  * 4ch mode
6237  */
6238 static struct hda_verb alc883_3ST_ch4_init[] = {
6239         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6240         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6241         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6242         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6243         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6244         { } /* end */
6245 };
6246
6247 /*
6248  * 6ch mode
6249  */
6250 static struct hda_verb alc883_3ST_ch6_init[] = {
6251         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6252         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6253         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6254         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6255         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6256         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6257         { } /* end */
6258 };
6259
6260 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6261         { 2, alc883_3ST_ch2_init },
6262         { 4, alc883_3ST_ch4_init },
6263         { 6, alc883_3ST_ch6_init },
6264 };
6265
6266 /*
6267  * 6ch mode
6268  */
6269 static struct hda_verb alc883_sixstack_ch6_init[] = {
6270         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6271         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6272         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6273         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6274         { } /* end */
6275 };
6276
6277 /*
6278  * 8ch mode
6279  */
6280 static struct hda_verb alc883_sixstack_ch8_init[] = {
6281         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6282         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6283         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6284         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6285         { } /* end */
6286 };
6287
6288 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6289         { 6, alc883_sixstack_ch6_init },
6290         { 8, alc883_sixstack_ch8_init },
6291 };
6292
6293 static struct hda_verb alc883_medion_eapd_verbs[] = {
6294         /* eanable EAPD on medion laptop */
6295         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6296         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6297         { }
6298 };
6299
6300 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6301  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6302  */
6303
6304 static struct snd_kcontrol_new alc883_base_mixer[] = {
6305         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6306         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6307         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6308         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6309         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6310         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6311         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6312         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6313         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6314         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6315         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6316         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6317         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6318         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6319         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6320         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6321         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6322         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6323         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6324         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6325         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6326         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6327         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6328         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6329         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6330         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6331         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6332         {
6333                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6334                 /* .name = "Capture Source", */
6335                 .name = "Input Source",
6336                 .count = 2,
6337                 .info = alc883_mux_enum_info,
6338                 .get = alc883_mux_enum_get,
6339                 .put = alc883_mux_enum_put,
6340         },
6341         { } /* end */
6342 };
6343
6344 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6345         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6346         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6347         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6348         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6349         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6350         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6351         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6352         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6353         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6354         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6355         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6356         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6357         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6358         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6359         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6360         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6361         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6362         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6363         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6364         {
6365                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6366                 /* .name = "Capture Source", */
6367                 .name = "Input Source",
6368                 .count = 2,
6369                 .info = alc883_mux_enum_info,
6370                 .get = alc883_mux_enum_get,
6371                 .put = alc883_mux_enum_put,
6372         },
6373         { } /* end */
6374 };
6375
6376 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6377         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6378         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6379         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6380         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6381         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6382         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6383         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6384         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6385         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6386         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6387         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6388         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6389         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6390         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6391         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6392         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6393         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6394         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6395         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6396         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6397         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6398         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6399         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6400         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6401         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6402         {
6403                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6404                 /* .name = "Capture Source", */
6405                 .name = "Input Source",
6406                 .count = 2,
6407                 .info = alc883_mux_enum_info,
6408                 .get = alc883_mux_enum_get,
6409                 .put = alc883_mux_enum_put,
6410         },
6411         { } /* end */
6412 };
6413
6414 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6415         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6416         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6417         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6418         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6419         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6420         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6421         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6422         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6423         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6424         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6425         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6426         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6427         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6428         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6429         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6430         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6431         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6432         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6433         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6434         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6435         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6436         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6437         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6438
6439         {
6440                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6441                 /* .name = "Capture Source", */
6442                 .name = "Input Source",
6443                 .count = 1,
6444                 .info = alc883_mux_enum_info,
6445                 .get = alc883_mux_enum_get,
6446                 .put = alc883_mux_enum_put,
6447         },
6448         { } /* end */
6449 };
6450
6451 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6452         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6453         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6454         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6455         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6456         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6457         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6458         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6459         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6460         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6461         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6462         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6463         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6464         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6465         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6466         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6467         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6468         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6469         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6470         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6471         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6472         {
6473                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6474                 /* .name = "Capture Source", */
6475                 .name = "Input Source",
6476                 .count = 2,
6477                 .info = alc883_mux_enum_info,
6478                 .get = alc883_mux_enum_get,
6479                 .put = alc883_mux_enum_put,
6480         },
6481         { } /* end */
6482 };
6483
6484 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6485         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6486         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6487         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6488         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6489         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6490         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6491         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6492         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6493         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6494         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6495         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6496         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6497         {
6498                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6499                 /* .name = "Capture Source", */
6500                 .name = "Input Source",
6501                 .count = 2,
6502                 .info = alc883_mux_enum_info,
6503                 .get = alc883_mux_enum_get,
6504                 .put = alc883_mux_enum_put,
6505         },
6506         { } /* end */
6507 };
6508
6509 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6510         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6511         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6512         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6513         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6514         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6515         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6516         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6517         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6518         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6519         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6520         {
6521                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6522                 /* .name = "Capture Source", */
6523                 .name = "Input Source",
6524                 .count = 1,
6525                 .info = alc883_mux_enum_info,
6526                 .get = alc883_mux_enum_get,
6527                 .put = alc883_mux_enum_put,
6528         },
6529         { } /* end */
6530 };
6531
6532 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6533         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6534         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6535         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6536         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6537         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6538         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6539         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6540         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6541         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6542         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6543         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6544         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6545         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6546         {
6547                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6548                 /* .name = "Capture Source", */
6549                 .name = "Input Source",
6550                 .count = 2,
6551                 .info = alc883_mux_enum_info,
6552                 .get = alc883_mux_enum_get,
6553                 .put = alc883_mux_enum_put,
6554         },
6555         { } /* end */
6556 };
6557
6558 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6559         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6560         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6561         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6562         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6563         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6564         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6565         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6566         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6567         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6568         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6569         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6570         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6571         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6572         {
6573                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6574                 /* .name = "Capture Source", */
6575                 .name = "Input Source",
6576                 .count = 2,
6577                 .info = alc883_mux_enum_info,
6578                 .get = alc883_mux_enum_get,
6579                 .put = alc883_mux_enum_put,
6580         },
6581         { } /* end */
6582 };      
6583
6584 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6585         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6586         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6587         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6588         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6589         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6590         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6591         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6592         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6593         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6594         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6595         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6596         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6597         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6598         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6599         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6600         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6601         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6602         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6603         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6604         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6605         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6606         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6607         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6608         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6609         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6610         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6611         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6612         {
6613                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6614                 /* .name = "Capture Source", */
6615                 .name = "Input Source",
6616                 .count = 2,
6617                 .info = alc883_mux_enum_info,
6618                 .get = alc883_mux_enum_get,
6619                 .put = alc883_mux_enum_put,
6620         },
6621         { } /* end */
6622 };
6623
6624 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6625         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6626         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6627         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6628         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6629         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6630         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6631         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6632         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6633         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6634         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6635         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6636         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6637         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6638         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6639         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6640         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6641         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6642         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6643         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6644         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6645         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6646         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6647         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6648         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6649         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6650         {
6651                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6652                 /* .name = "Capture Source", */
6653                 .name = "Input Source",
6654                 .count = 2,
6655                 .info = alc883_mux_enum_info,
6656                 .get = alc883_mux_enum_get,
6657                 .put = alc883_mux_enum_put,
6658         },
6659         { } /* end */
6660 };
6661
6662 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6663         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6664         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6665         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6666         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6667         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6668         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6669         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6670         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6671         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6672         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6673         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6674         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6675         {
6676                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6677                 /* .name = "Capture Source", */
6678                 .name = "Input Source",
6679                 .count = 2,
6680                 .info = alc883_mux_enum_info,
6681                 .get = alc883_mux_enum_get,
6682                 .put = alc883_mux_enum_put,
6683         },
6684         { } /* end */
6685 };
6686
6687 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6688         {
6689                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6690                 .name = "Channel Mode",
6691                 .info = alc_ch_mode_info,
6692                 .get = alc_ch_mode_get,
6693                 .put = alc_ch_mode_put,
6694         },
6695         { } /* end */
6696 };
6697
6698 static struct hda_verb alc883_init_verbs[] = {
6699         /* ADC1: mute amp left and right */
6700         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6701         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6702         /* ADC2: mute amp left and right */
6703         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6704         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6705         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6706         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6707         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6708         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6709         /* Rear mixer */
6710         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6711         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6712         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6713         /* CLFE mixer */
6714         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6715         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6716         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6717         /* Side mixer */
6718         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6719         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6720         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6721
6722         /* mute analog input loopbacks */
6723         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6724         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6725         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6726         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6727         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6728
6729         /* Front Pin: output 0 (0x0c) */
6730         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6731         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6732         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6733         /* Rear Pin: output 1 (0x0d) */
6734         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6735         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6736         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6737         /* CLFE Pin: output 2 (0x0e) */
6738         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6739         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6740         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6741         /* Side Pin: output 3 (0x0f) */
6742         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6743         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6744         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6745         /* Mic (rear) pin: input vref at 80% */
6746         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6747         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6748         /* Front Mic pin: input vref at 80% */
6749         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6750         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6751         /* Line In pin: input */
6752         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6753         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6754         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6755         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6756         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6757         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6758         /* CD pin widget for input */
6759         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6760
6761         /* FIXME: use matrix-type input source selection */
6762         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6763         /* Input mixer2 */
6764         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6765         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6766         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6767         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6768         /* Input mixer3 */
6769         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6770         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6771         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6772         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6773         { }
6774 };
6775
6776 static struct hda_verb alc883_tagra_verbs[] = {
6777         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6778         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6779
6780         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6781         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6782         
6783         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6784         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6785         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6786
6787         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6788         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6789         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6790         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6791
6792         { } /* end */
6793 };
6794
6795 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6796         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6797         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6798         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6799         { } /* end */
6800 };
6801
6802 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6803         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6804         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6805         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6806         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6807         { } /* end */
6808 };
6809
6810 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6811         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6812         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6813         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6814         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6815         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6816         { } /* end */
6817 };
6818
6819 static struct hda_verb alc883_haier_w66_verbs[] = {
6820         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6821         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6822
6823         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6824
6825         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6826         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6827         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6828         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6829         { } /* end */
6830 };
6831
6832 static struct hda_verb alc888_6st_hp_verbs[] = {
6833         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6834         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6835         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6836         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6837         { }
6838 };
6839
6840 static struct hda_verb alc888_3st_hp_verbs[] = {
6841         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6842         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6843         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6844         { }
6845 };
6846
6847 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6848         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6849         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6850         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6851         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6852         { }
6853 };
6854
6855 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6856         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6857         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6858         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6859         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6860         { }
6861 };
6862
6863 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6864         { 2, alc888_3st_hp_2ch_init },
6865         { 6, alc888_3st_hp_6ch_init },
6866 };
6867
6868 /* toggle front-jack and RCA according to the hp-jack state */
6869 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6870 {
6871         unsigned int present;
6872  
6873         present = snd_hda_codec_read(codec, 0x1b, 0,
6874                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6875         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6876                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6877         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6878                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6879 }
6880
6881 /* toggle RCA according to the front-jack state */
6882 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6883 {
6884         unsigned int present;
6885  
6886         present = snd_hda_codec_read(codec, 0x14, 0,
6887                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6888         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6889                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6890 }
6891
6892 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6893                                              unsigned int res)
6894 {
6895         if ((res >> 26) == ALC880_HP_EVENT)
6896                 alc888_lenovo_ms7195_front_automute(codec);
6897         if ((res >> 26) == ALC880_FRONT_EVENT)
6898                 alc888_lenovo_ms7195_rca_automute(codec);
6899 }
6900
6901 static struct hda_verb alc883_medion_md2_verbs[] = {
6902         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6903         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6904
6905         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6906
6907         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6908         { } /* end */
6909 };
6910
6911 /* toggle speaker-output according to the hp-jack state */
6912 static void alc883_medion_md2_automute(struct hda_codec *codec)
6913 {
6914         unsigned int present;
6915  
6916         present = snd_hda_codec_read(codec, 0x14, 0,
6917                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6918         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6919                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6920 }
6921
6922 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6923                                           unsigned int res)
6924 {
6925         if ((res >> 26) == ALC880_HP_EVENT)
6926                 alc883_medion_md2_automute(codec);
6927 }
6928
6929 /* toggle speaker-output according to the hp-jack state */
6930 static void alc883_tagra_automute(struct hda_codec *codec)
6931 {
6932         unsigned int present;
6933         unsigned char bits;
6934
6935         present = snd_hda_codec_read(codec, 0x14, 0,
6936                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6937         bits = present ? HDA_AMP_MUTE : 0;
6938         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6939                                  HDA_AMP_MUTE, bits);
6940         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6941                                   present ? 1 : 3);
6942 }
6943
6944 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6945 {
6946         if ((res >> 26) == ALC880_HP_EVENT)
6947                 alc883_tagra_automute(codec);
6948 }
6949
6950 static void alc883_haier_w66_automute(struct hda_codec *codec)
6951 {
6952         unsigned int present;
6953         unsigned char bits;
6954
6955         present = snd_hda_codec_read(codec, 0x1b, 0,
6956                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6957         bits = present ? 0x80 : 0;
6958         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6959                                  0x80, bits);
6960 }
6961
6962 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
6963                                          unsigned int res)
6964 {
6965         if ((res >> 26) == ALC880_HP_EVENT)
6966                 alc883_haier_w66_automute(codec);
6967 }
6968
6969 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6970 {
6971         unsigned int present;
6972         unsigned char bits;
6973
6974         present = snd_hda_codec_read(codec, 0x14, 0,
6975                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6976         bits = present ? HDA_AMP_MUTE : 0;
6977         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6978                                  HDA_AMP_MUTE, bits);
6979 }
6980
6981 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6982 {
6983         unsigned int present;
6984         unsigned char bits;
6985
6986         present = snd_hda_codec_read(codec, 0x1b, 0,
6987                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6988         bits = present ? HDA_AMP_MUTE : 0;
6989         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6990                                  HDA_AMP_MUTE, bits);
6991         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6992                                  HDA_AMP_MUTE, bits);
6993 }
6994
6995 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6996                                            unsigned int res)
6997 {
6998         if ((res >> 26) == ALC880_HP_EVENT)
6999                 alc883_lenovo_101e_all_automute(codec);
7000         if ((res >> 26) == ALC880_FRONT_EVENT)
7001                 alc883_lenovo_101e_ispeaker_automute(codec);
7002 }
7003
7004 /* toggle speaker-output according to the hp-jack state */
7005 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7006 {
7007         unsigned int present;
7008  
7009         present = snd_hda_codec_read(codec, 0x14, 0,
7010                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7011         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7012                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7013         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7014                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7015 }
7016
7017 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7018                                            unsigned int res)
7019 {
7020         if ((res >> 26) == ALC880_HP_EVENT)
7021                 alc883_acer_aspire_automute(codec);
7022 }
7023
7024 static struct hda_verb alc883_acer_eapd_verbs[] = {
7025         /* HP Pin: output 0 (0x0c) */
7026         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7027         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7028         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7029         /* Front Pin: output 0 (0x0c) */
7030         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7031         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7032         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7033         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7034         /* eanable EAPD on medion laptop */
7035         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7036         {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7037         /* enable unsolicited event */
7038         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7039         { }
7040 };
7041
7042 /*
7043  * generic initialization of ADC, input mixers and output mixers
7044  */
7045 static struct hda_verb alc883_auto_init_verbs[] = {
7046         /*
7047          * Unmute ADC0-2 and set the default input to mic-in
7048          */
7049         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7050         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7051         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7052         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7053
7054         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7055          * mixer widget
7056          * Note: PASD motherboards uses the Line In 2 as the input for
7057          * front panel mic (mic 2)
7058          */
7059         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7060         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7061         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7062         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7063         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7064         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7065
7066         /*
7067          * Set up output mixers (0x0c - 0x0f)
7068          */
7069         /* set vol=0 to output mixers */
7070         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7071         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7072         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7073         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7074         /* set up input amps for analog loopback */
7075         /* Amp Indices: DAC = 0, mixer = 1 */
7076         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7077         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7078         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7079         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7080         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7081         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7082         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7083         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7084         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7085         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7086
7087         /* FIXME: use matrix-type input source selection */
7088         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7089         /* Input mixer1 */
7090         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7091         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7092         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7093         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7094         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7095         /* Input mixer2 */
7096         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7097         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7098         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7099         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7100         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7101
7102         { }
7103 };
7104
7105 /* capture mixer elements */
7106 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7107         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7108         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7109         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7110         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7111         {
7112                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7113                 /* The multiple "Capture Source" controls confuse alsamixer
7114                  * So call somewhat different..
7115                  * FIXME: the controls appear in the "playback" view!
7116                  */
7117                 /* .name = "Capture Source", */
7118                 .name = "Input Source",
7119                 .count = 2,
7120                 .info = alc882_mux_enum_info,
7121                 .get = alc882_mux_enum_get,
7122                 .put = alc882_mux_enum_put,
7123         },
7124         { } /* end */
7125 };
7126
7127 #ifdef CONFIG_SND_HDA_POWER_SAVE
7128 #define alc883_loopbacks        alc880_loopbacks
7129 #endif
7130
7131 /* pcm configuration: identiacal with ALC880 */
7132 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
7133 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
7134 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
7135 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
7136
7137 /*
7138  * configuration and preset
7139  */
7140 static const char *alc883_models[ALC883_MODEL_LAST] = {
7141         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
7142         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
7143         [ALC883_3ST_6ch]        = "3stack-6ch",
7144         [ALC883_6ST_DIG]        = "6stack-dig",
7145         [ALC883_TARGA_DIG]      = "targa-dig",
7146         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
7147         [ALC883_ACER]           = "acer",
7148         [ALC883_ACER_ASPIRE]    = "acer-aspire",
7149         [ALC883_MEDION]         = "medion",
7150         [ALC883_MEDION_MD2]     = "medion-md2",
7151         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
7152         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7153         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
7154         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7155         [ALC883_HAIER_W66]      = "haier-w66",
7156         [ALC888_6ST_HP]         = "6stack-hp",
7157         [ALC888_3ST_HP]         = "3stack-hp",
7158         [ALC883_AUTO]           = "auto",
7159 };
7160
7161 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7162         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7163         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7164         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7165         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7166         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7167         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7168         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7169         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7170         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7171         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7172         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7173         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7174         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7175         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7176         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7177         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7178         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7179         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7180         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7181         SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7182         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7183         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7184         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7185         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7186         SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7187         SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7188         SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7189         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
7190         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7191         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7192         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7193         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7194         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7195         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7196         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7197         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7198         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7199         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7200         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7201         SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7202         SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7203         SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7204         SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7205         {}
7206 };
7207
7208 static struct alc_config_preset alc883_presets[] = {
7209         [ALC883_3ST_2ch_DIG] = {
7210                 .mixers = { alc883_3ST_2ch_mixer },
7211                 .init_verbs = { alc883_init_verbs },
7212                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7213                 .dac_nids = alc883_dac_nids,
7214                 .dig_out_nid = ALC883_DIGOUT_NID,
7215                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7216                 .adc_nids = alc883_adc_nids,
7217                 .dig_in_nid = ALC883_DIGIN_NID,
7218                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7219                 .channel_mode = alc883_3ST_2ch_modes,
7220                 .input_mux = &alc883_capture_source,
7221         },
7222         [ALC883_3ST_6ch_DIG] = {
7223                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7224                 .init_verbs = { alc883_init_verbs },
7225                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7226                 .dac_nids = alc883_dac_nids,
7227                 .dig_out_nid = ALC883_DIGOUT_NID,
7228                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7229                 .adc_nids = alc883_adc_nids,
7230                 .dig_in_nid = ALC883_DIGIN_NID,
7231                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7232                 .channel_mode = alc883_3ST_6ch_modes,
7233                 .need_dac_fix = 1,
7234                 .input_mux = &alc883_capture_source,
7235         },
7236         [ALC883_3ST_6ch] = {
7237                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7238                 .init_verbs = { alc883_init_verbs },
7239                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7240                 .dac_nids = alc883_dac_nids,
7241                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7242                 .adc_nids = alc883_adc_nids,
7243                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7244                 .channel_mode = alc883_3ST_6ch_modes,
7245                 .need_dac_fix = 1,
7246                 .input_mux = &alc883_capture_source,
7247         },
7248         [ALC883_6ST_DIG] = {
7249                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7250                 .init_verbs = { alc883_init_verbs },
7251                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7252                 .dac_nids = alc883_dac_nids,
7253                 .dig_out_nid = ALC883_DIGOUT_NID,
7254                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7255                 .adc_nids = alc883_adc_nids,
7256                 .dig_in_nid = ALC883_DIGIN_NID,
7257                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7258                 .channel_mode = alc883_sixstack_modes,
7259                 .input_mux = &alc883_capture_source,
7260         },
7261         [ALC883_TARGA_DIG] = {
7262                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7263                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7264                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7265                 .dac_nids = alc883_dac_nids,
7266                 .dig_out_nid = ALC883_DIGOUT_NID,
7267                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7268                 .adc_nids = alc883_adc_nids,
7269                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7270                 .channel_mode = alc883_3ST_6ch_modes,
7271                 .need_dac_fix = 1,
7272                 .input_mux = &alc883_capture_source,
7273                 .unsol_event = alc883_tagra_unsol_event,
7274                 .init_hook = alc883_tagra_automute,
7275         },
7276         [ALC883_TARGA_2ch_DIG] = {
7277                 .mixers = { alc883_tagra_2ch_mixer},
7278                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7279                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7280                 .dac_nids = alc883_dac_nids,
7281                 .dig_out_nid = ALC883_DIGOUT_NID,
7282                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7283                 .adc_nids = alc883_adc_nids,
7284                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7285                 .channel_mode = alc883_3ST_2ch_modes,
7286                 .input_mux = &alc883_capture_source,
7287                 .unsol_event = alc883_tagra_unsol_event,
7288                 .init_hook = alc883_tagra_automute,
7289         },
7290         [ALC883_ACER] = {
7291                 .mixers = { alc883_base_mixer },
7292                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7293                  * and the headphone jack.  Turn this on and rely on the
7294                  * standard mute methods whenever the user wants to turn
7295                  * these outputs off.
7296                  */
7297                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7298                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7299                 .dac_nids = alc883_dac_nids,
7300                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7301                 .adc_nids = alc883_adc_nids,
7302                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7303                 .channel_mode = alc883_3ST_2ch_modes,
7304                 .input_mux = &alc883_capture_source,
7305         },
7306         [ALC883_ACER_ASPIRE] = {
7307                 .mixers = { alc883_acer_aspire_mixer },
7308                 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7309                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7310                 .dac_nids = alc883_dac_nids,
7311                 .dig_out_nid = ALC883_DIGOUT_NID,
7312                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7313                 .adc_nids = alc883_adc_nids,
7314                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7315                 .channel_mode = alc883_3ST_2ch_modes,
7316                 .input_mux = &alc883_capture_source,
7317                 .unsol_event = alc883_acer_aspire_unsol_event,
7318                 .init_hook = alc883_acer_aspire_automute,
7319         },
7320         [ALC883_MEDION] = {
7321                 .mixers = { alc883_fivestack_mixer,
7322                             alc883_chmode_mixer },
7323                 .init_verbs = { alc883_init_verbs,
7324                                 alc883_medion_eapd_verbs },
7325                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7326                 .dac_nids = alc883_dac_nids,
7327                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7328                 .adc_nids = alc883_adc_nids,
7329                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7330                 .channel_mode = alc883_sixstack_modes,
7331                 .input_mux = &alc883_capture_source,
7332         },
7333         [ALC883_MEDION_MD2] = {
7334                 .mixers = { alc883_medion_md2_mixer},
7335                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7336                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7337                 .dac_nids = alc883_dac_nids,
7338                 .dig_out_nid = ALC883_DIGOUT_NID,
7339                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7340                 .adc_nids = alc883_adc_nids,
7341                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7342                 .channel_mode = alc883_3ST_2ch_modes,
7343                 .input_mux = &alc883_capture_source,
7344                 .unsol_event = alc883_medion_md2_unsol_event,
7345                 .init_hook = alc883_medion_md2_automute,
7346         },      
7347         [ALC883_LAPTOP_EAPD] = {
7348                 .mixers = { alc883_base_mixer },
7349                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7350                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7351                 .dac_nids = alc883_dac_nids,
7352                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7353                 .adc_nids = alc883_adc_nids,
7354                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7355                 .channel_mode = alc883_3ST_2ch_modes,
7356                 .input_mux = &alc883_capture_source,
7357         },
7358         [ALC883_LENOVO_101E_2ch] = {
7359                 .mixers = { alc883_lenovo_101e_2ch_mixer},
7360                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7361                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7362                 .dac_nids = alc883_dac_nids,
7363                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7364                 .adc_nids = alc883_adc_nids,
7365                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7366                 .channel_mode = alc883_3ST_2ch_modes,
7367                 .input_mux = &alc883_lenovo_101e_capture_source,
7368                 .unsol_event = alc883_lenovo_101e_unsol_event,
7369                 .init_hook = alc883_lenovo_101e_all_automute,
7370         },
7371         [ALC883_LENOVO_NB0763] = {
7372                 .mixers = { alc883_lenovo_nb0763_mixer },
7373                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7374                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7375                 .dac_nids = alc883_dac_nids,
7376                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7377                 .adc_nids = alc883_adc_nids,
7378                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7379                 .channel_mode = alc883_3ST_2ch_modes,
7380                 .need_dac_fix = 1,
7381                 .input_mux = &alc883_lenovo_nb0763_capture_source,
7382                 .unsol_event = alc883_medion_md2_unsol_event,
7383                 .init_hook = alc883_medion_md2_automute,
7384         },
7385         [ALC888_LENOVO_MS7195_DIG] = {
7386                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7387                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7388                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7389                 .dac_nids = alc883_dac_nids,
7390                 .dig_out_nid = ALC883_DIGOUT_NID,
7391                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7392                 .adc_nids = alc883_adc_nids,
7393                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7394                 .channel_mode = alc883_3ST_6ch_modes,
7395                 .need_dac_fix = 1,
7396                 .input_mux = &alc883_capture_source,
7397                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7398                 .init_hook = alc888_lenovo_ms7195_front_automute,
7399         },
7400         [ALC883_HAIER_W66] = {
7401                 .mixers = { alc883_tagra_2ch_mixer},
7402                 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7403                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7404                 .dac_nids = alc883_dac_nids,
7405                 .dig_out_nid = ALC883_DIGOUT_NID,
7406                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7407                 .adc_nids = alc883_adc_nids,
7408                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7409                 .channel_mode = alc883_3ST_2ch_modes,
7410                 .input_mux = &alc883_capture_source,
7411                 .unsol_event = alc883_haier_w66_unsol_event,
7412                 .init_hook = alc883_haier_w66_automute,
7413         },      
7414         [ALC888_6ST_HP] = {
7415                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7416                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7417                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7418                 .dac_nids = alc883_dac_nids,
7419                 .dig_out_nid = ALC883_DIGOUT_NID,
7420                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7421                 .adc_nids = alc883_adc_nids,
7422                 .dig_in_nid = ALC883_DIGIN_NID,
7423                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7424                 .channel_mode = alc883_sixstack_modes,
7425                 .input_mux = &alc883_capture_source,
7426         },
7427         [ALC888_3ST_HP] = {
7428                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7429                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7430                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7431                 .dac_nids = alc883_dac_nids,
7432                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7433                 .adc_nids = alc883_adc_nids,
7434                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7435                 .channel_mode = alc888_3st_hp_modes,
7436                 .need_dac_fix = 1,
7437                 .input_mux = &alc883_capture_source,
7438         },
7439 };
7440
7441
7442 /*
7443  * BIOS auto configuration
7444  */
7445 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7446                                               hda_nid_t nid, int pin_type,
7447                                               int dac_idx)
7448 {
7449         /* set as output */
7450         struct alc_spec *spec = codec->spec;
7451         int idx;
7452
7453         if (spec->multiout.dac_nids[dac_idx] == 0x25)
7454                 idx = 4;
7455         else
7456                 idx = spec->multiout.dac_nids[dac_idx] - 2;
7457
7458         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7459                             pin_type);
7460         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7461                             AMP_OUT_UNMUTE);
7462         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7463
7464 }
7465
7466 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7467 {
7468         struct alc_spec *spec = codec->spec;
7469         int i;
7470
7471         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7472         for (i = 0; i <= HDA_SIDE; i++) {
7473                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7474                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7475                 if (nid)
7476                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7477                                                           i);
7478         }
7479 }
7480
7481 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7482 {
7483         struct alc_spec *spec = codec->spec;
7484         hda_nid_t pin;
7485
7486         pin = spec->autocfg.hp_pins[0];
7487         if (pin) /* connect to front */
7488                 /* use dac 0 */
7489                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7490 }
7491
7492 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
7493 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
7494
7495 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7496 {
7497         struct alc_spec *spec = codec->spec;
7498         int i;
7499
7500         for (i = 0; i < AUTO_PIN_LAST; i++) {
7501                 hda_nid_t nid = spec->autocfg.input_pins[i];
7502                 if (alc883_is_input_pin(nid)) {
7503                         snd_hda_codec_write(codec, nid, 0,
7504                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
7505                                             (i <= AUTO_PIN_FRONT_MIC ?
7506                                              PIN_VREF80 : PIN_IN));
7507                         if (nid != ALC883_PIN_CD_NID)
7508                                 snd_hda_codec_write(codec, nid, 0,
7509                                                     AC_VERB_SET_AMP_GAIN_MUTE,
7510                                                     AMP_OUT_MUTE);
7511                 }
7512         }
7513 }
7514
7515 /* almost identical with ALC880 parser... */
7516 static int alc883_parse_auto_config(struct hda_codec *codec)
7517 {
7518         struct alc_spec *spec = codec->spec;
7519         int err = alc880_parse_auto_config(codec);
7520
7521         if (err < 0)
7522                 return err;
7523         else if (!err)
7524                 return 0; /* no config found */
7525
7526         err = alc_auto_add_mic_boost(codec);
7527         if (err < 0)
7528                 return err;
7529
7530         /* hack - override the init verbs */
7531         spec->init_verbs[0] = alc883_auto_init_verbs;
7532         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7533         spec->num_mixers++;
7534
7535         return 1; /* config found */
7536 }
7537
7538 /* additional initialization for auto-configuration model */
7539 static void alc883_auto_init(struct hda_codec *codec)
7540 {
7541         alc883_auto_init_multi_out(codec);
7542         alc883_auto_init_hp_out(codec);
7543         alc883_auto_init_analog_input(codec);
7544 }
7545
7546 static int patch_alc883(struct hda_codec *codec)
7547 {
7548         struct alc_spec *spec;
7549         int err, board_config;
7550
7551         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7552         if (spec == NULL)
7553                 return -ENOMEM;
7554
7555         codec->spec = spec;
7556
7557         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7558                                                   alc883_models,
7559                                                   alc883_cfg_tbl);
7560         if (board_config < 0) {
7561                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7562                        "trying auto-probe from BIOS...\n");
7563                 board_config = ALC883_AUTO;
7564         }
7565
7566         if (board_config == ALC883_AUTO) {
7567                 /* automatic parse from the BIOS config */
7568                 err = alc883_parse_auto_config(codec);
7569                 if (err < 0) {
7570                         alc_free(codec);
7571                         return err;
7572                 } else if (!err) {
7573                         printk(KERN_INFO
7574                                "hda_codec: Cannot set up configuration "
7575                                "from BIOS.  Using base mode...\n");
7576                         board_config = ALC883_3ST_2ch_DIG;
7577                 }
7578         }
7579
7580         if (board_config != ALC883_AUTO)
7581                 setup_preset(spec, &alc883_presets[board_config]);
7582
7583         spec->stream_name_analog = "ALC883 Analog";
7584         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7585         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7586
7587         spec->stream_name_digital = "ALC883 Digital";
7588         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7589         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7590
7591         if (!spec->adc_nids && spec->input_mux) {
7592                 spec->adc_nids = alc883_adc_nids;
7593                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7594         }
7595
7596         codec->patch_ops = alc_patch_ops;
7597         if (board_config == ALC883_AUTO)
7598                 spec->init_hook = alc883_auto_init;
7599 #ifdef CONFIG_SND_HDA_POWER_SAVE
7600         if (!spec->loopback.amplist)
7601                 spec->loopback.amplist = alc883_loopbacks;
7602 #endif
7603
7604         return 0;
7605 }
7606
7607 /*
7608  * ALC262 support
7609  */
7610
7611 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7612 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7613
7614 #define alc262_dac_nids         alc260_dac_nids
7615 #define alc262_adc_nids         alc882_adc_nids
7616 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7617
7618 #define alc262_modes            alc260_modes
7619 #define alc262_capture_source   alc882_capture_source
7620
7621 static struct snd_kcontrol_new alc262_base_mixer[] = {
7622         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7623         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7624         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7625         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7626         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7627         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7628         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7629         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7630         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7631         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7632         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7633         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7634         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7635            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7636         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7637         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7638         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7639         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7640         { } /* end */
7641 };
7642
7643 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7644         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7645         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7646         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7647         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7648         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7649         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7650         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7651         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7652         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7653         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7654         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7655         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7656         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7657            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7658         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7659         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7660         { } /* end */
7661 };
7662
7663 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7664         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7665         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7666         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7667         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7668         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7669
7670         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7671         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7672         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7673         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7674         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7675         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7676         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7677         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7678         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7679         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7680         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7681         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7682         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7683         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7684         { } /* end */
7685 };
7686
7687 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7688         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7689         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7690         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7691         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7692         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7693         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7694         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7695         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7696         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7697         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7698         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7699         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7700         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7701         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7702         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7703         { } /* end */
7704 };
7705
7706 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7707         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7708         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7709         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7710         { } /* end */
7711 };
7712
7713 /* bind hp and internal speaker mute (with plug check) */
7714 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7715                                      struct snd_ctl_elem_value *ucontrol)
7716 {
7717         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7718         long *valp = ucontrol->value.integer.value;
7719         int change;
7720
7721         /* change hp mute */
7722         change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7723                                           HDA_AMP_MUTE,
7724                                           valp[0] ? 0 : HDA_AMP_MUTE);
7725         change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7726                                            HDA_AMP_MUTE,
7727                                            valp[1] ? 0 : HDA_AMP_MUTE);
7728         if (change) {
7729                 /* change speaker according to HP jack state */
7730                 struct alc_spec *spec = codec->spec;
7731                 unsigned int mute;
7732                 if (spec->jack_present)
7733                         mute = HDA_AMP_MUTE;
7734                 else
7735                         mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7736                                                       HDA_OUTPUT, 0);
7737                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7738                                          HDA_AMP_MUTE, mute);
7739         }
7740         return change;
7741 }
7742
7743 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7744         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7745         {
7746                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7747                 .name = "Master Playback Switch",
7748                 .info = snd_hda_mixer_amp_switch_info,
7749                 .get = snd_hda_mixer_amp_switch_get,
7750                 .put = alc262_sony_master_sw_put,
7751                 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7752         },
7753         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7754         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7755         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7756         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7757         { } /* end */
7758 };
7759
7760 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7761         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7762         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7763         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7764         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7765         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7766         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7767         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7768         { } /* end */
7769 };
7770
7771 #define alc262_capture_mixer            alc882_capture_mixer
7772 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7773
7774 /*
7775  * generic initialization of ADC, input mixers and output mixers
7776  */
7777 static struct hda_verb alc262_init_verbs[] = {
7778         /*
7779          * Unmute ADC0-2 and set the default input to mic-in
7780          */
7781         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7782         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7783         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7784         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7785         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7786         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7787
7788         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7789          * mixer widget
7790          * Note: PASD motherboards uses the Line In 2 as the input for
7791          * front panel mic (mic 2)
7792          */
7793         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7794         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7795         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7796         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7797         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7798         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7799
7800         /*
7801          * Set up output mixers (0x0c - 0x0e)
7802          */
7803         /* set vol=0 to output mixers */
7804         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7805         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7806         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7807         /* set up input amps for analog loopback */
7808         /* Amp Indices: DAC = 0, mixer = 1 */
7809         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7810         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7811         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7812         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7813         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7814         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7815
7816         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7817         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7818         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7819         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7820         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7821         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7822
7823         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7824         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7825         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7826         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7827         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7828         
7829         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7830         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7831         
7832         /* FIXME: use matrix-type input source selection */
7833         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7834         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7835         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7836         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7837         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7838         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7839         /* Input mixer2 */
7840         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7841         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7842         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7843         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7844         /* Input mixer3 */
7845         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7846         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7847         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7848         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7849
7850         { }
7851 };
7852
7853 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7854         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7855         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7856         {}
7857 };
7858
7859 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7860         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7861         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7862         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7863
7864         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7865         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7866         {}
7867 };
7868
7869 static struct hda_verb alc262_sony_unsol_verbs[] = {
7870         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7871         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7872         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7873
7874         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7875         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7876 };
7877
7878 /* mute/unmute internal speaker according to the hp jack and mute state */
7879 static void alc262_hippo_automute(struct hda_codec *codec)
7880 {
7881         struct alc_spec *spec = codec->spec;
7882         unsigned int mute;
7883         unsigned int present;
7884
7885         /* need to execute and sync at first */
7886         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7887         present = snd_hda_codec_read(codec, 0x15, 0,
7888                                      AC_VERB_GET_PIN_SENSE, 0);
7889         spec->jack_present = (present & 0x80000000) != 0;
7890         if (spec->jack_present) {
7891                 /* mute internal speaker */
7892                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7893                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7894         } else {
7895                 /* unmute internal speaker if necessary */
7896                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7897                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7898                                          HDA_AMP_MUTE, mute);
7899         }
7900 }
7901
7902 /* unsolicited event for HP jack sensing */
7903 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7904                                        unsigned int res)
7905 {
7906         if ((res >> 26) != ALC880_HP_EVENT)
7907                 return;
7908         alc262_hippo_automute(codec);
7909 }
7910
7911 static void alc262_hippo1_automute(struct hda_codec *codec)
7912 {
7913         unsigned int mute;
7914         unsigned int present;
7915
7916         snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7917         present = snd_hda_codec_read(codec, 0x1b, 0,
7918                                      AC_VERB_GET_PIN_SENSE, 0);
7919         present = (present & 0x80000000) != 0;
7920         if (present) {
7921                 /* mute internal speaker */
7922                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7923                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7924         } else {
7925                 /* unmute internal speaker if necessary */
7926                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7927                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7928                                          HDA_AMP_MUTE, mute);
7929         }
7930 }
7931
7932 /* unsolicited event for HP jack sensing */
7933 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7934                                        unsigned int res)
7935 {
7936         if ((res >> 26) != ALC880_HP_EVENT)
7937                 return;
7938         alc262_hippo1_automute(codec);
7939 }
7940
7941 /*
7942  * fujitsu model
7943  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7944  */
7945
7946 #define ALC_HP_EVENT    0x37
7947
7948 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7949         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7950         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7951         {}
7952 };
7953
7954 static struct hda_input_mux alc262_fujitsu_capture_source = {
7955         .num_items = 3,
7956         .items = {
7957                 { "Mic", 0x0 },
7958                 { "Int Mic", 0x1 },
7959                 { "CD", 0x4 },
7960         },
7961 };
7962
7963 static struct hda_input_mux alc262_HP_capture_source = {
7964         .num_items = 5,
7965         .items = {
7966                 { "Mic", 0x0 },
7967                 { "Front Mic", 0x1 },
7968                 { "Line", 0x2 },
7969                 { "CD", 0x4 },
7970                 { "AUX IN", 0x6 },
7971         },
7972 };
7973
7974 static struct hda_input_mux alc262_HP_D7000_capture_source = {
7975         .num_items = 4,
7976         .items = {
7977                 { "Mic", 0x0 },
7978                 { "Front Mic", 0x2 },
7979                 { "Line", 0x1 },
7980                 { "CD", 0x4 },
7981         },
7982 };
7983
7984 /* mute/unmute internal speaker according to the hp jack and mute state */
7985 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7986 {
7987         struct alc_spec *spec = codec->spec;
7988         unsigned int mute;
7989
7990         if (force || !spec->sense_updated) {
7991                 unsigned int present;
7992                 /* need to execute and sync at first */
7993                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7994                 present = snd_hda_codec_read(codec, 0x14, 0,
7995                                          AC_VERB_GET_PIN_SENSE, 0);
7996                 spec->jack_present = (present & 0x80000000) != 0;
7997                 spec->sense_updated = 1;
7998         }
7999         if (spec->jack_present) {
8000                 /* mute internal speaker */
8001                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8002                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8003         } else {
8004                 /* unmute internal speaker if necessary */
8005                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8006                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8007                                          HDA_AMP_MUTE, mute);
8008         }
8009 }
8010
8011 /* unsolicited event for HP jack sensing */
8012 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8013                                        unsigned int res)
8014 {
8015         if ((res >> 26) != ALC_HP_EVENT)
8016                 return;
8017         alc262_fujitsu_automute(codec, 1);
8018 }
8019
8020 /* bind volumes of both NID 0x0c and 0x0d */
8021 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8022         .ops = &snd_hda_bind_vol,
8023         .values = {
8024                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8025                 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8026                 0
8027         },
8028 };
8029
8030 /* bind hp and internal speaker mute (with plug check) */
8031 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8032                                          struct snd_ctl_elem_value *ucontrol)
8033 {
8034         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8035         long *valp = ucontrol->value.integer.value;
8036         int change;
8037
8038         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8039                                           HDA_AMP_MUTE,
8040                                           valp[0] ? 0 : HDA_AMP_MUTE);
8041         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8042                                            HDA_AMP_MUTE,
8043                                            valp[1] ? 0 : HDA_AMP_MUTE);
8044         if (change)
8045                 alc262_fujitsu_automute(codec, 0);
8046         return change;
8047 }
8048
8049 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8050         HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8051         {
8052                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8053                 .name = "Master Playback Switch",
8054                 .info = snd_hda_mixer_amp_switch_info,
8055                 .get = snd_hda_mixer_amp_switch_get,
8056                 .put = alc262_fujitsu_master_sw_put,
8057                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8058         },
8059         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8060         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8061         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8062         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8063         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8064         HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8065         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8066         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8067         { } /* end */
8068 };
8069
8070 /* additional init verbs for Benq laptops */
8071 static struct hda_verb alc262_EAPD_verbs[] = {
8072         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8073         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
8074         {}
8075 };
8076
8077 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8078         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8079         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8080
8081         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8082         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
8083         {}
8084 };
8085
8086 /* Samsung Q1 Ultra Vista model setup */
8087 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8088         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8089         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8090         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8091         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8092         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8093         HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8094         { } /* end */
8095 };
8096
8097 static struct hda_verb alc262_ultra_verbs[] = {
8098         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8099         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8100         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8101         /* Mic is on Node 0x19 */
8102         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8103         {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8104         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8105         {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8106         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8107         {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8108         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8109         {}
8110 };
8111
8112 static struct hda_input_mux alc262_ultra_capture_source = {
8113         .num_items = 1,
8114         .items = {
8115                 { "Mic", 0x1 },
8116         },
8117 };
8118
8119 /* mute/unmute internal speaker according to the hp jack and mute state */
8120 static void alc262_ultra_automute(struct hda_codec *codec)
8121 {
8122         struct alc_spec *spec = codec->spec;
8123         unsigned int mute;
8124         unsigned int present;
8125
8126         /* need to execute and sync at first */
8127         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8128         present = snd_hda_codec_read(codec, 0x15, 0,
8129                                      AC_VERB_GET_PIN_SENSE, 0);
8130         spec->jack_present = (present & 0x80000000) != 0;
8131         if (spec->jack_present) {
8132                 /* mute internal speaker */
8133                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8134                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8135         } else {
8136                 /* unmute internal speaker if necessary */
8137                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8138                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8139                                          HDA_AMP_MUTE, mute);
8140         }
8141 }
8142
8143 /* unsolicited event for HP jack sensing */
8144 static void alc262_ultra_unsol_event(struct hda_codec *codec,
8145                                        unsigned int res)
8146 {
8147         if ((res >> 26) != ALC880_HP_EVENT)
8148                 return;
8149         alc262_ultra_automute(codec);
8150 }
8151
8152 /* add playback controls from the parsed DAC table */
8153 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8154                                              const struct auto_pin_cfg *cfg)
8155 {
8156         hda_nid_t nid;
8157         int err;
8158
8159         spec->multiout.num_dacs = 1;    /* only use one dac */
8160         spec->multiout.dac_nids = spec->private_dac_nids;
8161         spec->multiout.dac_nids[0] = 2;
8162
8163         nid = cfg->line_out_pins[0];
8164         if (nid) {
8165                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8166                                   "Front Playback Volume",
8167                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8168                 if (err < 0)
8169                         return err;
8170                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8171                                   "Front Playback Switch",
8172                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8173                 if (err < 0)
8174                         return err;
8175         }
8176
8177         nid = cfg->speaker_pins[0];
8178         if (nid) {
8179                 if (nid == 0x16) {
8180                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
8181                                           "Speaker Playback Volume",
8182                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8183                                                               HDA_OUTPUT));
8184                         if (err < 0)
8185                                 return err;
8186                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8187                                           "Speaker Playback Switch",
8188                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8189                                                               HDA_OUTPUT));
8190                         if (err < 0)
8191                                 return err;
8192                 } else {
8193                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8194                                           "Speaker Playback Switch",
8195                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8196                                                               HDA_OUTPUT));
8197                         if (err < 0)
8198                                 return err;
8199                 }
8200         }
8201         nid = cfg->hp_pins[0];
8202         if (nid) {
8203                 /* spec->multiout.hp_nid = 2; */
8204                 if (nid == 0x16) {
8205                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
8206                                           "Headphone Playback Volume",
8207                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8208                                                               HDA_OUTPUT));
8209                         if (err < 0)
8210                                 return err;
8211                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8212                                           "Headphone Playback Switch",
8213                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8214                                                               HDA_OUTPUT));
8215                         if (err < 0)
8216                                 return err;
8217                 } else {
8218                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8219                                           "Headphone Playback Switch",
8220                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8221                                                               HDA_OUTPUT));
8222                         if (err < 0)
8223                                 return err;
8224                 }
8225         }
8226         return 0;
8227 }
8228
8229 /* identical with ALC880 */
8230 #define alc262_auto_create_analog_input_ctls \
8231         alc880_auto_create_analog_input_ctls
8232
8233 /*
8234  * generic initialization of ADC, input mixers and output mixers
8235  */
8236 static struct hda_verb alc262_volume_init_verbs[] = {
8237         /*
8238          * Unmute ADC0-2 and set the default input to mic-in
8239          */
8240         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8241         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8242         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8243         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8244         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8245         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8246
8247         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8248          * mixer widget
8249          * Note: PASD motherboards uses the Line In 2 as the input for
8250          * front panel mic (mic 2)
8251          */
8252         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8253         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8254         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8255         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8256         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8257         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8258
8259         /*
8260          * Set up output mixers (0x0c - 0x0f)
8261          */
8262         /* set vol=0 to output mixers */
8263         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8264         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8265         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8266         
8267         /* set up input amps for analog loopback */
8268         /* Amp Indices: DAC = 0, mixer = 1 */
8269         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8270         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8271         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8272         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8273         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8274         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8275
8276         /* FIXME: use matrix-type input source selection */
8277         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8278         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8279         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8280         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8281         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8282         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8283         /* Input mixer2 */
8284         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8285         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8286         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8287         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8288         /* Input mixer3 */
8289         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8290         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8291         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8292         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8293
8294         { }
8295 };
8296
8297 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8298         /*
8299          * Unmute ADC0-2 and set the default input to mic-in
8300          */
8301         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8302         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8303         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8304         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8305         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8306         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8307
8308         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8309          * mixer widget
8310          * Note: PASD motherboards uses the Line In 2 as the input for
8311          * front panel mic (mic 2)
8312          */
8313         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8314         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8315         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8316         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8317         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8318         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8319         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8320         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8321         
8322         /*
8323          * Set up output mixers (0x0c - 0x0e)
8324          */
8325         /* set vol=0 to output mixers */
8326         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8327         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8328         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8329
8330         /* set up input amps for analog loopback */
8331         /* Amp Indices: DAC = 0, mixer = 1 */
8332         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8333         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8334         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8335         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8336         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8337         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8338
8339         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8340         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8341         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8342
8343         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8344         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8345
8346         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8347         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8348
8349         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8350         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8351         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8352         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8353         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8354
8355         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8356         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8357         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8358         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8359         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8360         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8361
8362
8363         /* FIXME: use matrix-type input source selection */
8364         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8365         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8366         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8367         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8368         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8369         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8370         /* Input mixer2 */
8371         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8372         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8373         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8374         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8375         /* Input mixer3 */
8376         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8377         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8378         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8379         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8380
8381         { }
8382 };
8383
8384 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8385         /*
8386          * Unmute ADC0-2 and set the default input to mic-in
8387          */
8388         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8389         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8390         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8391         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8392         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8393         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8394
8395         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8396          * mixer widget
8397          * Note: PASD motherboards uses the Line In 2 as the input for front
8398          * panel mic (mic 2)
8399          */
8400         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8401         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8402         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8403         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8404         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8405         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8406         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8407         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8408         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8409         /*
8410          * Set up output mixers (0x0c - 0x0e)
8411          */
8412         /* set vol=0 to output mixers */
8413         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8414         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8415         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8416
8417         /* set up input amps for analog loopback */
8418         /* Amp Indices: DAC = 0, mixer = 1 */
8419         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8420         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8421         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8422         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8423         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8424         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8425
8426
8427         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
8428         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
8429         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
8430         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
8431         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
8432         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
8433         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
8434
8435         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8436         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8437
8438         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8439         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8440
8441         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8442         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8443         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8444         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8445         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8446         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8447
8448         /* FIXME: use matrix-type input source selection */
8449         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8450         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8451         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8452         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8453         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8454         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8455         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8456         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
8457         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8458         /* Input mixer2 */
8459         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8460         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8461         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8462         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8463         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8464         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8465         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8466         /* Input mixer3 */
8467         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8468         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8469         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8470         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8471         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8472         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8473         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8474
8475         { }
8476 };
8477
8478 #ifdef CONFIG_SND_HDA_POWER_SAVE
8479 #define alc262_loopbacks        alc880_loopbacks
8480 #endif
8481
8482 /* pcm configuration: identiacal with ALC880 */
8483 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
8484 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
8485 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
8486 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
8487
8488 /*
8489  * BIOS auto configuration
8490  */
8491 static int alc262_parse_auto_config(struct hda_codec *codec)
8492 {
8493         struct alc_spec *spec = codec->spec;
8494         int err;
8495         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8496
8497         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8498                                            alc262_ignore);
8499         if (err < 0)
8500                 return err;
8501         if (!spec->autocfg.line_outs)
8502                 return 0; /* can't find valid BIOS pin config */
8503         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8504         if (err < 0)
8505                 return err;
8506         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8507         if (err < 0)
8508                 return err;
8509
8510         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8511
8512         if (spec->autocfg.dig_out_pin)
8513                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8514         if (spec->autocfg.dig_in_pin)
8515                 spec->dig_in_nid = ALC262_DIGIN_NID;
8516
8517         if (spec->kctl_alloc)
8518                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8519
8520         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8521         spec->num_mux_defs = 1;
8522         spec->input_mux = &spec->private_imux;
8523
8524         err = alc_auto_add_mic_boost(codec);
8525         if (err < 0)
8526                 return err;
8527
8528         return 1;
8529 }
8530
8531 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
8532 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
8533 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
8534
8535
8536 /* init callback for auto-configuration model -- overriding the default init */
8537 static void alc262_auto_init(struct hda_codec *codec)
8538 {
8539         alc262_auto_init_multi_out(codec);
8540         alc262_auto_init_hp_out(codec);
8541         alc262_auto_init_analog_input(codec);
8542 }
8543
8544 /*
8545  * configuration and preset
8546  */
8547 static const char *alc262_models[ALC262_MODEL_LAST] = {
8548         [ALC262_BASIC]          = "basic",
8549         [ALC262_HIPPO]          = "hippo",
8550         [ALC262_HIPPO_1]        = "hippo_1",
8551         [ALC262_FUJITSU]        = "fujitsu",
8552         [ALC262_HP_BPC]         = "hp-bpc",
8553         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8554         [ALC262_BENQ_ED8]       = "benq",
8555         [ALC262_BENQ_T31]       = "benq-t31",
8556         [ALC262_SONY_ASSAMD]    = "sony-assamd",
8557         [ALC262_ULTRA]          = "ultra",
8558         [ALC262_AUTO]           = "auto",
8559 };
8560
8561 static struct snd_pci_quirk alc262_cfg_tbl[] = {
8562         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8563         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8564         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8565         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8566         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8567         SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
8568         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8569         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8570         SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
8571         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8572         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8573         SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
8574         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8575         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8576         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8577         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8578         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8579         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8580         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8581         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8582         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8583         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8584         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8585         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8586         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8587         SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8588         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8589         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8590         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8591         SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
8592         {}
8593 };
8594
8595 static struct alc_config_preset alc262_presets[] = {
8596         [ALC262_BASIC] = {
8597                 .mixers = { alc262_base_mixer },
8598                 .init_verbs = { alc262_init_verbs },
8599                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8600                 .dac_nids = alc262_dac_nids,
8601                 .hp_nid = 0x03,
8602                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8603                 .channel_mode = alc262_modes,
8604                 .input_mux = &alc262_capture_source,
8605         },
8606         [ALC262_HIPPO] = {
8607                 .mixers = { alc262_base_mixer },
8608                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8609                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8610                 .dac_nids = alc262_dac_nids,
8611                 .hp_nid = 0x03,
8612                 .dig_out_nid = ALC262_DIGOUT_NID,
8613                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8614                 .channel_mode = alc262_modes,
8615                 .input_mux = &alc262_capture_source,
8616                 .unsol_event = alc262_hippo_unsol_event,
8617                 .init_hook = alc262_hippo_automute,
8618         },
8619         [ALC262_HIPPO_1] = {
8620                 .mixers = { alc262_hippo1_mixer },
8621                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8622                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8623                 .dac_nids = alc262_dac_nids,
8624                 .hp_nid = 0x02,
8625                 .dig_out_nid = ALC262_DIGOUT_NID,
8626                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8627                 .channel_mode = alc262_modes,
8628                 .input_mux = &alc262_capture_source,
8629                 .unsol_event = alc262_hippo1_unsol_event,
8630                 .init_hook = alc262_hippo1_automute,
8631         },
8632         [ALC262_FUJITSU] = {
8633                 .mixers = { alc262_fujitsu_mixer },
8634                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8635                                 alc262_fujitsu_unsol_verbs },
8636                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8637                 .dac_nids = alc262_dac_nids,
8638                 .hp_nid = 0x03,
8639                 .dig_out_nid = ALC262_DIGOUT_NID,
8640                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8641                 .channel_mode = alc262_modes,
8642                 .input_mux = &alc262_fujitsu_capture_source,
8643                 .unsol_event = alc262_fujitsu_unsol_event,
8644         },
8645         [ALC262_HP_BPC] = {
8646                 .mixers = { alc262_HP_BPC_mixer },
8647                 .init_verbs = { alc262_HP_BPC_init_verbs },
8648                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8649                 .dac_nids = alc262_dac_nids,
8650                 .hp_nid = 0x03,
8651                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8652                 .channel_mode = alc262_modes,
8653                 .input_mux = &alc262_HP_capture_source,
8654         },
8655         [ALC262_HP_BPC_D7000_WF] = {
8656                 .mixers = { alc262_HP_BPC_WildWest_mixer },
8657                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8658                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8659                 .dac_nids = alc262_dac_nids,
8660                 .hp_nid = 0x03,
8661                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8662                 .channel_mode = alc262_modes,
8663                 .input_mux = &alc262_HP_D7000_capture_source,
8664         },
8665         [ALC262_HP_BPC_D7000_WL] = {
8666                 .mixers = { alc262_HP_BPC_WildWest_mixer,
8667                             alc262_HP_BPC_WildWest_option_mixer },
8668                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8669                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8670                 .dac_nids = alc262_dac_nids,
8671                 .hp_nid = 0x03,
8672                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8673                 .channel_mode = alc262_modes,
8674                 .input_mux = &alc262_HP_D7000_capture_source,
8675         },
8676         [ALC262_BENQ_ED8] = {
8677                 .mixers = { alc262_base_mixer },
8678                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8679                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8680                 .dac_nids = alc262_dac_nids,
8681                 .hp_nid = 0x03,
8682                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8683                 .channel_mode = alc262_modes,
8684                 .input_mux = &alc262_capture_source,
8685         },
8686         [ALC262_SONY_ASSAMD] = {
8687                 .mixers = { alc262_sony_mixer },
8688                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8689                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8690                 .dac_nids = alc262_dac_nids,
8691                 .hp_nid = 0x02,
8692                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8693                 .channel_mode = alc262_modes,
8694                 .input_mux = &alc262_capture_source,
8695                 .unsol_event = alc262_hippo_unsol_event,
8696                 .init_hook = alc262_hippo_automute,
8697         },
8698         [ALC262_BENQ_T31] = {
8699                 .mixers = { alc262_benq_t31_mixer },
8700                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8701                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8702                 .dac_nids = alc262_dac_nids,
8703                 .hp_nid = 0x03,
8704                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8705                 .channel_mode = alc262_modes,
8706                 .input_mux = &alc262_capture_source,
8707                 .unsol_event = alc262_hippo_unsol_event,
8708                 .init_hook = alc262_hippo_automute,
8709         },      
8710         [ALC262_ULTRA] = {
8711                 .mixers = { alc262_ultra_mixer },
8712                 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
8713                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8714                 .dac_nids = alc262_dac_nids,
8715                 .hp_nid = 0x03,
8716                 .dig_out_nid = ALC262_DIGOUT_NID,
8717                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8718                 .channel_mode = alc262_modes,
8719                 .input_mux = &alc262_ultra_capture_source,
8720                 .unsol_event = alc262_ultra_unsol_event,
8721                 .init_hook = alc262_ultra_automute,
8722         },
8723 };
8724
8725 static int patch_alc262(struct hda_codec *codec)
8726 {
8727         struct alc_spec *spec;
8728         int board_config;
8729         int err;
8730
8731         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8732         if (spec == NULL)
8733                 return -ENOMEM;
8734
8735         codec->spec = spec;
8736 #if 0
8737         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8738          * under-run
8739          */
8740         {
8741         int tmp;
8742         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8743         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8744         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8745         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8746         }
8747 #endif
8748
8749         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8750                                                   alc262_models,
8751                                                   alc262_cfg_tbl);
8752
8753         if (board_config < 0) {
8754                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8755                        "trying auto-probe from BIOS...\n");
8756                 board_config = ALC262_AUTO;
8757         }
8758
8759         if (board_config == ALC262_AUTO) {
8760                 /* automatic parse from the BIOS config */
8761                 err = alc262_parse_auto_config(codec);
8762                 if (err < 0) {
8763                         alc_free(codec);
8764                         return err;
8765                 } else if (!err) {
8766                         printk(KERN_INFO
8767                                "hda_codec: Cannot set up configuration "
8768                                "from BIOS.  Using base mode...\n");
8769                         board_config = ALC262_BASIC;
8770                 }
8771         }
8772
8773         if (board_config != ALC262_AUTO)
8774                 setup_preset(spec, &alc262_presets[board_config]);
8775
8776         spec->stream_name_analog = "ALC262 Analog";
8777         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8778         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8779                 
8780         spec->stream_name_digital = "ALC262 Digital";
8781         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8782         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8783
8784         if (!spec->adc_nids && spec->input_mux) {
8785                 /* check whether NID 0x07 is valid */
8786                 unsigned int wcap = get_wcaps(codec, 0x07);
8787
8788                 /* get type */
8789                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8790                 if (wcap != AC_WID_AUD_IN) {
8791                         spec->adc_nids = alc262_adc_nids_alt;
8792                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8793                         spec->mixers[spec->num_mixers] =
8794                                 alc262_capture_alt_mixer;
8795                         spec->num_mixers++;
8796                 } else {
8797                         spec->adc_nids = alc262_adc_nids;
8798                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8799                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8800                         spec->num_mixers++;
8801                 }
8802         }
8803
8804         codec->patch_ops = alc_patch_ops;
8805         if (board_config == ALC262_AUTO)
8806                 spec->init_hook = alc262_auto_init;
8807 #ifdef CONFIG_SND_HDA_POWER_SAVE
8808         if (!spec->loopback.amplist)
8809                 spec->loopback.amplist = alc262_loopbacks;
8810 #endif
8811                 
8812         return 0;
8813 }
8814
8815 /*
8816  *  ALC268 channel source setting (2 channel)
8817  */
8818 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8819 #define alc268_modes            alc260_modes
8820         
8821 static hda_nid_t alc268_dac_nids[2] = {
8822         /* front, hp */
8823         0x02, 0x03
8824 };
8825
8826 static hda_nid_t alc268_adc_nids[2] = {
8827         /* ADC0-1 */
8828         0x08, 0x07
8829 };
8830
8831 static hda_nid_t alc268_adc_nids_alt[1] = {
8832         /* ADC0 */
8833         0x08
8834 };
8835
8836 static struct snd_kcontrol_new alc268_base_mixer[] = {
8837         /* output mixer control */
8838         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8839         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8840         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8841         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8842         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8843         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8844         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
8845         { }
8846 };
8847
8848 static struct hda_verb alc268_eapd_verbs[] = {
8849         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8850         {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8851         { }
8852 };
8853
8854 /* Toshiba specific */
8855 #define alc268_toshiba_automute alc262_hippo_automute
8856
8857 static struct hda_verb alc268_toshiba_verbs[] = {
8858         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8859         { } /* end */
8860 };
8861
8862 /* Acer specific */
8863 /* bind volumes of both NID 0x02 and 0x03 */
8864 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
8865         .ops = &snd_hda_bind_vol,
8866         .values = {
8867                 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
8868                 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
8869                 0
8870         },
8871 };
8872
8873 /* mute/unmute internal speaker according to the hp jack and mute state */
8874 static void alc268_acer_automute(struct hda_codec *codec, int force)
8875 {
8876         struct alc_spec *spec = codec->spec;
8877         unsigned int mute;
8878
8879         if (force || !spec->sense_updated) {
8880                 unsigned int present;
8881                 present = snd_hda_codec_read(codec, 0x14, 0,
8882                                          AC_VERB_GET_PIN_SENSE, 0);
8883                 spec->jack_present = (present & 0x80000000) != 0;
8884                 spec->sense_updated = 1;
8885         }
8886         if (spec->jack_present)
8887                 mute = HDA_AMP_MUTE; /* mute internal speaker */
8888         else /* unmute internal speaker if necessary */
8889                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8890         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8891                                  HDA_AMP_MUTE, mute);
8892 }
8893
8894
8895 /* bind hp and internal speaker mute (with plug check) */
8896 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
8897                                      struct snd_ctl_elem_value *ucontrol)
8898 {
8899         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8900         long *valp = ucontrol->value.integer.value;
8901         int change;
8902
8903         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8904                                           HDA_AMP_MUTE,
8905                                           valp[0] ? 0 : HDA_AMP_MUTE);
8906         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8907                                            HDA_AMP_MUTE,
8908                                            valp[1] ? 0 : HDA_AMP_MUTE);
8909         if (change)
8910                 alc268_acer_automute(codec, 0);
8911         return change;
8912 }
8913
8914 static struct snd_kcontrol_new alc268_acer_mixer[] = {
8915         /* output mixer control */
8916         HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
8917         {
8918                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8919                 .name = "Master Playback Switch",
8920                 .info = snd_hda_mixer_amp_switch_info,
8921                 .get = snd_hda_mixer_amp_switch_get,
8922                 .put = alc268_acer_master_sw_put,
8923                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8924         },
8925         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8926         HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
8927         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
8928         { }
8929 };
8930
8931 static struct hda_verb alc268_acer_verbs[] = {
8932         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8933         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8934
8935         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8936         { }
8937 };
8938
8939 /* unsolicited event for HP jack sensing */
8940 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
8941                                        unsigned int res)
8942 {
8943         if ((res >> 26) != ALC880_HP_EVENT)
8944                 return;
8945         alc268_toshiba_automute(codec);
8946 }
8947
8948 static void alc268_acer_unsol_event(struct hda_codec *codec,
8949                                        unsigned int res)
8950 {
8951         if ((res >> 26) != ALC880_HP_EVENT)
8952                 return;
8953         alc268_acer_automute(codec, 1);
8954 }
8955
8956 static void alc268_acer_init_hook(struct hda_codec *codec)
8957 {
8958         alc268_acer_automute(codec, 1);
8959 }
8960
8961 /*
8962  * generic initialization of ADC, input mixers and output mixers
8963  */
8964 static struct hda_verb alc268_base_init_verbs[] = {
8965         /* Unmute DAC0-1 and set vol = 0 */
8966         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8967         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8968         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8969         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8970         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8971         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8972
8973         /*
8974          * Set up output mixers (0x0c - 0x0e)
8975          */
8976         /* set vol=0 to output mixers */
8977         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8978         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8979         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8980         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8981
8982         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8983         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8984
8985         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8986         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8987         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8988         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8989         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8990         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8991         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8992         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8993
8994         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8995         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8996         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8997         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8998         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8999         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9000         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9001         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9002
9003         /* FIXME: use matrix-type input source selection */
9004         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
9005         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9006         /* Input mixer2 */
9007         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9008         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9009         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9010         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9011
9012         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9013         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9014         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9015         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9016         { }
9017 };
9018
9019 /*
9020  * generic initialization of ADC, input mixers and output mixers
9021  */
9022 static struct hda_verb alc268_volume_init_verbs[] = {
9023         /* set output DAC */
9024         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9025         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9026         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9027         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9028
9029         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9030         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9031         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9032         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9033         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9034
9035         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9036         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9037         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9038         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9039         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9040
9041         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9042         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9043         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9044         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9045
9046         /* set PCBEEP vol = 0 */
9047         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9048
9049         { }
9050 };
9051
9052 #define alc268_mux_enum_info alc_mux_enum_info
9053 #define alc268_mux_enum_get alc_mux_enum_get
9054
9055 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9056                                struct snd_ctl_elem_value *ucontrol)
9057 {
9058         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9059         struct alc_spec *spec = codec->spec;
9060         const struct hda_input_mux *imux = spec->input_mux;
9061         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9062         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9063         hda_nid_t nid = capture_mixers[adc_idx];
9064         unsigned int *cur_val = &spec->cur_mux[adc_idx];
9065         unsigned int i, idx;
9066
9067         idx = ucontrol->value.enumerated.item[0];
9068         if (idx >= imux->num_items)
9069                 idx = imux->num_items - 1;
9070         if (*cur_val == idx)
9071                 return 0;
9072         for (i = 0; i < imux->num_items; i++) {
9073                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
9074                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
9075                                          imux->items[i].index,
9076                                          HDA_AMP_MUTE, v);
9077                 snd_hda_codec_write_cache(codec, nid, 0,
9078                                           AC_VERB_SET_CONNECT_SEL,
9079                                           idx );
9080         }
9081         *cur_val = idx;
9082         return 1;
9083 }
9084
9085 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9086         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9087         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9088         {
9089                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9090                 /* The multiple "Capture Source" controls confuse alsamixer
9091                  * So call somewhat different..
9092                  * FIXME: the controls appear in the "playback" view!
9093                  */
9094                 /* .name = "Capture Source", */
9095                 .name = "Input Source",
9096                 .count = 1,
9097                 .info = alc268_mux_enum_info,
9098                 .get = alc268_mux_enum_get,
9099                 .put = alc268_mux_enum_put,
9100         },
9101         { } /* end */
9102 };
9103
9104 static struct snd_kcontrol_new alc268_capture_mixer[] = {
9105         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9106         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9107         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9108         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9109         {
9110                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9111                 /* The multiple "Capture Source" controls confuse alsamixer
9112                  * So call somewhat different..
9113                  * FIXME: the controls appear in the "playback" view!
9114                  */
9115                 /* .name = "Capture Source", */
9116                 .name = "Input Source",
9117                 .count = 2,
9118                 .info = alc268_mux_enum_info,
9119                 .get = alc268_mux_enum_get,
9120                 .put = alc268_mux_enum_put,
9121         },
9122         { } /* end */
9123 };
9124
9125 static struct hda_input_mux alc268_capture_source = {
9126         .num_items = 4,
9127         .items = {
9128                 { "Mic", 0x0 },
9129                 { "Front Mic", 0x1 },
9130                 { "Line", 0x2 },
9131                 { "CD", 0x3 },
9132         },
9133 };
9134
9135 /* create input playback/capture controls for the given pin */
9136 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9137                                     const char *ctlname, int idx)
9138 {
9139         char name[32];
9140         int err;
9141
9142         sprintf(name, "%s Playback Volume", ctlname);
9143         if (nid == 0x14) {
9144                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9145                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9146                                                       HDA_OUTPUT));
9147                 if (err < 0)
9148                         return err;
9149         } else if (nid == 0x15) {
9150                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9151                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9152                                                       HDA_OUTPUT));
9153                 if (err < 0)
9154                         return err;
9155         } else
9156                 return -1;
9157         sprintf(name, "%s Playback Switch", ctlname);
9158         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9159                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9160         if (err < 0)
9161                 return err;
9162         return 0;
9163 }
9164
9165 /* add playback controls from the parsed DAC table */
9166 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9167                                              const struct auto_pin_cfg *cfg)
9168 {
9169         hda_nid_t nid;
9170         int err;
9171
9172         spec->multiout.num_dacs = 2;    /* only use one dac */
9173         spec->multiout.dac_nids = spec->private_dac_nids;
9174         spec->multiout.dac_nids[0] = 2;
9175         spec->multiout.dac_nids[1] = 3;
9176
9177         nid = cfg->line_out_pins[0];
9178         if (nid)
9179                 alc268_new_analog_output(spec, nid, "Front", 0);        
9180
9181         nid = cfg->speaker_pins[0];
9182         if (nid == 0x1d) {
9183                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9184                                   "Speaker Playback Volume",
9185                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9186                 if (err < 0)
9187                         return err;
9188         }
9189         nid = cfg->hp_pins[0];
9190         if (nid)
9191                 alc268_new_analog_output(spec, nid, "Headphone", 0);
9192
9193         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9194         if (nid == 0x16) {
9195                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9196                                   "Mono Playback Switch",
9197                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9198                 if (err < 0)
9199                         return err;
9200         }
9201         return 0;       
9202 }
9203
9204 /* create playback/capture controls for input pins */
9205 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9206                                                 const struct auto_pin_cfg *cfg)
9207 {
9208         struct hda_input_mux *imux = &spec->private_imux;
9209         int i, idx1;
9210
9211         for (i = 0; i < AUTO_PIN_LAST; i++) {
9212                 switch(cfg->input_pins[i]) {
9213                 case 0x18:
9214                         idx1 = 0;       /* Mic 1 */
9215                         break;
9216                 case 0x19:
9217                         idx1 = 1;       /* Mic 2 */
9218                         break;
9219                 case 0x1a:
9220                         idx1 = 2;       /* Line In */
9221                         break;
9222                 case 0x1c:      
9223                         idx1 = 3;       /* CD */
9224                         break;
9225                 default:
9226                         continue;
9227                 }
9228                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9229                 imux->items[imux->num_items].index = idx1;
9230                 imux->num_items++;      
9231         }
9232         return 0;
9233 }
9234
9235 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9236 {
9237         struct alc_spec *spec = codec->spec;
9238         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9239         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9240         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9241         unsigned int    dac_vol1, dac_vol2;
9242
9243         if (speaker_nid) {
9244                 snd_hda_codec_write(codec, speaker_nid, 0,
9245                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9246                 snd_hda_codec_write(codec, 0x0f, 0,
9247                                     AC_VERB_SET_AMP_GAIN_MUTE,
9248                                     AMP_IN_UNMUTE(1));
9249                 snd_hda_codec_write(codec, 0x10, 0,
9250                                     AC_VERB_SET_AMP_GAIN_MUTE,
9251                                     AMP_IN_UNMUTE(1));
9252         } else {
9253                 snd_hda_codec_write(codec, 0x0f, 0,
9254                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9255                 snd_hda_codec_write(codec, 0x10, 0,
9256                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9257         }
9258
9259         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
9260         if (line_nid == 0x14)   
9261                 dac_vol2 = AMP_OUT_ZERO;
9262         else if (line_nid == 0x15)
9263                 dac_vol1 = AMP_OUT_ZERO;
9264         if (hp_nid == 0x14)     
9265                 dac_vol2 = AMP_OUT_ZERO;
9266         else if (hp_nid == 0x15)
9267                 dac_vol1 = AMP_OUT_ZERO;
9268         if (line_nid != 0x16 || hp_nid != 0x16 ||
9269             spec->autocfg.line_out_pins[1] != 0x16 ||
9270             spec->autocfg.line_out_pins[2] != 0x16)
9271                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9272
9273         snd_hda_codec_write(codec, 0x02, 0,
9274                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9275         snd_hda_codec_write(codec, 0x03, 0,
9276                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9277 }
9278
9279 /* pcm configuration: identiacal with ALC880 */
9280 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
9281 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
9282 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
9283
9284 /*
9285  * BIOS auto configuration
9286  */
9287 static int alc268_parse_auto_config(struct hda_codec *codec)
9288 {
9289         struct alc_spec *spec = codec->spec;
9290         int err;
9291         static hda_nid_t alc268_ignore[] = { 0 };
9292
9293         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9294                                            alc268_ignore);
9295         if (err < 0)
9296                 return err;
9297         if (!spec->autocfg.line_outs)
9298                 return 0; /* can't find valid BIOS pin config */
9299
9300         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9301         if (err < 0)
9302                 return err;
9303         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9304         if (err < 0)
9305                 return err;
9306
9307         spec->multiout.max_channels = 2;
9308
9309         /* digital only support output */
9310         if (spec->autocfg.dig_out_pin)
9311                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9312
9313         if (spec->kctl_alloc)
9314                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9315
9316         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9317         spec->num_mux_defs = 1;
9318         spec->input_mux = &spec->private_imux;
9319
9320         err = alc_auto_add_mic_boost(codec);
9321         if (err < 0)
9322                 return err;
9323
9324         return 1;
9325 }
9326
9327 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
9328 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
9329 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
9330
9331 /* init callback for auto-configuration model -- overriding the default init */
9332 static void alc268_auto_init(struct hda_codec *codec)
9333 {
9334         alc268_auto_init_multi_out(codec);
9335         alc268_auto_init_hp_out(codec);
9336         alc268_auto_init_mono_speaker_out(codec);
9337         alc268_auto_init_analog_input(codec);
9338 }
9339
9340 /*
9341  * configuration and preset
9342  */
9343 static const char *alc268_models[ALC268_MODEL_LAST] = {
9344         [ALC268_3ST]            = "3stack",
9345         [ALC268_TOSHIBA]        = "toshiba",
9346         [ALC268_ACER]           = "acer",
9347         [ALC268_AUTO]           = "auto",
9348 };
9349
9350 static struct snd_pci_quirk alc268_cfg_tbl[] = {
9351         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
9352         SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
9353         SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
9354         SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
9355         SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9356         SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9357         SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
9358         {}
9359 };
9360
9361 static struct alc_config_preset alc268_presets[] = {
9362         [ALC268_3ST] = {
9363                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9364                 .init_verbs = { alc268_base_init_verbs },
9365                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9366                 .dac_nids = alc268_dac_nids,
9367                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9368                 .adc_nids = alc268_adc_nids_alt,
9369                 .hp_nid = 0x03,
9370                 .dig_out_nid = ALC268_DIGOUT_NID,
9371                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9372                 .channel_mode = alc268_modes,
9373                 .input_mux = &alc268_capture_source,
9374         },
9375         [ALC268_TOSHIBA] = {
9376                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9377                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9378                                 alc268_toshiba_verbs },
9379                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9380                 .dac_nids = alc268_dac_nids,
9381                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9382                 .adc_nids = alc268_adc_nids_alt,
9383                 .hp_nid = 0x03,
9384                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9385                 .channel_mode = alc268_modes,
9386                 .input_mux = &alc268_capture_source,
9387                 .unsol_event = alc268_toshiba_unsol_event,
9388                 .init_hook = alc268_toshiba_automute,
9389         },
9390         [ALC268_ACER] = {
9391                 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9392                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9393                                 alc268_acer_verbs },
9394                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9395                 .dac_nids = alc268_dac_nids,
9396                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9397                 .adc_nids = alc268_adc_nids_alt,
9398                 .hp_nid = 0x02,
9399                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9400                 .channel_mode = alc268_modes,
9401                 .input_mux = &alc268_capture_source,
9402                 .unsol_event = alc268_acer_unsol_event,
9403                 .init_hook = alc268_acer_init_hook,
9404         },
9405 };
9406
9407 static int patch_alc268(struct hda_codec *codec)
9408 {
9409         struct alc_spec *spec;
9410         int board_config;
9411         int err;
9412
9413         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9414         if (spec == NULL)
9415                 return -ENOMEM;
9416
9417         codec->spec = spec;
9418
9419         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9420                                                   alc268_models,
9421                                                   alc268_cfg_tbl);
9422
9423         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9424                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9425                        "trying auto-probe from BIOS...\n");
9426                 board_config = ALC268_AUTO;
9427         }
9428
9429         if (board_config == ALC268_AUTO) {
9430                 /* automatic parse from the BIOS config */
9431                 err = alc268_parse_auto_config(codec);
9432                 if (err < 0) {
9433                         alc_free(codec);
9434                         return err;
9435                 } else if (!err) {
9436                         printk(KERN_INFO
9437                                "hda_codec: Cannot set up configuration "
9438                                "from BIOS.  Using base mode...\n");
9439                         board_config = ALC268_3ST;
9440                 }
9441         }
9442
9443         if (board_config != ALC268_AUTO)
9444                 setup_preset(spec, &alc268_presets[board_config]);
9445
9446         spec->stream_name_analog = "ALC268 Analog";
9447         spec->stream_analog_playback = &alc268_pcm_analog_playback;
9448         spec->stream_analog_capture = &alc268_pcm_analog_capture;
9449
9450         spec->stream_name_digital = "ALC268 Digital";
9451         spec->stream_digital_playback = &alc268_pcm_digital_playback;
9452
9453         if (board_config == ALC268_AUTO) {
9454                 if (!spec->adc_nids && spec->input_mux) {
9455                         /* check whether NID 0x07 is valid */
9456                         unsigned int wcap = get_wcaps(codec, 0x07);
9457
9458                         /* get type */
9459                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9460                         if (wcap != AC_WID_AUD_IN) {
9461                                 spec->adc_nids = alc268_adc_nids_alt;
9462                                 spec->num_adc_nids =
9463                                         ARRAY_SIZE(alc268_adc_nids_alt);
9464                                 spec->mixers[spec->num_mixers] =
9465                                         alc268_capture_alt_mixer;
9466                                 spec->num_mixers++;
9467                         } else {
9468                                 spec->adc_nids = alc268_adc_nids;
9469                                 spec->num_adc_nids =
9470                                         ARRAY_SIZE(alc268_adc_nids);
9471                                 spec->mixers[spec->num_mixers] =
9472                                         alc268_capture_mixer;
9473                                 spec->num_mixers++;
9474                         }
9475                 }
9476         }
9477         codec->patch_ops = alc_patch_ops;
9478         if (board_config == ALC268_AUTO)
9479                 spec->init_hook = alc268_auto_init;
9480                 
9481         return 0;
9482 }
9483
9484 /*
9485  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
9486  */
9487
9488 /*
9489  * set the path ways for 2 channel output
9490  * need to set the codec line out and mic 1 pin widgets to inputs
9491  */
9492 static struct hda_verb alc861_threestack_ch2_init[] = {
9493         /* set pin widget 1Ah (line in) for input */
9494         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9495         /* set pin widget 18h (mic1/2) for input, for mic also enable
9496          * the vref
9497          */
9498         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9499
9500         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9501 #if 0
9502         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9503         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9504 #endif
9505         { } /* end */
9506 };
9507 /*
9508  * 6ch mode
9509  * need to set the codec line out and mic 1 pin widgets to outputs
9510  */
9511 static struct hda_verb alc861_threestack_ch6_init[] = {
9512         /* set pin widget 1Ah (line in) for output (Back Surround)*/
9513         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9514         /* set pin widget 18h (mic1) for output (CLFE)*/
9515         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9516
9517         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9518         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9519
9520         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9521 #if 0
9522         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9523         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9524 #endif
9525         { } /* end */
9526 };
9527
9528 static struct hda_channel_mode alc861_threestack_modes[2] = {
9529         { 2, alc861_threestack_ch2_init },
9530         { 6, alc861_threestack_ch6_init },
9531 };
9532 /* Set mic1 as input and unmute the mixer */
9533 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
9534         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9535         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9536         { } /* end */
9537 };
9538 /* Set mic1 as output and mute mixer */
9539 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
9540         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9541         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9542         { } /* end */
9543 };
9544
9545 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
9546         { 2, alc861_uniwill_m31_ch2_init },
9547         { 4, alc861_uniwill_m31_ch4_init },
9548 };
9549
9550 /* Set mic1 and line-in as input and unmute the mixer */
9551 static struct hda_verb alc861_asus_ch2_init[] = {
9552         /* set pin widget 1Ah (line in) for input */
9553         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9554         /* set pin widget 18h (mic1/2) for input, for mic also enable
9555          * the vref
9556          */
9557         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9558
9559         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9560 #if 0
9561         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9562         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9563 #endif
9564         { } /* end */
9565 };
9566 /* Set mic1 nad line-in as output and mute mixer */
9567 static struct hda_verb alc861_asus_ch6_init[] = {
9568         /* set pin widget 1Ah (line in) for output (Back Surround)*/
9569         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9570         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9571         /* set pin widget 18h (mic1) for output (CLFE)*/
9572         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9573         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9574         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9575         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9576
9577         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9578 #if 0
9579         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9580         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9581 #endif
9582         { } /* end */
9583 };
9584
9585 static struct hda_channel_mode alc861_asus_modes[2] = {
9586         { 2, alc861_asus_ch2_init },
9587         { 6, alc861_asus_ch6_init },
9588 };
9589
9590 /* patch-ALC861 */
9591
9592 static struct snd_kcontrol_new alc861_base_mixer[] = {
9593         /* output mixer control */
9594         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9595         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9596         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9597         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9598         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9599
9600         /*Input mixer control */
9601         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9602            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9603         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9604         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9605         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9606         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9607         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9608         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9609         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9610         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9611
9612         /* Capture mixer control */
9613         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9614         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9615         {
9616                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9617                 .name = "Capture Source",
9618                 .count = 1,
9619                 .info = alc_mux_enum_info,
9620                 .get = alc_mux_enum_get,
9621                 .put = alc_mux_enum_put,
9622         },
9623         { } /* end */
9624 };
9625
9626 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
9627         /* output mixer control */
9628         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9629         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9630         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9631         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9632         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9633
9634         /* Input mixer control */
9635         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9636            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9637         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9638         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9639         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9640         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9641         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9642         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9643         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9644         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9645
9646         /* Capture mixer control */
9647         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9648         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9649         {
9650                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9651                 .name = "Capture Source",
9652                 .count = 1,
9653                 .info = alc_mux_enum_info,
9654                 .get = alc_mux_enum_get,
9655                 .put = alc_mux_enum_put,
9656         },
9657         {
9658                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9659                 .name = "Channel Mode",
9660                 .info = alc_ch_mode_info,
9661                 .get = alc_ch_mode_get,
9662                 .put = alc_ch_mode_put,
9663                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
9664         },
9665         { } /* end */
9666 };
9667
9668 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
9669         /* output mixer control */
9670         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9671         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9672         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9673         
9674         /*Capture mixer control */
9675         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9676         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9677         {
9678                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9679                 .name = "Capture Source",
9680                 .count = 1,
9681                 .info = alc_mux_enum_info,
9682                 .get = alc_mux_enum_get,
9683                 .put = alc_mux_enum_put,
9684         },
9685
9686         { } /* end */
9687 };
9688
9689 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
9690         /* output mixer control */
9691         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9692         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9693         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9694         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9695         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9696
9697         /* Input mixer control */
9698         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9699            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9700         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9701         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9702         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9703         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9704         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9705         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9706         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9707         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9708
9709         /* Capture mixer control */
9710         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9711         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9712         {
9713                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9714                 .name = "Capture Source",
9715                 .count = 1,
9716                 .info = alc_mux_enum_info,
9717                 .get = alc_mux_enum_get,
9718                 .put = alc_mux_enum_put,
9719         },
9720         {
9721                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9722                 .name = "Channel Mode",
9723                 .info = alc_ch_mode_info,
9724                 .get = alc_ch_mode_get,
9725                 .put = alc_ch_mode_put,
9726                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
9727         },
9728         { } /* end */
9729 };
9730
9731 static struct snd_kcontrol_new alc861_asus_mixer[] = {
9732         /* output mixer control */
9733         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9734         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9735         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9736         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9737         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9738
9739         /* Input mixer control */
9740         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9741         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9742         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9743         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9744         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9745         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9746         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9747         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9748         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9749         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
9750
9751         /* Capture mixer control */
9752         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9753         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9754         {
9755                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9756                 .name = "Capture Source",
9757                 .count = 1,
9758                 .info = alc_mux_enum_info,
9759                 .get = alc_mux_enum_get,
9760                 .put = alc_mux_enum_put,
9761         },
9762         {
9763                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9764                 .name = "Channel Mode",
9765                 .info = alc_ch_mode_info,
9766                 .get = alc_ch_mode_get,
9767                 .put = alc_ch_mode_put,
9768                 .private_value = ARRAY_SIZE(alc861_asus_modes),
9769         },
9770         { }
9771 };
9772
9773 /* additional mixer */
9774 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
9775         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9776         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9777         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
9778         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
9779         { }
9780 };
9781
9782 /*
9783  * generic initialization of ADC, input mixers and output mixers
9784  */
9785 static struct hda_verb alc861_base_init_verbs[] = {
9786         /*
9787          * Unmute ADC0 and set the default input to mic-in
9788          */
9789         /* port-A for surround (rear panel) */
9790         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9791         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
9792         /* port-B for mic-in (rear panel) with vref */
9793         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9794         /* port-C for line-in (rear panel) */
9795         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9796         /* port-D for Front */
9797         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9798         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9799         /* port-E for HP out (front panel) */
9800         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9801         /* route front PCM to HP */
9802         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9803         /* port-F for mic-in (front panel) with vref */
9804         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9805         /* port-G for CLFE (rear panel) */
9806         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9807         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9808         /* port-H for side (rear panel) */
9809         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9810         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
9811         /* CD-in */
9812         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9813         /* route front mic to ADC1*/
9814         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9815         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9816         
9817         /* Unmute DAC0~3 & spdif out*/
9818         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9819         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9820         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9821         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9822         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9823         
9824         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9825         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9826         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9827         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9828         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9829         
9830         /* Unmute Stereo Mixer 15 */
9831         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9832         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9833         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9834         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9835
9836         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9837         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9838         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9839         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9840         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9841         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9842         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9843         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9844         /* hp used DAC 3 (Front) */
9845         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9846         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9847
9848         { }
9849 };
9850
9851 static struct hda_verb alc861_threestack_init_verbs[] = {
9852         /*
9853          * Unmute ADC0 and set the default input to mic-in
9854          */
9855         /* port-A for surround (rear panel) */
9856         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9857         /* port-B for mic-in (rear panel) with vref */
9858         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9859         /* port-C for line-in (rear panel) */
9860         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9861         /* port-D for Front */
9862         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9863         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9864         /* port-E for HP out (front panel) */
9865         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9866         /* route front PCM to HP */
9867         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9868         /* port-F for mic-in (front panel) with vref */
9869         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9870         /* port-G for CLFE (rear panel) */
9871         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9872         /* port-H for side (rear panel) */
9873         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9874         /* CD-in */
9875         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9876         /* route front mic to ADC1*/
9877         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9878         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9879         /* Unmute DAC0~3 & spdif out*/
9880         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9881         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9882         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9883         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9884         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9885         
9886         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9887         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9888         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9889         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9890         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9891         
9892         /* Unmute Stereo Mixer 15 */
9893         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9894         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9895         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9896         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9897
9898         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9899         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9900         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9901         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9902         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9903         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9904         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9905         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9906         /* hp used DAC 3 (Front) */
9907         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9908         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9909         { }
9910 };
9911
9912 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9913         /*
9914          * Unmute ADC0 and set the default input to mic-in
9915          */
9916         /* port-A for surround (rear panel) */
9917         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9918         /* port-B for mic-in (rear panel) with vref */
9919         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9920         /* port-C for line-in (rear panel) */
9921         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9922         /* port-D for Front */
9923         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9924         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9925         /* port-E for HP out (front panel) */
9926         /* this has to be set to VREF80 */
9927         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9928         /* route front PCM to HP */
9929         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9930         /* port-F for mic-in (front panel) with vref */
9931         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9932         /* port-G for CLFE (rear panel) */
9933         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9934         /* port-H for side (rear panel) */
9935         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9936         /* CD-in */
9937         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9938         /* route front mic to ADC1*/
9939         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9940         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9941         /* Unmute DAC0~3 & spdif out*/
9942         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9943         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9944         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9945         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9946         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9947         
9948         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9949         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9950         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9951         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9952         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9953         
9954         /* Unmute Stereo Mixer 15 */
9955         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9956         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9957         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9958         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9959
9960         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9961         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9962         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9963         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9964         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9965         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9966         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9967         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9968         /* hp used DAC 3 (Front) */
9969         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9970         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9971         { }
9972 };
9973
9974 static struct hda_verb alc861_asus_init_verbs[] = {
9975         /*
9976          * Unmute ADC0 and set the default input to mic-in
9977          */
9978         /* port-A for surround (rear panel)
9979          * according to codec#0 this is the HP jack
9980          */
9981         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9982         /* route front PCM to HP */
9983         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9984         /* port-B for mic-in (rear panel) with vref */
9985         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9986         /* port-C for line-in (rear panel) */
9987         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9988         /* port-D for Front */
9989         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9990         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9991         /* port-E for HP out (front panel) */
9992         /* this has to be set to VREF80 */
9993         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9994         /* route front PCM to HP */
9995         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9996         /* port-F for mic-in (front panel) with vref */
9997         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9998         /* port-G for CLFE (rear panel) */
9999         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10000         /* port-H for side (rear panel) */
10001         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10002         /* CD-in */
10003         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10004         /* route front mic to ADC1*/
10005         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10006         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10007         /* Unmute DAC0~3 & spdif out*/
10008         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10009         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10010         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10011         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10012         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10013         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10014         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10015         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10016         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10017         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10018         
10019         /* Unmute Stereo Mixer 15 */
10020         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10021         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10022         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10023         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10024
10025         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10026         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10027         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10028         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10029         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10030         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10031         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10032         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10033         /* hp used DAC 3 (Front) */
10034         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10035         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10036         { }
10037 };
10038
10039 /* additional init verbs for ASUS laptops */
10040 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10041         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10042         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10043         { }
10044 };
10045
10046 /*
10047  * generic initialization of ADC, input mixers and output mixers
10048  */
10049 static struct hda_verb alc861_auto_init_verbs[] = {
10050         /*
10051          * Unmute ADC0 and set the default input to mic-in
10052          */
10053         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
10054         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10055         
10056         /* Unmute DAC0~3 & spdif out*/
10057         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10058         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10059         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10060         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10061         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10062         
10063         /* Unmute Mixer 14 (mic) 1c (Line in)*/
10064         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10065         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10066         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10067         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10068         
10069         /* Unmute Stereo Mixer 15 */
10070         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10071         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10072         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10073         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10074
10075         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10076         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10077         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10078         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10079         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10080         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10081         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10082         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10083
10084         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10085         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10086         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10087         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10088         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10089         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10090         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10091         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10092
10093         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
10094
10095         { }
10096 };
10097
10098 static struct hda_verb alc861_toshiba_init_verbs[] = {
10099         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10100
10101         { }
10102 };
10103
10104 /* toggle speaker-output according to the hp-jack state */
10105 static void alc861_toshiba_automute(struct hda_codec *codec)
10106 {
10107         unsigned int present;
10108
10109         present = snd_hda_codec_read(codec, 0x0f, 0,
10110                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10111         snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10112                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10113         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10114                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
10115 }
10116
10117 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10118                                        unsigned int res)
10119 {
10120         if ((res >> 26) == ALC880_HP_EVENT)
10121                 alc861_toshiba_automute(codec);
10122 }
10123
10124 /* pcm configuration: identiacal with ALC880 */
10125 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
10126 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
10127 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
10128 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
10129
10130
10131 #define ALC861_DIGOUT_NID       0x07
10132
10133 static struct hda_channel_mode alc861_8ch_modes[1] = {
10134         { 8, NULL }
10135 };
10136
10137 static hda_nid_t alc861_dac_nids[4] = {
10138         /* front, surround, clfe, side */
10139         0x03, 0x06, 0x05, 0x04
10140 };
10141
10142 static hda_nid_t alc660_dac_nids[3] = {
10143         /* front, clfe, surround */
10144         0x03, 0x05, 0x06
10145 };
10146
10147 static hda_nid_t alc861_adc_nids[1] = {
10148         /* ADC0-2 */
10149         0x08,
10150 };
10151
10152 static struct hda_input_mux alc861_capture_source = {
10153         .num_items = 5,
10154         .items = {
10155                 { "Mic", 0x0 },
10156                 { "Front Mic", 0x3 },
10157                 { "Line", 0x1 },
10158                 { "CD", 0x4 },
10159                 { "Mixer", 0x5 },
10160         },
10161 };
10162
10163 /* fill in the dac_nids table from the parsed pin configuration */
10164 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10165                                      const struct auto_pin_cfg *cfg)
10166 {
10167         int i;
10168         hda_nid_t nid;
10169
10170         spec->multiout.dac_nids = spec->private_dac_nids;
10171         for (i = 0; i < cfg->line_outs; i++) {
10172                 nid = cfg->line_out_pins[i];
10173                 if (nid) {
10174                         if (i >= ARRAY_SIZE(alc861_dac_nids))
10175                                 continue;
10176                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10177                 }
10178         }
10179         spec->multiout.num_dacs = cfg->line_outs;
10180         return 0;
10181 }
10182
10183 /* add playback controls from the parsed DAC table */
10184 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10185                                              const struct auto_pin_cfg *cfg)
10186 {
10187         char name[32];
10188         static const char *chname[4] = {
10189                 "Front", "Surround", NULL /*CLFE*/, "Side"
10190         };
10191         hda_nid_t nid;
10192         int i, idx, err;
10193
10194         for (i = 0; i < cfg->line_outs; i++) {
10195                 nid = spec->multiout.dac_nids[i];
10196                 if (!nid)
10197                         continue;
10198                 if (nid == 0x05) {
10199                         /* Center/LFE */
10200                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10201                                           "Center Playback Switch",
10202                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10203                                                               HDA_OUTPUT));
10204                         if (err < 0)
10205                                 return err;
10206                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10207                                           "LFE Playback Switch",
10208                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10209                                                               HDA_OUTPUT));
10210                         if (err < 0)
10211                                 return err;
10212                 } else {
10213                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10214                              idx++)
10215                                 if (nid == alc861_dac_nids[idx])
10216                                         break;
10217                         sprintf(name, "%s Playback Switch", chname[idx]);
10218                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10219                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10220                                                               HDA_OUTPUT));
10221                         if (err < 0)
10222                                 return err;
10223                 }
10224         }
10225         return 0;
10226 }
10227
10228 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10229 {
10230         int err;
10231         hda_nid_t nid;
10232
10233         if (!pin)
10234                 return 0;
10235
10236         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10237                 nid = 0x03;
10238                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10239                                   "Headphone Playback Switch",
10240                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10241                 if (err < 0)
10242                         return err;
10243                 spec->multiout.hp_nid = nid;
10244         }
10245         return 0;
10246 }
10247
10248 /* create playback/capture controls for input pins */
10249 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10250                                                 const struct auto_pin_cfg *cfg)
10251 {
10252         struct hda_input_mux *imux = &spec->private_imux;
10253         int i, err, idx, idx1;
10254
10255         for (i = 0; i < AUTO_PIN_LAST; i++) {
10256                 switch (cfg->input_pins[i]) {
10257                 case 0x0c:
10258                         idx1 = 1;
10259                         idx = 2;        /* Line In */
10260                         break;
10261                 case 0x0f:
10262                         idx1 = 2;
10263                         idx = 2;        /* Line In */
10264                         break;
10265                 case 0x0d:
10266                         idx1 = 0;
10267                         idx = 1;        /* Mic In */
10268                         break;
10269                 case 0x10:
10270                         idx1 = 3;
10271                         idx = 1;        /* Mic In */
10272                         break;
10273                 case 0x11:
10274                         idx1 = 4;
10275                         idx = 0;        /* CD */
10276                         break;
10277                 default:
10278                         continue;
10279                 }
10280
10281                 err = new_analog_input(spec, cfg->input_pins[i],
10282                                        auto_pin_cfg_labels[i], idx, 0x15);
10283                 if (err < 0)
10284                         return err;
10285
10286                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10287                 imux->items[imux->num_items].index = idx1;
10288                 imux->num_items++;
10289         }
10290         return 0;
10291 }
10292
10293 static struct snd_kcontrol_new alc861_capture_mixer[] = {
10294         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10295         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10296
10297         {
10298                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10299                 /* The multiple "Capture Source" controls confuse alsamixer
10300                  * So call somewhat different..
10301                  *FIXME: the controls appear in the "playback" view!
10302                  */
10303                 /* .name = "Capture Source", */
10304                 .name = "Input Source",
10305                 .count = 1,
10306                 .info = alc_mux_enum_info,
10307                 .get = alc_mux_enum_get,
10308                 .put = alc_mux_enum_put,
10309         },
10310         { } /* end */
10311 };
10312
10313 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10314                                               hda_nid_t nid,
10315                                               int pin_type, int dac_idx)
10316 {
10317         /* set as output */
10318
10319         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10320                             pin_type);
10321         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10322                             AMP_OUT_UNMUTE);
10323
10324 }
10325
10326 static void alc861_auto_init_multi_out(struct hda_codec *codec)
10327 {
10328         struct alc_spec *spec = codec->spec;
10329         int i;
10330
10331         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
10332         for (i = 0; i < spec->autocfg.line_outs; i++) {
10333                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10334                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10335                 if (nid)
10336                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
10337                                                           spec->multiout.dac_nids[i]);
10338         }
10339 }
10340
10341 static void alc861_auto_init_hp_out(struct hda_codec *codec)
10342 {
10343         struct alc_spec *spec = codec->spec;
10344         hda_nid_t pin;
10345
10346         pin = spec->autocfg.hp_pins[0];
10347         if (pin) /* connect to front */
10348                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
10349                                                   spec->multiout.dac_nids[0]);
10350 }
10351
10352 static void alc861_auto_init_analog_input(struct hda_codec *codec)
10353 {
10354         struct alc_spec *spec = codec->spec;
10355         int i;
10356
10357         for (i = 0; i < AUTO_PIN_LAST; i++) {
10358                 hda_nid_t nid = spec->autocfg.input_pins[i];
10359                 if (nid >= 0x0c && nid <= 0x11) {
10360                         snd_hda_codec_write(codec, nid, 0,
10361                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
10362                                             i <= AUTO_PIN_FRONT_MIC ?
10363                                             PIN_VREF80 : PIN_IN);
10364                 }
10365         }
10366 }
10367
10368 /* parse the BIOS configuration and set up the alc_spec */
10369 /* return 1 if successful, 0 if the proper config is not found,
10370  * or a negative error code
10371  */
10372 static int alc861_parse_auto_config(struct hda_codec *codec)
10373 {
10374         struct alc_spec *spec = codec->spec;
10375         int err;
10376         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
10377
10378         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10379                                            alc861_ignore);
10380         if (err < 0)
10381                 return err;
10382         if (!spec->autocfg.line_outs)
10383                 return 0; /* can't find valid BIOS pin config */
10384
10385         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
10386         if (err < 0)
10387                 return err;
10388         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
10389         if (err < 0)
10390                 return err;
10391         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
10392         if (err < 0)
10393                 return err;
10394         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
10395         if (err < 0)
10396                 return err;
10397
10398         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10399
10400         if (spec->autocfg.dig_out_pin)
10401                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
10402
10403         if (spec->kctl_alloc)
10404                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10405
10406         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
10407
10408         spec->num_mux_defs = 1;
10409         spec->input_mux = &spec->private_imux;
10410
10411         spec->adc_nids = alc861_adc_nids;
10412         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
10413         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
10414         spec->num_mixers++;
10415
10416         return 1;
10417 }
10418
10419 /* additional initialization for auto-configuration model */
10420 static void alc861_auto_init(struct hda_codec *codec)
10421 {
10422         alc861_auto_init_multi_out(codec);
10423         alc861_auto_init_hp_out(codec);
10424         alc861_auto_init_analog_input(codec);
10425 }
10426
10427 #ifdef CONFIG_SND_HDA_POWER_SAVE
10428 static struct hda_amp_list alc861_loopbacks[] = {
10429         { 0x15, HDA_INPUT, 0 },
10430         { 0x15, HDA_INPUT, 1 },
10431         { 0x15, HDA_INPUT, 2 },
10432         { 0x15, HDA_INPUT, 3 },
10433         { } /* end */
10434 };
10435 #endif
10436
10437
10438 /*
10439  * configuration and preset
10440  */
10441 static const char *alc861_models[ALC861_MODEL_LAST] = {
10442         [ALC861_3ST]            = "3stack",
10443         [ALC660_3ST]            = "3stack-660",
10444         [ALC861_3ST_DIG]        = "3stack-dig",
10445         [ALC861_6ST_DIG]        = "6stack-dig",
10446         [ALC861_UNIWILL_M31]    = "uniwill-m31",
10447         [ALC861_TOSHIBA]        = "toshiba",
10448         [ALC861_ASUS]           = "asus",
10449         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
10450         [ALC861_AUTO]           = "auto",
10451 };
10452
10453 static struct snd_pci_quirk alc861_cfg_tbl[] = {
10454         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
10455         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
10456         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
10457         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
10458         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
10459         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
10460         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
10461         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
10462         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
10463          *        Any other models that need this preset?
10464          */
10465         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
10466         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
10467         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
10468         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
10469         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
10470         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
10471         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
10472         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
10473         {}
10474 };
10475
10476 static struct alc_config_preset alc861_presets[] = {
10477         [ALC861_3ST] = {
10478                 .mixers = { alc861_3ST_mixer },
10479                 .init_verbs = { alc861_threestack_init_verbs },
10480                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10481                 .dac_nids = alc861_dac_nids,
10482                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10483                 .channel_mode = alc861_threestack_modes,
10484                 .need_dac_fix = 1,
10485                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10486                 .adc_nids = alc861_adc_nids,
10487                 .input_mux = &alc861_capture_source,
10488         },
10489         [ALC861_3ST_DIG] = {
10490                 .mixers = { alc861_base_mixer },
10491                 .init_verbs = { alc861_threestack_init_verbs },
10492                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10493                 .dac_nids = alc861_dac_nids,
10494                 .dig_out_nid = ALC861_DIGOUT_NID,
10495                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10496                 .channel_mode = alc861_threestack_modes,
10497                 .need_dac_fix = 1,
10498                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10499                 .adc_nids = alc861_adc_nids,
10500                 .input_mux = &alc861_capture_source,
10501         },
10502         [ALC861_6ST_DIG] = {
10503                 .mixers = { alc861_base_mixer },
10504                 .init_verbs = { alc861_base_init_verbs },
10505                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10506                 .dac_nids = alc861_dac_nids,
10507                 .dig_out_nid = ALC861_DIGOUT_NID,
10508                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
10509                 .channel_mode = alc861_8ch_modes,
10510                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10511                 .adc_nids = alc861_adc_nids,
10512                 .input_mux = &alc861_capture_source,
10513         },
10514         [ALC660_3ST] = {
10515                 .mixers = { alc861_3ST_mixer },
10516                 .init_verbs = { alc861_threestack_init_verbs },
10517                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
10518                 .dac_nids = alc660_dac_nids,
10519                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10520                 .channel_mode = alc861_threestack_modes,
10521                 .need_dac_fix = 1,
10522                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10523                 .adc_nids = alc861_adc_nids,
10524                 .input_mux = &alc861_capture_source,
10525         },
10526         [ALC861_UNIWILL_M31] = {
10527                 .mixers = { alc861_uniwill_m31_mixer },
10528                 .init_verbs = { alc861_uniwill_m31_init_verbs },
10529                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10530                 .dac_nids = alc861_dac_nids,
10531                 .dig_out_nid = ALC861_DIGOUT_NID,
10532                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
10533                 .channel_mode = alc861_uniwill_m31_modes,
10534                 .need_dac_fix = 1,
10535                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10536                 .adc_nids = alc861_adc_nids,
10537                 .input_mux = &alc861_capture_source,
10538         },
10539         [ALC861_TOSHIBA] = {
10540                 .mixers = { alc861_toshiba_mixer },
10541                 .init_verbs = { alc861_base_init_verbs,
10542                                 alc861_toshiba_init_verbs },
10543                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10544                 .dac_nids = alc861_dac_nids,
10545                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10546                 .channel_mode = alc883_3ST_2ch_modes,
10547                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10548                 .adc_nids = alc861_adc_nids,
10549                 .input_mux = &alc861_capture_source,
10550                 .unsol_event = alc861_toshiba_unsol_event,
10551                 .init_hook = alc861_toshiba_automute,
10552         },
10553         [ALC861_ASUS] = {
10554                 .mixers = { alc861_asus_mixer },
10555                 .init_verbs = { alc861_asus_init_verbs },
10556                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10557                 .dac_nids = alc861_dac_nids,
10558                 .dig_out_nid = ALC861_DIGOUT_NID,
10559                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
10560                 .channel_mode = alc861_asus_modes,
10561                 .need_dac_fix = 1,
10562                 .hp_nid = 0x06,
10563                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10564                 .adc_nids = alc861_adc_nids,
10565                 .input_mux = &alc861_capture_source,
10566         },
10567         [ALC861_ASUS_LAPTOP] = {
10568                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
10569                 .init_verbs = { alc861_asus_init_verbs,
10570                                 alc861_asus_laptop_init_verbs },
10571                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10572                 .dac_nids = alc861_dac_nids,
10573                 .dig_out_nid = ALC861_DIGOUT_NID,
10574                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10575                 .channel_mode = alc883_3ST_2ch_modes,
10576                 .need_dac_fix = 1,
10577                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10578                 .adc_nids = alc861_adc_nids,
10579                 .input_mux = &alc861_capture_source,
10580         },
10581 };
10582
10583
10584 static int patch_alc861(struct hda_codec *codec)
10585 {
10586         struct alc_spec *spec;
10587         int board_config;
10588         int err;
10589
10590         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10591         if (spec == NULL)
10592                 return -ENOMEM;
10593
10594         codec->spec = spec;
10595
10596         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
10597                                                   alc861_models,
10598                                                   alc861_cfg_tbl);
10599
10600         if (board_config < 0) {
10601                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
10602                        "trying auto-probe from BIOS...\n");
10603                 board_config = ALC861_AUTO;
10604         }
10605
10606         if (board_config == ALC861_AUTO) {
10607                 /* automatic parse from the BIOS config */
10608                 err = alc861_parse_auto_config(codec);
10609                 if (err < 0) {
10610                         alc_free(codec);
10611                         return err;
10612                 } else if (!err) {
10613                         printk(KERN_INFO
10614                                "hda_codec: Cannot set up configuration "
10615                                "from BIOS.  Using base mode...\n");
10616                    board_config = ALC861_3ST_DIG;
10617                 }
10618         }
10619
10620         if (board_config != ALC861_AUTO)
10621                 setup_preset(spec, &alc861_presets[board_config]);
10622
10623         spec->stream_name_analog = "ALC861 Analog";
10624         spec->stream_analog_playback = &alc861_pcm_analog_playback;
10625         spec->stream_analog_capture = &alc861_pcm_analog_capture;
10626
10627         spec->stream_name_digital = "ALC861 Digital";
10628         spec->stream_digital_playback = &alc861_pcm_digital_playback;
10629         spec->stream_digital_capture = &alc861_pcm_digital_capture;
10630
10631         codec->patch_ops = alc_patch_ops;
10632         if (board_config == ALC861_AUTO)
10633                 spec->init_hook = alc861_auto_init;
10634 #ifdef CONFIG_SND_HDA_POWER_SAVE
10635         if (!spec->loopback.amplist)
10636                 spec->loopback.amplist = alc861_loopbacks;
10637 #endif
10638                 
10639         return 0;
10640 }
10641
10642 /*
10643  * ALC861-VD support
10644  *
10645  * Based on ALC882
10646  *
10647  * In addition, an independent DAC
10648  */
10649 #define ALC861VD_DIGOUT_NID     0x06
10650
10651 static hda_nid_t alc861vd_dac_nids[4] = {
10652         /* front, surr, clfe, side surr */
10653         0x02, 0x03, 0x04, 0x05
10654 };
10655
10656 /* dac_nids for ALC660vd are in a different order - according to
10657  * Realtek's driver.
10658  * This should probably tesult in a different mixer for 6stack models
10659  * of ALC660vd codecs, but for now there is only 3stack mixer
10660  * - and it is the same as in 861vd.
10661  * adc_nids in ALC660vd are (is) the same as in 861vd
10662  */
10663 static hda_nid_t alc660vd_dac_nids[3] = {
10664         /* front, rear, clfe, rear_surr */
10665         0x02, 0x04, 0x03
10666 };
10667
10668 static hda_nid_t alc861vd_adc_nids[1] = {
10669         /* ADC0 */
10670         0x09,
10671 };
10672
10673 /* input MUX */
10674 /* FIXME: should be a matrix-type input source selection */
10675 static struct hda_input_mux alc861vd_capture_source = {
10676         .num_items = 4,
10677         .items = {
10678                 { "Mic", 0x0 },
10679                 { "Front Mic", 0x1 },
10680                 { "Line", 0x2 },
10681                 { "CD", 0x4 },
10682         },
10683 };
10684
10685 static struct hda_input_mux alc861vd_dallas_capture_source = {
10686         .num_items = 3,
10687         .items = {
10688                 { "Front Mic", 0x0 },
10689                 { "ATAPI Mic", 0x1 },
10690                 { "Line In", 0x5 },
10691         },
10692 };
10693
10694 static struct hda_input_mux alc861vd_hp_capture_source = {
10695         .num_items = 2,
10696         .items = {
10697                 { "Front Mic", 0x0 },
10698                 { "ATAPI Mic", 0x1 },
10699         },
10700 };
10701
10702 #define alc861vd_mux_enum_info alc_mux_enum_info
10703 #define alc861vd_mux_enum_get alc_mux_enum_get
10704
10705 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
10706                                 struct snd_ctl_elem_value *ucontrol)
10707 {
10708         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10709         struct alc_spec *spec = codec->spec;
10710         const struct hda_input_mux *imux = spec->input_mux;
10711         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10712         static hda_nid_t capture_mixers[1] = { 0x22 };
10713         hda_nid_t nid = capture_mixers[adc_idx];
10714         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10715         unsigned int i, idx;
10716
10717         idx = ucontrol->value.enumerated.item[0];
10718         if (idx >= imux->num_items)
10719                 idx = imux->num_items - 1;
10720         if (*cur_val == idx)
10721                 return 0;
10722         for (i = 0; i < imux->num_items; i++) {
10723                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10724                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10725                                          imux->items[i].index,
10726                                          HDA_AMP_MUTE, v);
10727         }
10728         *cur_val = idx;
10729         return 1;
10730 }
10731
10732 /*
10733  * 2ch mode
10734  */
10735 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
10736         { 2, NULL }
10737 };
10738
10739 /*
10740  * 6ch mode
10741  */
10742 static struct hda_verb alc861vd_6stack_ch6_init[] = {
10743         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10744         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10745         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10746         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10747         { } /* end */
10748 };
10749
10750 /*
10751  * 8ch mode
10752  */
10753 static struct hda_verb alc861vd_6stack_ch8_init[] = {
10754         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10755         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10756         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10757         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10758         { } /* end */
10759 };
10760
10761 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
10762         { 6, alc861vd_6stack_ch6_init },
10763         { 8, alc861vd_6stack_ch8_init },
10764 };
10765
10766 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
10767         {
10768                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10769                 .name = "Channel Mode",
10770                 .info = alc_ch_mode_info,
10771                 .get = alc_ch_mode_get,
10772                 .put = alc_ch_mode_put,
10773         },
10774         { } /* end */
10775 };
10776
10777 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
10778         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10779         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10780
10781         {
10782                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10783                 /* The multiple "Capture Source" controls confuse alsamixer
10784                  * So call somewhat different..
10785                  *FIXME: the controls appear in the "playback" view!
10786                  */
10787                 /* .name = "Capture Source", */
10788                 .name = "Input Source",
10789                 .count = 1,
10790                 .info = alc861vd_mux_enum_info,
10791                 .get = alc861vd_mux_enum_get,
10792                 .put = alc861vd_mux_enum_put,
10793         },
10794         { } /* end */
10795 };
10796
10797 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10798  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10799  */
10800 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
10801         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10802         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10803
10804         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10805         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
10806
10807         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
10808                                 HDA_OUTPUT),
10809         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
10810                                 HDA_OUTPUT),
10811         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10812         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
10813
10814         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
10815         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
10816
10817         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10818
10819         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10820         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10821         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10822
10823         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10824         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10825         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10826
10827         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10828         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10829
10830         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10831         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10832
10833         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10834         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10835
10836         { } /* end */
10837 };
10838
10839 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
10840         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10841         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10842
10843         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10844
10845         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10846         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10847         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10848
10849         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10850         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10851         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10852
10853         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10854         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10855
10856         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10857         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10858
10859         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10860         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10861
10862         { } /* end */
10863 };
10864
10865 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10866         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10867         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10868         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10869
10870         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10871
10872         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10873         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10874         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10875
10876         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10877         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10878         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10879
10880         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10881         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10882
10883         { } /* end */
10884 };
10885
10886 /* Pin assignment: Front=0x14, HP = 0x15,
10887  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10888  */
10889 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10890         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10891         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10892         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10893         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10894         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10895         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10896         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10897         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10898         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10899         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10900         { } /* end */
10901 };
10902
10903 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
10904  *                 Front Mic=0x18, ATAPI Mic = 0x19,
10905  */
10906 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
10907         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10908         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10909         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10910         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10911         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10912         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10913         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10914         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10915         
10916         { } /* end */
10917 };
10918
10919 /*
10920  * generic initialization of ADC, input mixers and output mixers
10921  */
10922 static struct hda_verb alc861vd_volume_init_verbs[] = {
10923         /*
10924          * Unmute ADC0 and set the default input to mic-in
10925          */
10926         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10927         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10928
10929         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10930          * the analog-loopback mixer widget
10931          */
10932         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10933         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10934         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10935         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10936         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10937         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10938
10939         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10940         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10941         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10942         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10943         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10944
10945         /*
10946          * Set up output mixers (0x02 - 0x05)
10947          */
10948         /* set vol=0 to output mixers */
10949         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10950         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10951         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10952         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10953
10954         /* set up input amps for analog loopback */
10955         /* Amp Indices: DAC = 0, mixer = 1 */
10956         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10957         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10958         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10959         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10960         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10961         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10962         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10963         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10964
10965         { }
10966 };
10967
10968 /*
10969  * 3-stack pin configuration:
10970  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10971  */
10972 static struct hda_verb alc861vd_3stack_init_verbs[] = {
10973         /*
10974          * Set pin mode and muting
10975          */
10976         /* set front pin widgets 0x14 for output */
10977         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10978         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10979         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10980
10981         /* Mic (rear) pin: input vref at 80% */
10982         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10983         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10984         /* Front Mic pin: input vref at 80% */
10985         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10986         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10987         /* Line In pin: input */
10988         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10989         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10990         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10991         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10992         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10993         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10994         /* CD pin widget for input */
10995         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10996
10997         { }
10998 };
10999
11000 /*
11001  * 6-stack pin configuration:
11002  */
11003 static struct hda_verb alc861vd_6stack_init_verbs[] = {
11004         /*
11005          * Set pin mode and muting
11006          */
11007         /* set front pin widgets 0x14 for output */
11008         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11009         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11010         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11011
11012         /* Rear Pin: output 1 (0x0d) */
11013         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11014         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11015         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11016         /* CLFE Pin: output 2 (0x0e) */
11017         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11018         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11019         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11020         /* Side Pin: output 3 (0x0f) */
11021         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11022         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11023         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11024
11025         /* Mic (rear) pin: input vref at 80% */
11026         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11027         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11028         /* Front Mic pin: input vref at 80% */
11029         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11030         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11031         /* Line In pin: input */
11032         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11033         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11034         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11035         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11036         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11037         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11038         /* CD pin widget for input */
11039         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11040
11041         { }
11042 };
11043
11044 static struct hda_verb alc861vd_eapd_verbs[] = {
11045         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11046         { }
11047 };
11048
11049 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11050         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11051         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11052         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11053         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11054         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
11055         {}
11056 };
11057
11058 /* toggle speaker-output according to the hp-jack state */
11059 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11060 {
11061         unsigned int present;
11062         unsigned char bits;
11063
11064         present = snd_hda_codec_read(codec, 0x1b, 0,
11065                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11066         bits = present ? HDA_AMP_MUTE : 0;
11067         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11068                                  HDA_AMP_MUTE, bits);
11069 }
11070
11071 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11072 {
11073         unsigned int present;
11074         unsigned char bits;
11075
11076         present = snd_hda_codec_read(codec, 0x18, 0,
11077                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11078         bits = present ? HDA_AMP_MUTE : 0;
11079         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11080                                  HDA_AMP_MUTE, bits);
11081 }
11082
11083 static void alc861vd_lenovo_automute(struct hda_codec *codec)
11084 {
11085         alc861vd_lenovo_hp_automute(codec);
11086         alc861vd_lenovo_mic_automute(codec);
11087 }
11088
11089 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11090                                         unsigned int res)
11091 {
11092         switch (res >> 26) {
11093         case ALC880_HP_EVENT:
11094                 alc861vd_lenovo_hp_automute(codec);
11095                 break;
11096         case ALC880_MIC_EVENT:
11097                 alc861vd_lenovo_mic_automute(codec);
11098                 break;
11099         }
11100 }
11101
11102 static struct hda_verb alc861vd_dallas_verbs[] = {
11103         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11104         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11105         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11106         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11107
11108         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11109         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11110         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11111         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11112         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11113         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11114         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11115         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11116         
11117         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11118         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11119         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11120         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11121         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11122         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11123         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11124         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11125
11126         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11127         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11128         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11129         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11130         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11131         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11132         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11133         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11134
11135         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11136         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11137         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11138         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11139
11140         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11141         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
11142         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11143
11144         { } /* end */
11145 };
11146
11147 /* toggle speaker-output according to the hp-jack state */
11148 static void alc861vd_dallas_automute(struct hda_codec *codec)
11149 {
11150         unsigned int present;
11151
11152         present = snd_hda_codec_read(codec, 0x15, 0,
11153                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11154         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11155                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11156 }
11157
11158 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11159 {
11160         if ((res >> 26) == ALC880_HP_EVENT)
11161                 alc861vd_dallas_automute(codec);
11162 }
11163
11164 #ifdef CONFIG_SND_HDA_POWER_SAVE
11165 #define alc861vd_loopbacks      alc880_loopbacks
11166 #endif
11167
11168 /* pcm configuration: identiacal with ALC880 */
11169 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
11170 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
11171 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
11172 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
11173
11174 /*
11175  * configuration and preset
11176  */
11177 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11178         [ALC660VD_3ST]          = "3stack-660",
11179         [ALC660VD_3ST_DIG]      = "3stack-660-digout",
11180         [ALC861VD_3ST]          = "3stack",
11181         [ALC861VD_3ST_DIG]      = "3stack-digout",
11182         [ALC861VD_6ST_DIG]      = "6stack-digout",
11183         [ALC861VD_LENOVO]       = "lenovo",
11184         [ALC861VD_DALLAS]       = "dallas",
11185         [ALC861VD_HP]           = "hp",
11186         [ALC861VD_AUTO]         = "auto",
11187 };
11188
11189 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
11190         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
11191         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
11192         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
11193         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
11194         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11195
11196         /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
11197         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
11198         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
11199         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11200         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
11201         SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
11202         SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
11203         SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
11204         SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
11205         {}
11206 };
11207
11208 static struct alc_config_preset alc861vd_presets[] = {
11209         [ALC660VD_3ST] = {
11210                 .mixers = { alc861vd_3st_mixer },
11211                 .init_verbs = { alc861vd_volume_init_verbs,
11212                                  alc861vd_3stack_init_verbs },
11213                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11214                 .dac_nids = alc660vd_dac_nids,
11215                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11216                 .adc_nids = alc861vd_adc_nids,
11217                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11218                 .channel_mode = alc861vd_3stack_2ch_modes,
11219                 .input_mux = &alc861vd_capture_source,
11220         },
11221         [ALC660VD_3ST_DIG] = {
11222                 .mixers = { alc861vd_3st_mixer },
11223                 .init_verbs = { alc861vd_volume_init_verbs,
11224                                  alc861vd_3stack_init_verbs },
11225                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11226                 .dac_nids = alc660vd_dac_nids,
11227                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11228                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11229                 .adc_nids = alc861vd_adc_nids,
11230                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11231                 .channel_mode = alc861vd_3stack_2ch_modes,
11232                 .input_mux = &alc861vd_capture_source,
11233         },
11234         [ALC861VD_3ST] = {
11235                 .mixers = { alc861vd_3st_mixer },
11236                 .init_verbs = { alc861vd_volume_init_verbs,
11237                                  alc861vd_3stack_init_verbs },
11238                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11239                 .dac_nids = alc861vd_dac_nids,
11240                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11241                 .channel_mode = alc861vd_3stack_2ch_modes,
11242                 .input_mux = &alc861vd_capture_source,
11243         },
11244         [ALC861VD_3ST_DIG] = {
11245                 .mixers = { alc861vd_3st_mixer },
11246                 .init_verbs = { alc861vd_volume_init_verbs,
11247                                  alc861vd_3stack_init_verbs },
11248                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11249                 .dac_nids = alc861vd_dac_nids,
11250                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11251                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11252                 .channel_mode = alc861vd_3stack_2ch_modes,
11253                 .input_mux = &alc861vd_capture_source,
11254         },
11255         [ALC861VD_6ST_DIG] = {
11256                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11257                 .init_verbs = { alc861vd_volume_init_verbs,
11258                                 alc861vd_6stack_init_verbs },
11259                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11260                 .dac_nids = alc861vd_dac_nids,
11261                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11262                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11263                 .channel_mode = alc861vd_6stack_modes,
11264                 .input_mux = &alc861vd_capture_source,
11265         },
11266         [ALC861VD_LENOVO] = {
11267                 .mixers = { alc861vd_lenovo_mixer },
11268                 .init_verbs = { alc861vd_volume_init_verbs,
11269                                 alc861vd_3stack_init_verbs,
11270                                 alc861vd_eapd_verbs,
11271                                 alc861vd_lenovo_unsol_verbs },
11272                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11273                 .dac_nids = alc660vd_dac_nids,
11274                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11275                 .adc_nids = alc861vd_adc_nids,
11276                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11277                 .channel_mode = alc861vd_3stack_2ch_modes,
11278                 .input_mux = &alc861vd_capture_source,
11279                 .unsol_event = alc861vd_lenovo_unsol_event,
11280                 .init_hook = alc861vd_lenovo_automute,
11281         },
11282         [ALC861VD_DALLAS] = {
11283                 .mixers = { alc861vd_dallas_mixer },
11284                 .init_verbs = { alc861vd_dallas_verbs },
11285                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11286                 .dac_nids = alc861vd_dac_nids,
11287                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11288                 .adc_nids = alc861vd_adc_nids,
11289                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11290                 .channel_mode = alc861vd_3stack_2ch_modes,
11291                 .input_mux = &alc861vd_dallas_capture_source,
11292                 .unsol_event = alc861vd_dallas_unsol_event,
11293                 .init_hook = alc861vd_dallas_automute,
11294         },
11295         [ALC861VD_HP] = {
11296                 .mixers = { alc861vd_hp_mixer },
11297                 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11298                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11299                 .dac_nids = alc861vd_dac_nids,
11300                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11301                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11302                 .adc_nids = alc861vd_adc_nids,
11303                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11304                 .channel_mode = alc861vd_3stack_2ch_modes,
11305                 .input_mux = &alc861vd_hp_capture_source,
11306                 .unsol_event = alc861vd_dallas_unsol_event,
11307                 .init_hook = alc861vd_dallas_automute,
11308         },              
11309 };
11310
11311 /*
11312  * BIOS auto configuration
11313  */
11314 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11315                                 hda_nid_t nid, int pin_type, int dac_idx)
11316 {
11317         /* set as output */
11318         snd_hda_codec_write(codec, nid, 0,
11319                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11320         snd_hda_codec_write(codec, nid, 0,
11321                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11322 }
11323
11324 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11325 {
11326         struct alc_spec *spec = codec->spec;
11327         int i;
11328
11329         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
11330         for (i = 0; i <= HDA_SIDE; i++) {
11331                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11332                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11333                 if (nid)
11334                         alc861vd_auto_set_output_and_unmute(codec, nid,
11335                                                             pin_type, i);
11336         }
11337 }
11338
11339
11340 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
11341 {
11342         struct alc_spec *spec = codec->spec;
11343         hda_nid_t pin;
11344
11345         pin = spec->autocfg.hp_pins[0];
11346         if (pin) /* connect to front and  use dac 0 */
11347                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11348 }
11349
11350 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
11351 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
11352
11353 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
11354 {
11355         struct alc_spec *spec = codec->spec;
11356         int i;
11357
11358         for (i = 0; i < AUTO_PIN_LAST; i++) {
11359                 hda_nid_t nid = spec->autocfg.input_pins[i];
11360                 if (alc861vd_is_input_pin(nid)) {
11361                         snd_hda_codec_write(codec, nid, 0,
11362                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
11363                                         i <= AUTO_PIN_FRONT_MIC ?
11364                                                         PIN_VREF80 : PIN_IN);
11365                         if (nid != ALC861VD_PIN_CD_NID)
11366                                 snd_hda_codec_write(codec, nid, 0,
11367                                                 AC_VERB_SET_AMP_GAIN_MUTE,
11368                                                 AMP_OUT_MUTE);
11369                 }
11370         }
11371 }
11372
11373 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
11374 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
11375
11376 /* add playback controls from the parsed DAC table */
11377 /* Based on ALC880 version. But ALC861VD has separate,
11378  * different NIDs for mute/unmute switch and volume control */
11379 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
11380                                              const struct auto_pin_cfg *cfg)
11381 {
11382         char name[32];
11383         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
11384         hda_nid_t nid_v, nid_s;
11385         int i, err;
11386
11387         for (i = 0; i < cfg->line_outs; i++) {
11388                 if (!spec->multiout.dac_nids[i])
11389                         continue;
11390                 nid_v = alc861vd_idx_to_mixer_vol(
11391                                 alc880_dac_to_idx(
11392                                         spec->multiout.dac_nids[i]));
11393                 nid_s = alc861vd_idx_to_mixer_switch(
11394                                 alc880_dac_to_idx(
11395                                         spec->multiout.dac_nids[i]));
11396
11397                 if (i == 2) {
11398                         /* Center/LFE */
11399                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11400                                           "Center Playback Volume",
11401                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
11402                                                               HDA_OUTPUT));
11403                         if (err < 0)
11404                                 return err;
11405                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11406                                           "LFE Playback Volume",
11407                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
11408                                                               HDA_OUTPUT));
11409                         if (err < 0)
11410                                 return err;
11411                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11412                                           "Center Playback Switch",
11413                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
11414                                                               HDA_INPUT));
11415                         if (err < 0)
11416                                 return err;
11417                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11418                                           "LFE Playback Switch",
11419                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
11420                                                               HDA_INPUT));
11421                         if (err < 0)
11422                                 return err;
11423                 } else {
11424                         sprintf(name, "%s Playback Volume", chname[i]);
11425                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11426                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
11427                                                               HDA_OUTPUT));
11428                         if (err < 0)
11429                                 return err;
11430                         sprintf(name, "%s Playback Switch", chname[i]);
11431                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11432                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
11433                                                               HDA_INPUT));
11434                         if (err < 0)
11435                                 return err;
11436                 }
11437         }
11438         return 0;
11439 }
11440
11441 /* add playback controls for speaker and HP outputs */
11442 /* Based on ALC880 version. But ALC861VD has separate,
11443  * different NIDs for mute/unmute switch and volume control */
11444 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
11445                                         hda_nid_t pin, const char *pfx)
11446 {
11447         hda_nid_t nid_v, nid_s;
11448         int err;
11449         char name[32];
11450
11451         if (!pin)
11452                 return 0;
11453
11454         if (alc880_is_fixed_pin(pin)) {
11455                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11456                 /* specify the DAC as the extra output */
11457                 if (!spec->multiout.hp_nid)
11458                         spec->multiout.hp_nid = nid_v;
11459                 else
11460                         spec->multiout.extra_out_nid[0] = nid_v;
11461                 /* control HP volume/switch on the output mixer amp */
11462                 nid_v = alc861vd_idx_to_mixer_vol(
11463                                 alc880_fixed_pin_idx(pin));
11464                 nid_s = alc861vd_idx_to_mixer_switch(
11465                                 alc880_fixed_pin_idx(pin));
11466
11467                 sprintf(name, "%s Playback Volume", pfx);
11468                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11469                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
11470                 if (err < 0)
11471                         return err;
11472                 sprintf(name, "%s Playback Switch", pfx);
11473                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11474                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
11475                 if (err < 0)
11476                         return err;
11477         } else if (alc880_is_multi_pin(pin)) {
11478                 /* set manual connection */
11479                 /* we have only a switch on HP-out PIN */
11480                 sprintf(name, "%s Playback Switch", pfx);
11481                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11482                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11483                 if (err < 0)
11484                         return err;
11485         }
11486         return 0;
11487 }
11488
11489 /* parse the BIOS configuration and set up the alc_spec
11490  * return 1 if successful, 0 if the proper config is not found,
11491  * or a negative error code
11492  * Based on ALC880 version - had to change it to override
11493  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
11494 static int alc861vd_parse_auto_config(struct hda_codec *codec)
11495 {
11496         struct alc_spec *spec = codec->spec;
11497         int err;
11498         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
11499
11500         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11501                                            alc861vd_ignore);
11502         if (err < 0)
11503                 return err;
11504         if (!spec->autocfg.line_outs)
11505                 return 0; /* can't find valid BIOS pin config */
11506
11507         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11508         if (err < 0)
11509                 return err;
11510         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
11511         if (err < 0)
11512                 return err;
11513         err = alc861vd_auto_create_extra_out(spec,
11514                                              spec->autocfg.speaker_pins[0],
11515                                              "Speaker");
11516         if (err < 0)
11517                 return err;
11518         err = alc861vd_auto_create_extra_out(spec,
11519                                              spec->autocfg.hp_pins[0],
11520                                              "Headphone");
11521         if (err < 0)
11522                 return err;
11523         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
11524         if (err < 0)
11525                 return err;
11526
11527         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11528
11529         if (spec->autocfg.dig_out_pin)
11530                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
11531
11532         if (spec->kctl_alloc)
11533                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11534
11535         spec->init_verbs[spec->num_init_verbs++]
11536                 = alc861vd_volume_init_verbs;
11537
11538         spec->num_mux_defs = 1;
11539         spec->input_mux = &spec->private_imux;
11540
11541         err = alc_auto_add_mic_boost(codec);
11542         if (err < 0)
11543                 return err;
11544
11545         return 1;
11546 }
11547
11548 /* additional initialization for auto-configuration model */
11549 static void alc861vd_auto_init(struct hda_codec *codec)
11550 {
11551         alc861vd_auto_init_multi_out(codec);
11552         alc861vd_auto_init_hp_out(codec);
11553         alc861vd_auto_init_analog_input(codec);
11554 }
11555
11556 static int patch_alc861vd(struct hda_codec *codec)
11557 {
11558         struct alc_spec *spec;
11559         int err, board_config;
11560
11561         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11562         if (spec == NULL)
11563                 return -ENOMEM;
11564
11565         codec->spec = spec;
11566
11567         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
11568                                                   alc861vd_models,
11569                                                   alc861vd_cfg_tbl);
11570
11571         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
11572                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
11573                         "ALC861VD, trying auto-probe from BIOS...\n");
11574                 board_config = ALC861VD_AUTO;
11575         }
11576
11577         if (board_config == ALC861VD_AUTO) {
11578                 /* automatic parse from the BIOS config */
11579                 err = alc861vd_parse_auto_config(codec);
11580                 if (err < 0) {
11581                         alc_free(codec);
11582                         return err;
11583                 } else if (!err) {
11584                         printk(KERN_INFO
11585                                "hda_codec: Cannot set up configuration "
11586                                "from BIOS.  Using base mode...\n");
11587                         board_config = ALC861VD_3ST;
11588                 }
11589         }
11590
11591         if (board_config != ALC861VD_AUTO)
11592                 setup_preset(spec, &alc861vd_presets[board_config]);
11593
11594         spec->stream_name_analog = "ALC861VD Analog";
11595         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
11596         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
11597
11598         spec->stream_name_digital = "ALC861VD Digital";
11599         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
11600         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
11601
11602         spec->adc_nids = alc861vd_adc_nids;
11603         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
11604
11605         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
11606         spec->num_mixers++;
11607
11608         codec->patch_ops = alc_patch_ops;
11609
11610         if (board_config == ALC861VD_AUTO)
11611                 spec->init_hook = alc861vd_auto_init;
11612 #ifdef CONFIG_SND_HDA_POWER_SAVE
11613         if (!spec->loopback.amplist)
11614                 spec->loopback.amplist = alc861vd_loopbacks;
11615 #endif
11616
11617         return 0;
11618 }
11619
11620 /*
11621  * ALC662 support
11622  *
11623  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
11624  * configuration.  Each pin widget can choose any input DACs and a mixer.
11625  * Each ADC is connected from a mixer of all inputs.  This makes possible
11626  * 6-channel independent captures.
11627  *
11628  * In addition, an independent DAC for the multi-playback (not used in this
11629  * driver yet).
11630  */
11631 #define ALC662_DIGOUT_NID       0x06
11632 #define ALC662_DIGIN_NID        0x0a
11633
11634 static hda_nid_t alc662_dac_nids[4] = {
11635         /* front, rear, clfe, rear_surr */
11636         0x02, 0x03, 0x04
11637 };
11638
11639 static hda_nid_t alc662_adc_nids[1] = {
11640         /* ADC1-2 */
11641         0x09,
11642 };
11643 /* input MUX */
11644 /* FIXME: should be a matrix-type input source selection */
11645
11646 static struct hda_input_mux alc662_capture_source = {
11647         .num_items = 4,
11648         .items = {
11649                 { "Mic", 0x0 },
11650                 { "Front Mic", 0x1 },
11651                 { "Line", 0x2 },
11652                 { "CD", 0x4 },
11653         },
11654 };
11655
11656 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
11657         .num_items = 2,
11658         .items = {
11659                 { "Mic", 0x1 },
11660                 { "Line", 0x2 },
11661         },
11662 };
11663
11664 static struct hda_input_mux alc662_eeepc_capture_source = {
11665         .num_items = 2,
11666         .items = {
11667                 { "i-Mic", 0x1 },
11668                 { "e-Mic", 0x0 },
11669         },
11670 };
11671
11672 #define alc662_mux_enum_info alc_mux_enum_info
11673 #define alc662_mux_enum_get alc_mux_enum_get
11674
11675 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
11676                                struct snd_ctl_elem_value *ucontrol)
11677 {
11678         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11679         struct alc_spec *spec = codec->spec;
11680         const struct hda_input_mux *imux = spec->input_mux;
11681         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11682         static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
11683         hda_nid_t nid = capture_mixers[adc_idx];
11684         unsigned int *cur_val = &spec->cur_mux[adc_idx];
11685         unsigned int i, idx;
11686
11687         idx = ucontrol->value.enumerated.item[0];
11688         if (idx >= imux->num_items)
11689                 idx = imux->num_items - 1;
11690         if (*cur_val == idx)
11691                 return 0;
11692         for (i = 0; i < imux->num_items; i++) {
11693                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11694                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11695                                          imux->items[i].index,
11696                                          HDA_AMP_MUTE, v);
11697         }
11698         *cur_val = idx;
11699         return 1;
11700 }
11701 /*
11702  * 2ch mode
11703  */
11704 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
11705         { 2, NULL }
11706 };
11707
11708 /*
11709  * 2ch mode
11710  */
11711 static struct hda_verb alc662_3ST_ch2_init[] = {
11712         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
11713         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11714         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
11715         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11716         { } /* end */
11717 };
11718
11719 /*
11720  * 6ch mode
11721  */
11722 static struct hda_verb alc662_3ST_ch6_init[] = {
11723         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11724         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11725         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
11726         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11727         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11728         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
11729         { } /* end */
11730 };
11731
11732 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
11733         { 2, alc662_3ST_ch2_init },
11734         { 6, alc662_3ST_ch6_init },
11735 };
11736
11737 /*
11738  * 2ch mode
11739  */
11740 static struct hda_verb alc662_sixstack_ch6_init[] = {
11741         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11742         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11743         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11744         { } /* end */
11745 };
11746
11747 /*
11748  * 6ch mode
11749  */
11750 static struct hda_verb alc662_sixstack_ch8_init[] = {
11751         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11752         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11753         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11754         { } /* end */
11755 };
11756
11757 static struct hda_channel_mode alc662_5stack_modes[2] = {
11758         { 2, alc662_sixstack_ch6_init },
11759         { 6, alc662_sixstack_ch8_init },
11760 };
11761
11762 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11763  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11764  */
11765
11766 static struct snd_kcontrol_new alc662_base_mixer[] = {
11767         /* output mixer control */
11768         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11769         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
11770         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11771         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11772         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11773         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11774         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11775         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11776         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11777
11778         /*Input mixer control */
11779         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
11780         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
11781         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
11782         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
11783         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
11784         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
11785         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
11786         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
11787
11788         /* Capture mixer control */
11789         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11790         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11791         {
11792                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11793                 .name = "Capture Source",
11794                 .count = 1,
11795                 .info = alc_mux_enum_info,
11796                 .get = alc_mux_enum_get,
11797                 .put = alc_mux_enum_put,
11798         },
11799         { } /* end */
11800 };
11801
11802 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
11803         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11804         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11805         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11806         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11807         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11808         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11809         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11810         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11811         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11812         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11813         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11814         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11815         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11816         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11817         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11818         {
11819                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11820                 /* .name = "Capture Source", */
11821                 .name = "Input Source",
11822                 .count = 1,
11823                 .info = alc662_mux_enum_info,
11824                 .get = alc662_mux_enum_get,
11825                 .put = alc662_mux_enum_put,
11826         },
11827         { } /* end */
11828 };
11829
11830 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
11831         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11832         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11833         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11834         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
11835         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11836         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11837         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11838         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11839         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11840         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11841         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11842         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11843         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11844         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11845         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11846         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11847         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11848         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11849         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11850         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11851         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11852         {
11853                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11854                 /* .name = "Capture Source", */
11855                 .name = "Input Source",
11856                 .count = 1,
11857                 .info = alc662_mux_enum_info,
11858                 .get = alc662_mux_enum_get,
11859                 .put = alc662_mux_enum_put,
11860         },
11861         { } /* end */
11862 };
11863
11864 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
11865         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11866         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11867         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11868         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
11869         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11870         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11871         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11872         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11873         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11874         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11875         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11876         {
11877                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11878                 /* .name = "Capture Source", */
11879                 .name = "Input Source",
11880                 .count = 1,
11881                 .info = alc662_mux_enum_info,
11882                 .get = alc662_mux_enum_get,
11883                 .put = alc662_mux_enum_put,
11884         },
11885         { } /* end */
11886 };
11887
11888 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
11889         HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11890
11891         HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11892         HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11893
11894         HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
11895         HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11896         HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11897
11898         HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
11899         HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11900         HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11901         { } /* end */
11902 };
11903
11904 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11905         {
11906                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11907                 .name = "Channel Mode",
11908                 .info = alc_ch_mode_info,
11909                 .get = alc_ch_mode_get,
11910                 .put = alc_ch_mode_put,
11911         },
11912         { } /* end */
11913 };
11914
11915 static struct hda_verb alc662_init_verbs[] = {
11916         /* ADC: mute amp left and right */
11917         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11918         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11919         /* Front mixer: unmute input/output amp left and right (volume = 0) */
11920
11921         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11922         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11923         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11924         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11925         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11926
11927         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11928         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11929         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11930         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11931         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11932         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11933
11934         /* Front Pin: output 0 (0x0c) */
11935         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11936         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11937
11938         /* Rear Pin: output 1 (0x0d) */
11939         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11940         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11941
11942         /* CLFE Pin: output 2 (0x0e) */
11943         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11944         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11945
11946         /* Mic (rear) pin: input vref at 80% */
11947         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11948         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11949         /* Front Mic pin: input vref at 80% */
11950         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11951         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11952         /* Line In pin: input */
11953         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11954         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11955         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11956         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11957         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11958         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11959         /* CD pin widget for input */
11960         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11961
11962         /* FIXME: use matrix-type input source selection */
11963         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11964         /* Input mixer */
11965         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11966         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11967         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11968         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11969
11970         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11971         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11972         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11973         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11974         { }
11975 };
11976
11977 static struct hda_verb alc662_sue_init_verbs[] = {
11978         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11979         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11980         {}
11981 };
11982
11983 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
11984         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11985         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11986         {}
11987 };
11988
11989 /*
11990  * generic initialization of ADC, input mixers and output mixers
11991  */
11992 static struct hda_verb alc662_auto_init_verbs[] = {
11993         /*
11994          * Unmute ADC and set the default input to mic-in
11995          */
11996         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11997         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11998
11999         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12000          * mixer widget
12001          * Note: PASD motherboards uses the Line In 2 as the input for front
12002          * panel mic (mic 2)
12003          */
12004         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12005         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12006         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12007         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12008         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12009         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12010
12011         /*
12012          * Set up output mixers (0x0c - 0x0f)
12013          */
12014         /* set vol=0 to output mixers */
12015         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12016         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12017         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12018
12019         /* set up input amps for analog loopback */
12020         /* Amp Indices: DAC = 0, mixer = 1 */
12021         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12022         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12023         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12024         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12025         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12026         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12027
12028
12029         /* FIXME: use matrix-type input source selection */
12030         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12031         /* Input mixer */
12032         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12033         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12034         { }
12035 };
12036
12037 /* capture mixer elements */
12038 static struct snd_kcontrol_new alc662_capture_mixer[] = {
12039         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12040         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12041         {
12042                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12043                 /* The multiple "Capture Source" controls confuse alsamixer
12044                  * So call somewhat different..
12045                  * FIXME: the controls appear in the "playback" view!
12046                  */
12047                 /* .name = "Capture Source", */
12048                 .name = "Input Source",
12049                 .count = 1,
12050                 .info = alc882_mux_enum_info,
12051                 .get = alc882_mux_enum_get,
12052                 .put = alc882_mux_enum_put,
12053         },
12054         { } /* end */
12055 };
12056
12057 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12058 {
12059         unsigned int present;
12060         unsigned char bits;
12061
12062         present = snd_hda_codec_read(codec, 0x14, 0,
12063                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12064         bits = present ? HDA_AMP_MUTE : 0;
12065         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12066                                  HDA_AMP_MUTE, bits);
12067 }
12068
12069 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12070 {
12071         unsigned int present;
12072         unsigned char bits;
12073
12074         present = snd_hda_codec_read(codec, 0x1b, 0,
12075                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12076         bits = present ? HDA_AMP_MUTE : 0;
12077         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12078                                  HDA_AMP_MUTE, bits);
12079         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12080                                  HDA_AMP_MUTE, bits);
12081 }
12082
12083 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12084                                            unsigned int res)
12085 {
12086         if ((res >> 26) == ALC880_HP_EVENT)
12087                 alc662_lenovo_101e_all_automute(codec);
12088         if ((res >> 26) == ALC880_FRONT_EVENT)
12089                 alc662_lenovo_101e_ispeaker_automute(codec);
12090 }
12091
12092 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12093 {
12094         unsigned int present;
12095
12096         present = snd_hda_codec_read(codec, 0x18, 0,
12097                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12098         snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12099                             0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12100         snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12101                             0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12102         snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12103                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12104         snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12105                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12106 }
12107
12108 /* unsolicited event for HP jack sensing */
12109 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12110                                      unsigned int res)
12111 {
12112         if ((res >> 26) == ALC880_HP_EVENT)
12113                 alc262_hippo1_automute( codec );
12114
12115         if ((res >> 26) == ALC880_MIC_EVENT)
12116                 alc662_eeepc_mic_automute(codec);
12117 }
12118
12119 static void alc662_eeepc_inithook(struct hda_codec *codec)
12120 {
12121         alc262_hippo1_automute( codec );
12122         alc662_eeepc_mic_automute(codec);
12123 }
12124
12125 #ifdef CONFIG_SND_HDA_POWER_SAVE
12126 #define alc662_loopbacks        alc880_loopbacks
12127 #endif
12128
12129
12130 /* pcm configuration: identiacal with ALC880 */
12131 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
12132 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
12133 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
12134 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
12135
12136 /*
12137  * configuration and preset
12138  */
12139 static const char *alc662_models[ALC662_MODEL_LAST] = {
12140         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
12141         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
12142         [ALC662_3ST_6ch]        = "3stack-6ch",
12143         [ALC662_5ST_DIG]        = "6stack-dig",
12144         [ALC662_LENOVO_101E]    = "lenovo-101e",
12145         [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
12146         [ALC662_AUTO]           = "auto",
12147 };
12148
12149 static struct snd_pci_quirk alc662_cfg_tbl[] = {
12150         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12151         SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12152         {}
12153 };
12154
12155 static struct alc_config_preset alc662_presets[] = {
12156         [ALC662_3ST_2ch_DIG] = {
12157                 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
12158                 .init_verbs = { alc662_init_verbs },
12159                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12160                 .dac_nids = alc662_dac_nids,
12161                 .dig_out_nid = ALC662_DIGOUT_NID,
12162                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12163                 .adc_nids = alc662_adc_nids,
12164                 .dig_in_nid = ALC662_DIGIN_NID,
12165                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12166                 .channel_mode = alc662_3ST_2ch_modes,
12167                 .input_mux = &alc662_capture_source,
12168         },
12169         [ALC662_3ST_6ch_DIG] = {
12170                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12171                             alc662_capture_mixer },
12172                 .init_verbs = { alc662_init_verbs },
12173                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12174                 .dac_nids = alc662_dac_nids,
12175                 .dig_out_nid = ALC662_DIGOUT_NID,
12176                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12177                 .adc_nids = alc662_adc_nids,
12178                 .dig_in_nid = ALC662_DIGIN_NID,
12179                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12180                 .channel_mode = alc662_3ST_6ch_modes,
12181                 .need_dac_fix = 1,
12182                 .input_mux = &alc662_capture_source,
12183         },
12184         [ALC662_3ST_6ch] = {
12185                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12186                             alc662_capture_mixer },
12187                 .init_verbs = { alc662_init_verbs },
12188                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12189                 .dac_nids = alc662_dac_nids,
12190                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12191                 .adc_nids = alc662_adc_nids,
12192                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12193                 .channel_mode = alc662_3ST_6ch_modes,
12194                 .need_dac_fix = 1,
12195                 .input_mux = &alc662_capture_source,
12196         },
12197         [ALC662_5ST_DIG] = {
12198                 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
12199                             alc662_capture_mixer },
12200                 .init_verbs = { alc662_init_verbs },
12201                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12202                 .dac_nids = alc662_dac_nids,
12203                 .dig_out_nid = ALC662_DIGOUT_NID,
12204                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12205                 .adc_nids = alc662_adc_nids,
12206                 .dig_in_nid = ALC662_DIGIN_NID,
12207                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12208                 .channel_mode = alc662_5stack_modes,
12209                 .input_mux = &alc662_capture_source,
12210         },
12211         [ALC662_LENOVO_101E] = {
12212                 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
12213                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12214                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12215                 .dac_nids = alc662_dac_nids,
12216                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12217                 .adc_nids = alc662_adc_nids,
12218                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12219                 .channel_mode = alc662_3ST_2ch_modes,
12220                 .input_mux = &alc662_lenovo_101e_capture_source,
12221                 .unsol_event = alc662_lenovo_101e_unsol_event,
12222                 .init_hook = alc662_lenovo_101e_all_automute,
12223         },
12224         [ALC662_ASUS_EEEPC_P701] = {
12225                 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12226                 .init_verbs = { alc662_init_verbs,
12227                                 alc662_eeepc_sue_init_verbs },
12228                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12229                 .dac_nids = alc662_dac_nids,
12230                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12231                 .adc_nids = alc662_adc_nids,
12232                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12233                 .channel_mode = alc662_3ST_2ch_modes,
12234                 .input_mux = &alc662_eeepc_capture_source,
12235                 .unsol_event = alc662_eeepc_unsol_event,
12236                 .init_hook = alc662_eeepc_inithook,
12237         },
12238
12239 };
12240
12241
12242 /*
12243  * BIOS auto configuration
12244  */
12245
12246 /* add playback controls from the parsed DAC table */
12247 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12248                                              const struct auto_pin_cfg *cfg)
12249 {
12250         char name[32];
12251         static const char *chname[4] = {
12252                 "Front", "Surround", NULL /*CLFE*/, "Side"
12253         };
12254         hda_nid_t nid;
12255         int i, err;
12256
12257         for (i = 0; i < cfg->line_outs; i++) {
12258                 if (!spec->multiout.dac_nids[i])
12259                         continue;
12260                 nid = alc880_idx_to_dac(i);
12261                 if (i == 2) {
12262                         /* Center/LFE */
12263                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
12264                                           "Center Playback Volume",
12265                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12266                                                               HDA_OUTPUT));
12267                         if (err < 0)
12268                                 return err;
12269                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
12270                                           "LFE Playback Volume",
12271                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12272                                                               HDA_OUTPUT));
12273                         if (err < 0)
12274                                 return err;
12275                         err = add_control(spec, ALC_CTL_BIND_MUTE,
12276                                           "Center Playback Switch",
12277                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12278                                                               HDA_INPUT));
12279                         if (err < 0)
12280                                 return err;
12281                         err = add_control(spec, ALC_CTL_BIND_MUTE,
12282                                           "LFE Playback Switch",
12283                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12284                                                               HDA_INPUT));
12285                         if (err < 0)
12286                                 return err;
12287                 } else {
12288                         sprintf(name, "%s Playback Volume", chname[i]);
12289                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12290                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12291                                                               HDA_OUTPUT));
12292                         if (err < 0)
12293                                 return err;
12294                         sprintf(name, "%s Playback Switch", chname[i]);
12295                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12296                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12297                                                               HDA_INPUT));
12298                         if (err < 0)
12299                                 return err;
12300                 }
12301         }
12302         return 0;
12303 }
12304
12305 /* add playback controls for speaker and HP outputs */
12306 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12307                                         const char *pfx)
12308 {
12309         hda_nid_t nid;
12310         int err;
12311         char name[32];
12312
12313         if (!pin)
12314                 return 0;
12315
12316         if (alc880_is_fixed_pin(pin)) {
12317                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12318                 /* printk("DAC nid=%x\n",nid); */
12319                 /* specify the DAC as the extra output */
12320                 if (!spec->multiout.hp_nid)
12321                         spec->multiout.hp_nid = nid;
12322                 else
12323                         spec->multiout.extra_out_nid[0] = nid;
12324                 /* control HP volume/switch on the output mixer amp */
12325                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12326                 sprintf(name, "%s Playback Volume", pfx);
12327                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12328                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12329                 if (err < 0)
12330                         return err;
12331                 sprintf(name, "%s Playback Switch", pfx);
12332                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12333                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12334                 if (err < 0)
12335                         return err;
12336         } else if (alc880_is_multi_pin(pin)) {
12337                 /* set manual connection */
12338                 /* we have only a switch on HP-out PIN */
12339                 sprintf(name, "%s Playback Switch", pfx);
12340                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12341                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12342                 if (err < 0)
12343                         return err;
12344         }
12345         return 0;
12346 }
12347
12348 /* create playback/capture controls for input pins */
12349 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12350                                                 const struct auto_pin_cfg *cfg)
12351 {
12352         struct hda_input_mux *imux = &spec->private_imux;
12353         int i, err, idx;
12354
12355         for (i = 0; i < AUTO_PIN_LAST; i++) {
12356                 if (alc880_is_input_pin(cfg->input_pins[i])) {
12357                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
12358                         err = new_analog_input(spec, cfg->input_pins[i],
12359                                                auto_pin_cfg_labels[i],
12360                                                idx, 0x0b);
12361                         if (err < 0)
12362                                 return err;
12363                         imux->items[imux->num_items].label =
12364                                 auto_pin_cfg_labels[i];
12365                         imux->items[imux->num_items].index =
12366                                 alc880_input_pin_idx(cfg->input_pins[i]);
12367                         imux->num_items++;
12368                 }
12369         }
12370         return 0;
12371 }
12372
12373 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12374                                               hda_nid_t nid, int pin_type,
12375                                               int dac_idx)
12376 {
12377         /* set as output */
12378         snd_hda_codec_write(codec, nid, 0,
12379                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12380         snd_hda_codec_write(codec, nid, 0,
12381                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12382         /* need the manual connection? */
12383         if (alc880_is_multi_pin(nid)) {
12384                 struct alc_spec *spec = codec->spec;
12385                 int idx = alc880_multi_pin_idx(nid);
12386                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
12387                                     AC_VERB_SET_CONNECT_SEL,
12388                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
12389         }
12390 }
12391
12392 static void alc662_auto_init_multi_out(struct hda_codec *codec)
12393 {
12394         struct alc_spec *spec = codec->spec;
12395         int i;
12396
12397         for (i = 0; i <= HDA_SIDE; i++) {
12398                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12399                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12400                 if (nid)
12401                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
12402                                                           i);
12403         }
12404 }
12405
12406 static void alc662_auto_init_hp_out(struct hda_codec *codec)
12407 {
12408         struct alc_spec *spec = codec->spec;
12409         hda_nid_t pin;
12410
12411         pin = spec->autocfg.hp_pins[0];
12412         if (pin) /* connect to front */
12413                 /* use dac 0 */
12414                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12415 }
12416
12417 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
12418 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
12419
12420 static void alc662_auto_init_analog_input(struct hda_codec *codec)
12421 {
12422         struct alc_spec *spec = codec->spec;
12423         int i;
12424
12425         for (i = 0; i < AUTO_PIN_LAST; i++) {
12426                 hda_nid_t nid = spec->autocfg.input_pins[i];
12427                 if (alc662_is_input_pin(nid)) {
12428                         snd_hda_codec_write(codec, nid, 0,
12429                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
12430                                             (i <= AUTO_PIN_FRONT_MIC ?
12431                                              PIN_VREF80 : PIN_IN));
12432                         if (nid != ALC662_PIN_CD_NID)
12433                                 snd_hda_codec_write(codec, nid, 0,
12434                                                     AC_VERB_SET_AMP_GAIN_MUTE,
12435                                                     AMP_OUT_MUTE);
12436                 }
12437         }
12438 }
12439
12440 static int alc662_parse_auto_config(struct hda_codec *codec)
12441 {
12442         struct alc_spec *spec = codec->spec;
12443         int err;
12444         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
12445
12446         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12447                                            alc662_ignore);
12448         if (err < 0)
12449                 return err;
12450         if (!spec->autocfg.line_outs)
12451                 return 0; /* can't find valid BIOS pin config */
12452
12453         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12454         if (err < 0)
12455                 return err;
12456         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
12457         if (err < 0)
12458                 return err;
12459         err = alc662_auto_create_extra_out(spec,
12460                                            spec->autocfg.speaker_pins[0],
12461                                            "Speaker");
12462         if (err < 0)
12463                 return err;
12464         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
12465                                            "Headphone");
12466         if (err < 0)
12467                 return err;
12468         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
12469         if (err < 0)
12470                 return err;
12471
12472         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12473
12474         if (spec->autocfg.dig_out_pin)
12475                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
12476
12477         if (spec->kctl_alloc)
12478                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12479
12480         spec->num_mux_defs = 1;
12481         spec->input_mux = &spec->private_imux;
12482         
12483         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
12484         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
12485         spec->num_mixers++;
12486         return 1;
12487 }
12488
12489 /* additional initialization for auto-configuration model */
12490 static void alc662_auto_init(struct hda_codec *codec)
12491 {
12492         alc662_auto_init_multi_out(codec);
12493         alc662_auto_init_hp_out(codec);
12494         alc662_auto_init_analog_input(codec);
12495 }
12496
12497 static int patch_alc662(struct hda_codec *codec)
12498 {
12499         struct alc_spec *spec;
12500         int err, board_config;
12501
12502         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12503         if (!spec)
12504                 return -ENOMEM;
12505
12506         codec->spec = spec;
12507
12508         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
12509                                                   alc662_models,
12510                                                   alc662_cfg_tbl);
12511         if (board_config < 0) {
12512                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
12513                        "trying auto-probe from BIOS...\n");
12514                 board_config = ALC662_AUTO;
12515         }
12516
12517         if (board_config == ALC662_AUTO) {
12518                 /* automatic parse from the BIOS config */
12519                 err = alc662_parse_auto_config(codec);
12520                 if (err < 0) {
12521                         alc_free(codec);
12522                         return err;
12523                 } else if (!err) {
12524                         printk(KERN_INFO
12525                                "hda_codec: Cannot set up configuration "
12526                                "from BIOS.  Using base mode...\n");
12527                         board_config = ALC662_3ST_2ch_DIG;
12528                 }
12529         }
12530
12531         if (board_config != ALC662_AUTO)
12532                 setup_preset(spec, &alc662_presets[board_config]);
12533
12534         spec->stream_name_analog = "ALC662 Analog";
12535         spec->stream_analog_playback = &alc662_pcm_analog_playback;
12536         spec->stream_analog_capture = &alc662_pcm_analog_capture;
12537
12538         spec->stream_name_digital = "ALC662 Digital";
12539         spec->stream_digital_playback = &alc662_pcm_digital_playback;
12540         spec->stream_digital_capture = &alc662_pcm_digital_capture;
12541
12542         if (!spec->adc_nids && spec->input_mux) {
12543                 spec->adc_nids = alc662_adc_nids;
12544                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
12545         }
12546
12547         codec->patch_ops = alc_patch_ops;
12548         if (board_config == ALC662_AUTO)
12549                 spec->init_hook = alc662_auto_init;
12550 #ifdef CONFIG_SND_HDA_POWER_SAVE
12551         if (!spec->loopback.amplist)
12552                 spec->loopback.amplist = alc662_loopbacks;
12553 #endif
12554
12555         return 0;
12556 }
12557
12558 /*
12559  * patch entries
12560  */
12561 struct hda_codec_preset snd_hda_preset_realtek[] = {
12562         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
12563         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
12564         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
12565         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
12566           .patch = patch_alc861 },
12567         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
12568         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
12569         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
12570         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
12571           .patch = patch_alc883 },
12572         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
12573           .patch = patch_alc662 },
12574         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
12575         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
12576         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
12577         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
12578         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
12579         {} /* terminator */
12580 };