[ALSA] hda-codec - Add support for Sony UX-90s
[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_UNIWILL_DIG,
56         ALC880_UNIWILL,
57         ALC880_UNIWILL_P53,
58         ALC880_CLEVO,
59         ALC880_TCL_S700,
60         ALC880_LG,
61         ALC880_LG_LW,
62 #ifdef CONFIG_SND_DEBUG
63         ALC880_TEST,
64 #endif
65         ALC880_AUTO,
66         ALC880_MODEL_LAST /* last tag */
67 };
68
69 /* ALC260 models */
70 enum {
71         ALC260_BASIC,
72         ALC260_HP,
73         ALC260_HP_3013,
74         ALC260_FUJITSU_S702X,
75         ALC260_ACER,
76 #ifdef CONFIG_SND_DEBUG
77         ALC260_TEST,
78 #endif
79         ALC260_AUTO,
80         ALC260_MODEL_LAST /* last tag */
81 };
82
83 /* ALC262 models */
84 enum {
85         ALC262_BASIC,
86         ALC262_HIPPO,
87         ALC262_HIPPO_1,
88         ALC262_FUJITSU,
89         ALC262_HP_BPC,
90         ALC262_BENQ_ED8,
91         ALC262_AUTO,
92         ALC262_MODEL_LAST /* last tag */
93 };
94
95 /* ALC861 models */
96 enum {
97         ALC861_3ST,
98         ALC660_3ST,
99         ALC861_3ST_DIG,
100         ALC861_6ST_DIG,
101         ALC861_UNIWILL_M31,
102         ALC861_TOSHIBA,
103         ALC861_ASUS,
104         ALC861_AUTO,
105         ALC861_MODEL_LAST,
106 };
107
108 /* ALC882 models */
109 enum {
110         ALC882_3ST_DIG,
111         ALC882_6ST_DIG,
112         ALC882_ARIMA,
113         ALC882_AUTO,
114         ALC882_MODEL_LAST,
115 };
116
117 /* ALC883 models */
118 enum {
119         ALC883_3ST_2ch_DIG,
120         ALC883_3ST_6ch_DIG,
121         ALC883_3ST_6ch,
122         ALC883_6ST_DIG,
123         ALC883_TARGA_DIG,
124         ALC883_TARGA_2ch_DIG,
125         ALC888_DEMO_BOARD,
126         ALC883_ACER,
127         ALC883_MEDION,
128         ALC883_LAPTOP_EAPD,
129         ALC883_AUTO,
130         ALC883_MODEL_LAST,
131 };
132
133 /* for GPIO Poll */
134 #define GPIO_MASK       0x03
135
136 struct alc_spec {
137         /* codec parameterization */
138         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
139         unsigned int num_mixers;
140
141         const struct hda_verb *init_verbs[5];   /* initialization verbs
142                                                  * don't forget NULL
143                                                  * termination!
144                                                  */
145         unsigned int num_init_verbs;
146
147         char *stream_name_analog;       /* analog PCM stream */
148         struct hda_pcm_stream *stream_analog_playback;
149         struct hda_pcm_stream *stream_analog_capture;
150
151         char *stream_name_digital;      /* digital PCM stream */ 
152         struct hda_pcm_stream *stream_digital_playback;
153         struct hda_pcm_stream *stream_digital_capture;
154
155         /* playback */
156         struct hda_multi_out multiout;  /* playback set-up
157                                          * max_channels, dacs must be set
158                                          * dig_out_nid and hp_nid are optional
159                                          */
160
161         /* capture */
162         unsigned int num_adc_nids;
163         hda_nid_t *adc_nids;
164         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
165
166         /* capture source */
167         unsigned int num_mux_defs;
168         const struct hda_input_mux *input_mux;
169         unsigned int cur_mux[3];
170
171         /* channel model */
172         const struct hda_channel_mode *channel_mode;
173         int num_channel_mode;
174         int need_dac_fix;
175
176         /* PCM information */
177         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
178
179         /* dynamic controls, init_verbs and input_mux */
180         struct auto_pin_cfg autocfg;
181         unsigned int num_kctl_alloc, num_kctl_used;
182         struct snd_kcontrol_new *kctl_alloc;
183         struct hda_input_mux private_imux;
184         hda_nid_t private_dac_nids[5];
185
186         /* hooks */
187         void (*init_hook)(struct hda_codec *codec);
188         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
189
190         /* for pin sensing */
191         unsigned int sense_updated: 1;
192         unsigned int jack_present: 1;
193 };
194
195 /*
196  * configuration template - to be copied to the spec instance
197  */
198 struct alc_config_preset {
199         struct snd_kcontrol_new *mixers[5]; /* should be identical size
200                                              * with spec
201                                              */
202         const struct hda_verb *init_verbs[5];
203         unsigned int num_dacs;
204         hda_nid_t *dac_nids;
205         hda_nid_t dig_out_nid;          /* optional */
206         hda_nid_t hp_nid;               /* optional */
207         unsigned int num_adc_nids;
208         hda_nid_t *adc_nids;
209         hda_nid_t dig_in_nid;
210         unsigned int num_channel_mode;
211         const struct hda_channel_mode *channel_mode;
212         int need_dac_fix;
213         unsigned int num_mux_defs;
214         const struct hda_input_mux *input_mux;
215         void (*unsol_event)(struct hda_codec *, unsigned int);
216         void (*init_hook)(struct hda_codec *);
217 };
218
219
220 /*
221  * input MUX handling
222  */
223 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
224                              struct snd_ctl_elem_info *uinfo)
225 {
226         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
227         struct alc_spec *spec = codec->spec;
228         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
229         if (mux_idx >= spec->num_mux_defs)
230                 mux_idx = 0;
231         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
232 }
233
234 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
235                             struct snd_ctl_elem_value *ucontrol)
236 {
237         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
238         struct alc_spec *spec = codec->spec;
239         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
240
241         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
242         return 0;
243 }
244
245 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
246                             struct snd_ctl_elem_value *ucontrol)
247 {
248         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
249         struct alc_spec *spec = codec->spec;
250         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
251         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
252         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
253                                      spec->adc_nids[adc_idx],
254                                      &spec->cur_mux[adc_idx]);
255 }
256
257
258 /*
259  * channel mode setting
260  */
261 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
262                             struct snd_ctl_elem_info *uinfo)
263 {
264         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
265         struct alc_spec *spec = codec->spec;
266         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
267                                     spec->num_channel_mode);
268 }
269
270 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
271                            struct snd_ctl_elem_value *ucontrol)
272 {
273         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
274         struct alc_spec *spec = codec->spec;
275         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
276                                    spec->num_channel_mode,
277                                    spec->multiout.max_channels);
278 }
279
280 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
281                            struct snd_ctl_elem_value *ucontrol)
282 {
283         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
284         struct alc_spec *spec = codec->spec;
285         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
286                                       spec->num_channel_mode,
287                                       &spec->multiout.max_channels);
288         if (err >= 0 && spec->need_dac_fix)
289                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
290         return err;
291 }
292
293 /*
294  * Control the mode of pin widget settings via the mixer.  "pc" is used
295  * instead of "%" to avoid consequences of accidently treating the % as 
296  * being part of a format specifier.  Maximum allowed length of a value is
297  * 63 characters plus NULL terminator.
298  *
299  * Note: some retasking pin complexes seem to ignore requests for input
300  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
301  * are requested.  Therefore order this list so that this behaviour will not
302  * cause problems when mixer clients move through the enum sequentially.
303  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
304  * March 2006.
305  */
306 static char *alc_pin_mode_names[] = {
307         "Mic 50pc bias", "Mic 80pc bias",
308         "Line in", "Line out", "Headphone out",
309 };
310 static unsigned char alc_pin_mode_values[] = {
311         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
312 };
313 /* The control can present all 5 options, or it can limit the options based
314  * in the pin being assumed to be exclusively an input or an output pin.  In
315  * addition, "input" pins may or may not process the mic bias option
316  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
317  * accept requests for bias as of chip versions up to March 2006) and/or
318  * wiring in the computer.
319  */
320 #define ALC_PIN_DIR_IN              0x00
321 #define ALC_PIN_DIR_OUT             0x01
322 #define ALC_PIN_DIR_INOUT           0x02
323 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
324 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
325
326 /* Info about the pin modes supported by the different pin direction modes. 
327  * For each direction the minimum and maximum values are given.
328  */
329 static signed char alc_pin_mode_dir_info[5][2] = {
330         { 0, 2 },    /* ALC_PIN_DIR_IN */
331         { 3, 4 },    /* ALC_PIN_DIR_OUT */
332         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
333         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
334         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
335 };
336 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
337 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
338 #define alc_pin_mode_n_items(_dir) \
339         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
340
341 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
342                              struct snd_ctl_elem_info *uinfo)
343 {
344         unsigned int item_num = uinfo->value.enumerated.item;
345         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
346
347         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
348         uinfo->count = 1;
349         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
350
351         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
352                 item_num = alc_pin_mode_min(dir);
353         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
354         return 0;
355 }
356
357 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
358                             struct snd_ctl_elem_value *ucontrol)
359 {
360         unsigned int i;
361         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
362         hda_nid_t nid = kcontrol->private_value & 0xffff;
363         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
364         long *valp = ucontrol->value.integer.value;
365         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
366                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
367                                                  0x00);
368
369         /* Find enumerated value for current pinctl setting */
370         i = alc_pin_mode_min(dir);
371         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
372                 i++;
373         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
374         return 0;
375 }
376
377 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
378                             struct snd_ctl_elem_value *ucontrol)
379 {
380         signed int change;
381         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
382         hda_nid_t nid = kcontrol->private_value & 0xffff;
383         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
384         long val = *ucontrol->value.integer.value;
385         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
386                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
387                                                  0x00);
388
389         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 
390                 val = alc_pin_mode_min(dir);
391
392         change = pinctl != alc_pin_mode_values[val];
393         if (change) {
394                 /* Set pin mode to that requested */
395                 snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
396                                     alc_pin_mode_values[val]);
397
398                 /* Also enable the retasking pin's input/output as required 
399                  * for the requested pin mode.  Enum values of 2 or less are
400                  * input modes.
401                  *
402                  * Dynamically switching the input/output buffers probably
403                  * reduces noise slightly (particularly on input) so we'll
404                  * do it.  However, having both input and output buffers
405                  * enabled simultaneously doesn't seem to be problematic if
406                  * this turns out to be necessary in the future.
407                  */
408                 if (val <= 2) {
409                         snd_hda_codec_write(codec, nid, 0,
410                                             AC_VERB_SET_AMP_GAIN_MUTE,
411                                             AMP_OUT_MUTE);
412                         snd_hda_codec_write(codec, nid, 0,
413                                             AC_VERB_SET_AMP_GAIN_MUTE,
414                                             AMP_IN_UNMUTE(0));
415                 } else {
416                         snd_hda_codec_write(codec, nid, 0,
417                                             AC_VERB_SET_AMP_GAIN_MUTE,
418                                             AMP_IN_MUTE(0));
419                         snd_hda_codec_write(codec, nid, 0,
420                                             AC_VERB_SET_AMP_GAIN_MUTE,
421                                             AMP_OUT_UNMUTE);
422                 }
423         }
424         return change;
425 }
426
427 #define ALC_PIN_MODE(xname, nid, dir) \
428         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
429           .info = alc_pin_mode_info, \
430           .get = alc_pin_mode_get, \
431           .put = alc_pin_mode_put, \
432           .private_value = nid | (dir<<16) }
433
434 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
435  * together using a mask with more than one bit set.  This control is
436  * currently used only by the ALC260 test model.  At this stage they are not
437  * needed for any "production" models.
438  */
439 #ifdef CONFIG_SND_DEBUG
440 static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
441                               struct snd_ctl_elem_info *uinfo)
442 {
443         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
444         uinfo->count = 1;
445         uinfo->value.integer.min = 0;
446         uinfo->value.integer.max = 1;
447         return 0;
448 }                                
449 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
450                              struct snd_ctl_elem_value *ucontrol)
451 {
452         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
453         hda_nid_t nid = kcontrol->private_value & 0xffff;
454         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
455         long *valp = ucontrol->value.integer.value;
456         unsigned int val = snd_hda_codec_read(codec, nid, 0,
457                                               AC_VERB_GET_GPIO_DATA, 0x00);
458
459         *valp = (val & mask) != 0;
460         return 0;
461 }
462 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
463                              struct snd_ctl_elem_value *ucontrol)
464 {
465         signed int change;
466         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
467         hda_nid_t nid = kcontrol->private_value & 0xffff;
468         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
469         long val = *ucontrol->value.integer.value;
470         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
471                                                     AC_VERB_GET_GPIO_DATA,
472                                                     0x00);
473
474         /* Set/unset the masked GPIO bit(s) as needed */
475         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
476         if (val == 0)
477                 gpio_data &= ~mask;
478         else
479                 gpio_data |= mask;
480         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
481
482         return change;
483 }
484 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
485         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
486           .info = alc_gpio_data_info, \
487           .get = alc_gpio_data_get, \
488           .put = alc_gpio_data_put, \
489           .private_value = nid | (mask<<16) }
490 #endif   /* CONFIG_SND_DEBUG */
491
492 /* A switch control to allow the enabling of the digital IO pins on the
493  * ALC260.  This is incredibly simplistic; the intention of this control is
494  * to provide something in the test model allowing digital outputs to be
495  * identified if present.  If models are found which can utilise these
496  * outputs a more complete mixer control can be devised for those models if
497  * necessary.
498  */
499 #ifdef CONFIG_SND_DEBUG
500 static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
501                                struct snd_ctl_elem_info *uinfo)
502 {
503         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
504         uinfo->count = 1;
505         uinfo->value.integer.min = 0;
506         uinfo->value.integer.max = 1;
507         return 0;
508 }                                
509 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
510                               struct snd_ctl_elem_value *ucontrol)
511 {
512         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
513         hda_nid_t nid = kcontrol->private_value & 0xffff;
514         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
515         long *valp = ucontrol->value.integer.value;
516         unsigned int val = snd_hda_codec_read(codec, nid, 0,
517                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
518
519         *valp = (val & mask) != 0;
520         return 0;
521 }
522 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
523                               struct snd_ctl_elem_value *ucontrol)
524 {
525         signed int change;
526         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527         hda_nid_t nid = kcontrol->private_value & 0xffff;
528         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
529         long val = *ucontrol->value.integer.value;
530         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
531                                                     AC_VERB_GET_DIGI_CONVERT,
532                                                     0x00);
533
534         /* Set/unset the masked control bit(s) as needed */
535         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
536         if (val==0)
537                 ctrl_data &= ~mask;
538         else
539                 ctrl_data |= mask;
540         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
541                             ctrl_data);
542
543         return change;
544 }
545 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
546         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
547           .info = alc_spdif_ctrl_info, \
548           .get = alc_spdif_ctrl_get, \
549           .put = alc_spdif_ctrl_put, \
550           .private_value = nid | (mask<<16) }
551 #endif   /* CONFIG_SND_DEBUG */
552
553 /*
554  * set up from the preset table
555  */
556 static void setup_preset(struct alc_spec *spec,
557                          const struct alc_config_preset *preset)
558 {
559         int i;
560
561         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
562                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
563         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
564              i++)
565                 spec->init_verbs[spec->num_init_verbs++] =
566                         preset->init_verbs[i];
567         
568         spec->channel_mode = preset->channel_mode;
569         spec->num_channel_mode = preset->num_channel_mode;
570         spec->need_dac_fix = preset->need_dac_fix;
571
572         spec->multiout.max_channels = spec->channel_mode[0].channels;
573
574         spec->multiout.num_dacs = preset->num_dacs;
575         spec->multiout.dac_nids = preset->dac_nids;
576         spec->multiout.dig_out_nid = preset->dig_out_nid;
577         spec->multiout.hp_nid = preset->hp_nid;
578         
579         spec->num_mux_defs = preset->num_mux_defs;
580         if (! spec->num_mux_defs)
581                 spec->num_mux_defs = 1;
582         spec->input_mux = preset->input_mux;
583
584         spec->num_adc_nids = preset->num_adc_nids;
585         spec->adc_nids = preset->adc_nids;
586         spec->dig_in_nid = preset->dig_in_nid;
587
588         spec->unsol_event = preset->unsol_event;
589         spec->init_hook = preset->init_hook;
590 }
591
592 /*
593  * ALC880 3-stack model
594  *
595  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
596  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
597  *                 F-Mic = 0x1b, HP = 0x19
598  */
599
600 static hda_nid_t alc880_dac_nids[4] = {
601         /* front, rear, clfe, rear_surr */
602         0x02, 0x05, 0x04, 0x03
603 };
604
605 static hda_nid_t alc880_adc_nids[3] = {
606         /* ADC0-2 */
607         0x07, 0x08, 0x09,
608 };
609
610 /* The datasheet says the node 0x07 is connected from inputs,
611  * but it shows zero connection in the real implementation on some devices.
612  * Note: this is a 915GAV bug, fixed on 915GLV
613  */
614 static hda_nid_t alc880_adc_nids_alt[2] = {
615         /* ADC1-2 */
616         0x08, 0x09,
617 };
618
619 #define ALC880_DIGOUT_NID       0x06
620 #define ALC880_DIGIN_NID        0x0a
621
622 static struct hda_input_mux alc880_capture_source = {
623         .num_items = 4,
624         .items = {
625                 { "Mic", 0x0 },
626                 { "Front Mic", 0x3 },
627                 { "Line", 0x2 },
628                 { "CD", 0x4 },
629         },
630 };
631
632 /* channel source setting (2/6 channel selection for 3-stack) */
633 /* 2ch mode */
634 static struct hda_verb alc880_threestack_ch2_init[] = {
635         /* set line-in to input, mute it */
636         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
637         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
638         /* set mic-in to input vref 80%, mute it */
639         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
640         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
641         { } /* end */
642 };
643
644 /* 6ch mode */
645 static struct hda_verb alc880_threestack_ch6_init[] = {
646         /* set line-in to output, unmute it */
647         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
648         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
649         /* set mic-in to output, unmute it */
650         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
651         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
652         { } /* end */
653 };
654
655 static struct hda_channel_mode alc880_threestack_modes[2] = {
656         { 2, alc880_threestack_ch2_init },
657         { 6, alc880_threestack_ch6_init },
658 };
659
660 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
661         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
662         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
663         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
664         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
665         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
666         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
667         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
668         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
669         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
670         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
671         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
672         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
673         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
674         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
675         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
676         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
677         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
678         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
679         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
680         {
681                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
682                 .name = "Channel Mode",
683                 .info = alc_ch_mode_info,
684                 .get = alc_ch_mode_get,
685                 .put = alc_ch_mode_put,
686         },
687         { } /* end */
688 };
689
690 /* capture mixer elements */
691 static struct snd_kcontrol_new alc880_capture_mixer[] = {
692         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
693         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
694         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
695         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
696         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
697         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
698         {
699                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
700                 /* The multiple "Capture Source" controls confuse alsamixer
701                  * So call somewhat different..
702                  * FIXME: the controls appear in the "playback" view!
703                  */
704                 /* .name = "Capture Source", */
705                 .name = "Input Source",
706                 .count = 3,
707                 .info = alc_mux_enum_info,
708                 .get = alc_mux_enum_get,
709                 .put = alc_mux_enum_put,
710         },
711         { } /* end */
712 };
713
714 /* capture mixer elements (in case NID 0x07 not available) */
715 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
716         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
717         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
718         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
719         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
720         {
721                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
722                 /* The multiple "Capture Source" controls confuse alsamixer
723                  * So call somewhat different..
724                  * FIXME: the controls appear in the "playback" view!
725                  */
726                 /* .name = "Capture Source", */
727                 .name = "Input Source",
728                 .count = 2,
729                 .info = alc_mux_enum_info,
730                 .get = alc_mux_enum_get,
731                 .put = alc_mux_enum_put,
732         },
733         { } /* end */
734 };
735
736
737
738 /*
739  * ALC880 5-stack model
740  *
741  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
742  *      Side = 0x02 (0xd)
743  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
744  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
745  */
746
747 /* additional mixers to alc880_three_stack_mixer */
748 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
749         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
750         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
751         { } /* end */
752 };
753
754 /* channel source setting (6/8 channel selection for 5-stack) */
755 /* 6ch mode */
756 static struct hda_verb alc880_fivestack_ch6_init[] = {
757         /* set line-in to input, mute it */
758         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
759         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
760         { } /* end */
761 };
762
763 /* 8ch mode */
764 static struct hda_verb alc880_fivestack_ch8_init[] = {
765         /* set line-in to output, unmute it */
766         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
767         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
768         { } /* end */
769 };
770
771 static struct hda_channel_mode alc880_fivestack_modes[2] = {
772         { 6, alc880_fivestack_ch6_init },
773         { 8, alc880_fivestack_ch8_init },
774 };
775
776
777 /*
778  * ALC880 6-stack model
779  *
780  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
781  *      Side = 0x05 (0x0f)
782  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
783  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
784  */
785
786 static hda_nid_t alc880_6st_dac_nids[4] = {
787         /* front, rear, clfe, rear_surr */
788         0x02, 0x03, 0x04, 0x05
789 };      
790
791 static struct hda_input_mux alc880_6stack_capture_source = {
792         .num_items = 4,
793         .items = {
794                 { "Mic", 0x0 },
795                 { "Front Mic", 0x1 },
796                 { "Line", 0x2 },
797                 { "CD", 0x4 },
798         },
799 };
800
801 /* fixed 8-channels */
802 static struct hda_channel_mode alc880_sixstack_modes[1] = {
803         { 8, NULL },
804 };
805
806 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
807         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
808         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
809         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
810         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
811         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
812         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
813         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
814         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
815         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
816         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
817         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
818         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
819         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
820         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
821         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
822         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
823         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
824         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
825         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
826         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
827         {
828                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
829                 .name = "Channel Mode",
830                 .info = alc_ch_mode_info,
831                 .get = alc_ch_mode_get,
832                 .put = alc_ch_mode_put,
833         },
834         { } /* end */
835 };
836
837
838 /*
839  * ALC880 W810 model
840  *
841  * W810 has rear IO for:
842  * Front (DAC 02)
843  * Surround (DAC 03)
844  * Center/LFE (DAC 04)
845  * Digital out (06)
846  *
847  * The system also has a pair of internal speakers, and a headphone jack.
848  * These are both connected to Line2 on the codec, hence to DAC 02.
849  * 
850  * There is a variable resistor to control the speaker or headphone
851  * volume. This is a hardware-only device without a software API.
852  *
853  * Plugging headphones in will disable the internal speakers. This is
854  * implemented in hardware, not via the driver using jack sense. In
855  * a similar fashion, plugging into the rear socket marked "front" will
856  * disable both the speakers and headphones.
857  *
858  * For input, there's a microphone jack, and an "audio in" jack.
859  * These may not do anything useful with this driver yet, because I
860  * haven't setup any initialization verbs for these yet...
861  */
862
863 static hda_nid_t alc880_w810_dac_nids[3] = {
864         /* front, rear/surround, clfe */
865         0x02, 0x03, 0x04
866 };
867
868 /* fixed 6 channels */
869 static struct hda_channel_mode alc880_w810_modes[1] = {
870         { 6, NULL }
871 };
872
873 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
874 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
875         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
876         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
877         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
878         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
879         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
880         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
881         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
882         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
883         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
884         { } /* end */
885 };
886
887
888 /*
889  * Z710V model
890  *
891  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
892  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
893  *                 Line = 0x1a
894  */
895
896 static hda_nid_t alc880_z71v_dac_nids[1] = {
897         0x02
898 };
899 #define ALC880_Z71V_HP_DAC      0x03
900
901 /* fixed 2 channels */
902 static struct hda_channel_mode alc880_2_jack_modes[1] = {
903         { 2, NULL }
904 };
905
906 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
907         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
908         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
909         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
910         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
911         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
912         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
913         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
914         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
915         { } /* end */
916 };
917
918
919 /* FIXME! */
920 /*
921  * ALC880 F1734 model
922  *
923  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
924  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
925  */
926
927 static hda_nid_t alc880_f1734_dac_nids[1] = {
928         0x03
929 };
930 #define ALC880_F1734_HP_DAC     0x02
931
932 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
933         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
934         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
935         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
936         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
937         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
938         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
939         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
940         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
941         { } /* end */
942 };
943
944
945 /* FIXME! */
946 /*
947  * ALC880 ASUS model
948  *
949  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
950  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
951  *  Mic = 0x18, Line = 0x1a
952  */
953
954 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
955 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
956
957 static struct snd_kcontrol_new alc880_asus_mixer[] = {
958         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
959         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
960         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
961         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
962         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
963         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
964         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
965         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
966         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
967         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
968         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
969         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
970         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
971         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
972         {
973                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
974                 .name = "Channel Mode",
975                 .info = alc_ch_mode_info,
976                 .get = alc_ch_mode_get,
977                 .put = alc_ch_mode_put,
978         },
979         { } /* end */
980 };
981
982 /* FIXME! */
983 /*
984  * ALC880 ASUS W1V model
985  *
986  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
987  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
988  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
989  */
990
991 /* additional mixers to alc880_asus_mixer */
992 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
993         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
994         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
995         { } /* end */
996 };
997
998 /* additional mixers to alc880_asus_mixer */
999 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1000         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1001         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1002         { } /* end */
1003 };
1004
1005 /* TCL S700 */
1006 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1007         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1008         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1009         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1010         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1011         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1012         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1013         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1014         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1015         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1016         {
1017                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1018                 /* The multiple "Capture Source" controls confuse alsamixer
1019                  * So call somewhat different..
1020                  * FIXME: the controls appear in the "playback" view!
1021                  */
1022                 /* .name = "Capture Source", */
1023                 .name = "Input Source",
1024                 .count = 1,
1025                 .info = alc_mux_enum_info,
1026                 .get = alc_mux_enum_get,
1027                 .put = alc_mux_enum_put,
1028         },
1029         { } /* end */
1030 };
1031
1032 /* Uniwill */
1033 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1034         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1035         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1036         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1037         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1038         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1039         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1040         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1041         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1042         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1043         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1044         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1045         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1046         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1047         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1048         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1049         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1050         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1051         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1052         {
1053                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1054                 .name = "Channel Mode",
1055                 .info = alc_ch_mode_info,
1056                 .get = alc_ch_mode_get,
1057                 .put = alc_ch_mode_put,
1058         },
1059         { } /* end */
1060 };
1061
1062 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1063         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1064         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1065         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1066         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1067         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1068         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1069         { } /* end */
1070 };
1071
1072 /*
1073  * build control elements
1074  */
1075 static int alc_build_controls(struct hda_codec *codec)
1076 {
1077         struct alc_spec *spec = codec->spec;
1078         int err;
1079         int i;
1080
1081         for (i = 0; i < spec->num_mixers; i++) {
1082                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1083                 if (err < 0)
1084                         return err;
1085         }
1086
1087         if (spec->multiout.dig_out_nid) {
1088                 err = snd_hda_create_spdif_out_ctls(codec,
1089                                                     spec->multiout.dig_out_nid);
1090                 if (err < 0)
1091                         return err;
1092         }
1093         if (spec->dig_in_nid) {
1094                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1095                 if (err < 0)
1096                         return err;
1097         }
1098         return 0;
1099 }
1100
1101
1102 /*
1103  * initialize the codec volumes, etc
1104  */
1105
1106 /*
1107  * generic initialization of ADC, input mixers and output mixers
1108  */
1109 static struct hda_verb alc880_volume_init_verbs[] = {
1110         /*
1111          * Unmute ADC0-2 and set the default input to mic-in
1112          */
1113         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1114         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1115         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1116         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1117         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1118         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1119
1120         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1121          * mixer widget
1122          * Note: PASD motherboards uses the Line In 2 as the input for front
1123          * panel mic (mic 2)
1124          */
1125         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1126         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1127         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1128         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1129         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1130         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1131
1132         /*
1133          * Set up output mixers (0x0c - 0x0f)
1134          */
1135         /* set vol=0 to output mixers */
1136         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1137         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1138         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1139         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1140         /* set up input amps for analog loopback */
1141         /* Amp Indices: DAC = 0, mixer = 1 */
1142         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1143         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1144         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1145         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1146         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1147         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1148         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1149         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1150
1151         { }
1152 };
1153
1154 /*
1155  * 3-stack pin configuration:
1156  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1157  */
1158 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1159         /*
1160          * preset connection lists of input pins
1161          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1162          */
1163         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1164         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1165         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1166
1167         /*
1168          * Set pin mode and muting
1169          */
1170         /* set front pin widgets 0x14 for output */
1171         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1172         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1173         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1174         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1175         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1176         /* Mic2 (as headphone out) for HP output */
1177         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1178         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1179         /* Line In pin widget for input */
1180         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1181         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1182         /* Line2 (as front mic) pin widget for input and vref at 80% */
1183         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1184         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1185         /* CD pin widget for input */
1186         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1187
1188         { }
1189 };
1190
1191 /*
1192  * 5-stack pin configuration:
1193  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1194  * line-in/side = 0x1a, f-mic = 0x1b
1195  */
1196 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1197         /*
1198          * preset connection lists of input pins
1199          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1200          */
1201         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1202         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1203
1204         /*
1205          * Set pin mode and muting
1206          */
1207         /* set pin widgets 0x14-0x17 for output */
1208         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1209         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1210         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1211         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1212         /* unmute pins for output (no gain on this amp) */
1213         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1214         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1215         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1216         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1217
1218         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1219         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1220         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1221         /* Mic2 (as headphone out) for HP output */
1222         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1223         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1224         /* Line In pin widget for input */
1225         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1226         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1227         /* Line2 (as front mic) pin widget for input and vref at 80% */
1228         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1229         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1230         /* CD pin widget for input */
1231         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1232
1233         { }
1234 };
1235
1236 /*
1237  * W810 pin configuration:
1238  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1239  */
1240 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1241         /* hphone/speaker input selector: front DAC */
1242         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1243
1244         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1245         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1246         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1247         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1248         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1249         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1250
1251         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1252         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1253
1254         { }
1255 };
1256
1257 /*
1258  * Z71V pin configuration:
1259  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1260  */
1261 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1262         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1263         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1264         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1265         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1266
1267         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1268         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1269         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1270         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1271
1272         { }
1273 };
1274
1275 /*
1276  * 6-stack pin configuration:
1277  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1278  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1279  */
1280 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1281         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1282
1283         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1284         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1285         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1286         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1287         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1288         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1289         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1290         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1291
1292         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1293         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1294         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1295         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1296         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1297         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1298         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1299         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1300         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1301         
1302         { }
1303 };
1304
1305 /*
1306  * Uniwill pin configuration:
1307  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1308  * line = 0x1a
1309  */
1310 static struct hda_verb alc880_uniwill_init_verbs[] = {
1311         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1312
1313         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1314         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1315         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1316         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1317         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1318         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1319         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1320         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1321         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1322         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1323         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1324         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1325         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1326         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1327
1328         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1329         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1330         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1331         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1332         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1333         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1334         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1335         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1336         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1337
1338         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1339         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1340
1341         { }
1342 };
1343
1344 /*
1345 * Uniwill P53
1346 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1347  */
1348 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1349         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1350
1351         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1352         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1353         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1354         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1355         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1356         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1357         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1358         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1359         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1360         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1361         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1362         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1363
1364         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1365         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1366         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1367         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1368         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1369         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1370
1371         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1372         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1373
1374         { }
1375 };
1376
1377 /* toggle speaker-output according to the hp-jack state */
1378 static void alc880_uniwill_automute(struct hda_codec *codec)
1379 {
1380         unsigned int present;
1381
1382         present = snd_hda_codec_read(codec, 0x14, 0,
1383                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1384         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1385                                  0x80, present ? 0x80 : 0);
1386         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1387                                  0x80, present ? 0x80 : 0);
1388         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1389                                  0x80, present ? 0x80 : 0);
1390         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1391                                  0x80, present ? 0x80 : 0);
1392
1393         present = snd_hda_codec_read(codec, 0x18, 0,
1394                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1395         snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1396                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
1397 }
1398
1399 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1400                                        unsigned int res)
1401 {
1402         /* Looks like the unsol event is incompatible with the standard
1403          * definition.  4bit tag is placed at 28 bit!
1404          */
1405         if ((res >> 28) == ALC880_HP_EVENT ||
1406             (res >> 28) == ALC880_MIC_EVENT)
1407                 alc880_uniwill_automute(codec);
1408 }
1409
1410 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1411 {
1412         unsigned int present;
1413
1414         present = snd_hda_codec_read(codec, 0x14, 0,
1415                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1416
1417         snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1418                                  0x80, present ? 0x80 : 0);
1419         snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1420                                  0x80, present ? 0x80 : 0);
1421 }
1422
1423 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1424 {
1425         unsigned int present;
1426         
1427         present = snd_hda_codec_read(codec, 0x21, 0,
1428                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1429
1430         snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1431                                  0x7f, present);
1432         snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1433                                  0x7f,  present);
1434
1435         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1436                                  0x7f,  present);
1437         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1438                                  0x7f, present);
1439
1440 }
1441 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1442                                            unsigned int res)
1443 {
1444         /* Looks like the unsol event is incompatible with the standard
1445          * definition.  4bit tag is placed at 28 bit!
1446          */
1447         if ((res >> 28) == ALC880_HP_EVENT)
1448                 alc880_uniwill_p53_hp_automute(codec);
1449         if ((res >> 28) == ALC880_DCVOL_EVENT) 
1450                 alc880_uniwill_p53_dcvol_automute(codec);
1451 }
1452
1453 /* FIXME! */
1454 /*
1455  * F1734 pin configuration:
1456  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1457  */
1458 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1459         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1460         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1461         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1462         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1463
1464         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1465         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1466         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1467         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1468
1469         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1470         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1471         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1472         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1473         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1474         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1475         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1476         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1477         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1478
1479         { }
1480 };
1481
1482 /* FIXME! */
1483 /*
1484  * ASUS pin configuration:
1485  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1486  */
1487 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1488         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1489         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1490         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1491         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1492
1493         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1494         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1496         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1497         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1498         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1500         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1501
1502         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1503         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1504         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1505         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1506         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1507         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1508         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1509         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1510         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1511         
1512         { }
1513 };
1514
1515 /* Enable GPIO mask and set output */
1516 static struct hda_verb alc880_gpio1_init_verbs[] = {
1517         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1518         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1519         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1520
1521         { }
1522 };
1523
1524 /* Enable GPIO mask and set output */
1525 static struct hda_verb alc880_gpio2_init_verbs[] = {
1526         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1527         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1528         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1529
1530         { }
1531 };
1532
1533 /* Clevo m520g init */
1534 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1535         /* headphone output */
1536         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1537         /* line-out */
1538         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1539         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1540         /* Line-in */
1541         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1542         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1543         /* CD */
1544         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1545         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1546         /* Mic1 (rear panel) */
1547         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1548         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1549         /* Mic2 (front panel) */
1550         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1551         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1552         /* headphone */
1553         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1554         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1555         /* change to EAPD mode */
1556         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1557         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1558
1559         { }
1560 };
1561
1562 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1563         /* change to EAPD mode */
1564         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1565         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1566
1567         /* Headphone output */
1568         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1569         /* Front output*/
1570         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1571         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1572
1573         /* Line In pin widget for input */
1574         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1575         /* CD pin widget for input */
1576         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1577         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1578         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1579
1580         /* change to EAPD mode */
1581         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1582         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1583
1584         { }
1585 };
1586
1587 /*
1588  * LG m1 express dual
1589  *
1590  * Pin assignment:
1591  *   Rear Line-In/Out (blue): 0x14
1592  *   Build-in Mic-In: 0x15
1593  *   Speaker-out: 0x17
1594  *   HP-Out (green): 0x1b
1595  *   Mic-In/Out (red): 0x19
1596  *   SPDIF-Out: 0x1e
1597  */
1598
1599 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1600 static hda_nid_t alc880_lg_dac_nids[3] = {
1601         0x05, 0x02, 0x03
1602 };
1603
1604 /* seems analog CD is not working */
1605 static struct hda_input_mux alc880_lg_capture_source = {
1606         .num_items = 3,
1607         .items = {
1608                 { "Mic", 0x1 },
1609                 { "Line", 0x5 },
1610                 { "Internal Mic", 0x6 },
1611         },
1612 };
1613
1614 /* 2,4,6 channel modes */
1615 static struct hda_verb alc880_lg_ch2_init[] = {
1616         /* set line-in and mic-in to input */
1617         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1618         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1619         { }
1620 };
1621
1622 static struct hda_verb alc880_lg_ch4_init[] = {
1623         /* set line-in to out and mic-in to input */
1624         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1625         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1626         { }
1627 };
1628
1629 static struct hda_verb alc880_lg_ch6_init[] = {
1630         /* set line-in and mic-in to output */
1631         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1632         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1633         { }
1634 };
1635
1636 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1637         { 2, alc880_lg_ch2_init },
1638         { 4, alc880_lg_ch4_init },
1639         { 6, alc880_lg_ch6_init },
1640 };
1641
1642 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1643         /* FIXME: it's not really "master" but front channels */
1644         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1645         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1646         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1647         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1648         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1649         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1650         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1651         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1652         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1653         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1654         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1655         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1656         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1657         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1658         {
1659                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1660                 .name = "Channel Mode",
1661                 .info = alc_ch_mode_info,
1662                 .get = alc_ch_mode_get,
1663                 .put = alc_ch_mode_put,
1664         },
1665         { } /* end */
1666 };
1667
1668 static struct hda_verb alc880_lg_init_verbs[] = {
1669         /* set capture source to mic-in */
1670         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1671         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1672         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1673         /* mute all amp mixer inputs */
1674         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1675         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1676         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1677         /* line-in to input */
1678         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1679         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680         /* built-in mic */
1681         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1682         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1683         /* speaker-out */
1684         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1685         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1686         /* mic-in to input */
1687         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1688         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1689         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690         /* HP-out */
1691         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1692         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1693         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694         /* jack sense */
1695         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1696         { }
1697 };
1698
1699 /* toggle speaker-output according to the hp-jack state */
1700 static void alc880_lg_automute(struct hda_codec *codec)
1701 {
1702         unsigned int present;
1703
1704         present = snd_hda_codec_read(codec, 0x1b, 0,
1705                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1706         snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1707                                  0x80, present ? 0x80 : 0);
1708         snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1709                                  0x80, present ? 0x80 : 0);
1710 }
1711
1712 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1713 {
1714         /* Looks like the unsol event is incompatible with the standard
1715          * definition.  4bit tag is placed at 28 bit!
1716          */
1717         if ((res >> 28) == 0x01)
1718                 alc880_lg_automute(codec);
1719 }
1720
1721 /*
1722  * LG LW20
1723  *
1724  * Pin assignment:
1725  *   Speaker-out: 0x14
1726  *   Mic-In: 0x18
1727  *   Built-in Mic-In: 0x19 (?)
1728  *   HP-Out: 0x1b
1729  *   SPDIF-Out: 0x1e
1730  */
1731
1732 /* seems analog CD is not working */
1733 static struct hda_input_mux alc880_lg_lw_capture_source = {
1734         .num_items = 2,
1735         .items = {
1736                 { "Mic", 0x0 },
1737                 { "Internal Mic", 0x1 },
1738         },
1739 };
1740
1741 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1742         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1743         HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1744         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1745         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1746         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1747         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1748         { } /* end */
1749 };
1750
1751 static struct hda_verb alc880_lg_lw_init_verbs[] = {
1752         /* set capture source to mic-in */
1753         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1754         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1755         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1756         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1757         /* speaker-out */
1758         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1759         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1760         /* HP-out */
1761         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1762         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1763         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1764         /* mic-in to input */
1765         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1766         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1767         /* built-in mic */
1768         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1769         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1770         /* jack sense */
1771         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1772         { }
1773 };
1774
1775 /* toggle speaker-output according to the hp-jack state */
1776 static void alc880_lg_lw_automute(struct hda_codec *codec)
1777 {
1778         unsigned int present;
1779
1780         present = snd_hda_codec_read(codec, 0x1b, 0,
1781                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1782         snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1783                                  0x80, present ? 0x80 : 0);
1784         snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1785                                  0x80, present ? 0x80 : 0);
1786 }
1787
1788 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1789 {
1790         /* Looks like the unsol event is incompatible with the standard
1791          * definition.  4bit tag is placed at 28 bit!
1792          */
1793         if ((res >> 28) == 0x01)
1794                 alc880_lg_lw_automute(codec);
1795 }
1796
1797 /*
1798  * Common callbacks
1799  */
1800
1801 static int alc_init(struct hda_codec *codec)
1802 {
1803         struct alc_spec *spec = codec->spec;
1804         unsigned int i;
1805
1806         for (i = 0; i < spec->num_init_verbs; i++)
1807                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1808
1809         if (spec->init_hook)
1810                 spec->init_hook(codec);
1811
1812         return 0;
1813 }
1814
1815 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
1816 {
1817         struct alc_spec *spec = codec->spec;
1818
1819         if (spec->unsol_event)
1820                 spec->unsol_event(codec, res);
1821 }
1822
1823 #ifdef CONFIG_PM
1824 /*
1825  * resume
1826  */
1827 static int alc_resume(struct hda_codec *codec)
1828 {
1829         struct alc_spec *spec = codec->spec;
1830         int i;
1831
1832         alc_init(codec);
1833         for (i = 0; i < spec->num_mixers; i++)
1834                 snd_hda_resume_ctls(codec, spec->mixers[i]);
1835         if (spec->multiout.dig_out_nid)
1836                 snd_hda_resume_spdif_out(codec);
1837         if (spec->dig_in_nid)
1838                 snd_hda_resume_spdif_in(codec);
1839
1840         return 0;
1841 }
1842 #endif
1843
1844 /*
1845  * Analog playback callbacks
1846  */
1847 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
1848                                     struct hda_codec *codec,
1849                                     struct snd_pcm_substream *substream)
1850 {
1851         struct alc_spec *spec = codec->spec;
1852         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1853 }
1854
1855 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1856                                        struct hda_codec *codec,
1857                                        unsigned int stream_tag,
1858                                        unsigned int format,
1859                                        struct snd_pcm_substream *substream)
1860 {
1861         struct alc_spec *spec = codec->spec;
1862         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
1863                                                 stream_tag, format, substream);
1864 }
1865
1866 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1867                                        struct hda_codec *codec,
1868                                        struct snd_pcm_substream *substream)
1869 {
1870         struct alc_spec *spec = codec->spec;
1871         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1872 }
1873
1874 /*
1875  * Digital out
1876  */
1877 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1878                                         struct hda_codec *codec,
1879                                         struct snd_pcm_substream *substream)
1880 {
1881         struct alc_spec *spec = codec->spec;
1882         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1883 }
1884
1885 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1886                                          struct hda_codec *codec,
1887                                          struct snd_pcm_substream *substream)
1888 {
1889         struct alc_spec *spec = codec->spec;
1890         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1891 }
1892
1893 /*
1894  * Analog capture
1895  */
1896 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1897                                       struct hda_codec *codec,
1898                                       unsigned int stream_tag,
1899                                       unsigned int format,
1900                                       struct snd_pcm_substream *substream)
1901 {
1902         struct alc_spec *spec = codec->spec;
1903
1904         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1905                                    stream_tag, 0, format);
1906         return 0;
1907 }
1908
1909 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1910                                       struct hda_codec *codec,
1911                                       struct snd_pcm_substream *substream)
1912 {
1913         struct alc_spec *spec = codec->spec;
1914
1915         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1916                                    0, 0, 0);
1917         return 0;
1918 }
1919
1920
1921 /*
1922  */
1923 static struct hda_pcm_stream alc880_pcm_analog_playback = {
1924         .substreams = 1,
1925         .channels_min = 2,
1926         .channels_max = 8,
1927         /* NID is set in alc_build_pcms */
1928         .ops = {
1929                 .open = alc880_playback_pcm_open,
1930                 .prepare = alc880_playback_pcm_prepare,
1931                 .cleanup = alc880_playback_pcm_cleanup
1932         },
1933 };
1934
1935 static struct hda_pcm_stream alc880_pcm_analog_capture = {
1936         .substreams = 2,
1937         .channels_min = 2,
1938         .channels_max = 2,
1939         /* NID is set in alc_build_pcms */
1940         .ops = {
1941                 .prepare = alc880_capture_pcm_prepare,
1942                 .cleanup = alc880_capture_pcm_cleanup
1943         },
1944 };
1945
1946 static struct hda_pcm_stream alc880_pcm_digital_playback = {
1947         .substreams = 1,
1948         .channels_min = 2,
1949         .channels_max = 2,
1950         /* NID is set in alc_build_pcms */
1951         .ops = {
1952                 .open = alc880_dig_playback_pcm_open,
1953                 .close = alc880_dig_playback_pcm_close
1954         },
1955 };
1956
1957 static struct hda_pcm_stream alc880_pcm_digital_capture = {
1958         .substreams = 1,
1959         .channels_min = 2,
1960         .channels_max = 2,
1961         /* NID is set in alc_build_pcms */
1962 };
1963
1964 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
1965 static struct hda_pcm_stream alc_pcm_null_playback = {
1966         .substreams = 0,
1967         .channels_min = 0,
1968         .channels_max = 0,
1969 };
1970
1971 static int alc_build_pcms(struct hda_codec *codec)
1972 {
1973         struct alc_spec *spec = codec->spec;
1974         struct hda_pcm *info = spec->pcm_rec;
1975         int i;
1976
1977         codec->num_pcms = 1;
1978         codec->pcm_info = info;
1979
1980         info->name = spec->stream_name_analog;
1981         if (spec->stream_analog_playback) {
1982                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
1983                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1984                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
1985         }
1986         if (spec->stream_analog_capture) {
1987                 snd_assert(spec->adc_nids, return -EINVAL);
1988                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1989                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1990         }
1991
1992         if (spec->channel_mode) {
1993                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1994                 for (i = 0; i < spec->num_channel_mode; i++) {
1995                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1996                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1997                         }
1998                 }
1999         }
2000
2001         /* SPDIF for stream index #1 */
2002         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2003                 codec->num_pcms = 2;
2004                 info = spec->pcm_rec + 1;
2005                 info->name = spec->stream_name_digital;
2006                 if (spec->multiout.dig_out_nid &&
2007                     spec->stream_digital_playback) {
2008                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2009                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2010                 }
2011                 if (spec->dig_in_nid &&
2012                     spec->stream_digital_capture) {
2013                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2014                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2015                 }
2016         }
2017
2018         /* If the use of more than one ADC is requested for the current
2019          * model, configure a second analog capture-only PCM.
2020          */
2021         /* Additional Analaog capture for index #2 */
2022         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2023             spec->adc_nids) {
2024                 codec->num_pcms = 3;
2025                 info = spec->pcm_rec + 2;
2026                 info->name = spec->stream_name_analog;
2027                 /* No playback stream for second PCM */
2028                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2029                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2030                 if (spec->stream_analog_capture) {
2031                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2032                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2033                 }
2034         }
2035
2036         return 0;
2037 }
2038
2039 static void alc_free(struct hda_codec *codec)
2040 {
2041         struct alc_spec *spec = codec->spec;
2042         unsigned int i;
2043
2044         if (! spec)
2045                 return;
2046
2047         if (spec->kctl_alloc) {
2048                 for (i = 0; i < spec->num_kctl_used; i++)
2049                         kfree(spec->kctl_alloc[i].name);
2050                 kfree(spec->kctl_alloc);
2051         }
2052         kfree(spec);
2053 }
2054
2055 /*
2056  */
2057 static struct hda_codec_ops alc_patch_ops = {
2058         .build_controls = alc_build_controls,
2059         .build_pcms = alc_build_pcms,
2060         .init = alc_init,
2061         .free = alc_free,
2062         .unsol_event = alc_unsol_event,
2063 #ifdef CONFIG_PM
2064         .resume = alc_resume,
2065 #endif
2066 };
2067
2068
2069 /*
2070  * Test configuration for debugging
2071  *
2072  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2073  * enum controls.
2074  */
2075 #ifdef CONFIG_SND_DEBUG
2076 static hda_nid_t alc880_test_dac_nids[4] = {
2077         0x02, 0x03, 0x04, 0x05
2078 };
2079
2080 static struct hda_input_mux alc880_test_capture_source = {
2081         .num_items = 7,
2082         .items = {
2083                 { "In-1", 0x0 },
2084                 { "In-2", 0x1 },
2085                 { "In-3", 0x2 },
2086                 { "In-4", 0x3 },
2087                 { "CD", 0x4 },
2088                 { "Front", 0x5 },
2089                 { "Surround", 0x6 },
2090         },
2091 };
2092
2093 static struct hda_channel_mode alc880_test_modes[4] = {
2094         { 2, NULL },
2095         { 4, NULL },
2096         { 6, NULL },
2097         { 8, NULL },
2098 };
2099
2100 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2101                                  struct snd_ctl_elem_info *uinfo)
2102 {
2103         static char *texts[] = {
2104                 "N/A", "Line Out", "HP Out",
2105                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2106         };
2107         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2108         uinfo->count = 1;
2109         uinfo->value.enumerated.items = 8;
2110         if (uinfo->value.enumerated.item >= 8)
2111                 uinfo->value.enumerated.item = 7;
2112         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2113         return 0;
2114 }
2115
2116 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2117                                 struct snd_ctl_elem_value *ucontrol)
2118 {
2119         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2120         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2121         unsigned int pin_ctl, item = 0;
2122
2123         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2124                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2125         if (pin_ctl & AC_PINCTL_OUT_EN) {
2126                 if (pin_ctl & AC_PINCTL_HP_EN)
2127                         item = 2;
2128                 else
2129                         item = 1;
2130         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2131                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2132                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2133                 case AC_PINCTL_VREF_50:  item = 4; break;
2134                 case AC_PINCTL_VREF_GRD: item = 5; break;
2135                 case AC_PINCTL_VREF_80:  item = 6; break;
2136                 case AC_PINCTL_VREF_100: item = 7; break;
2137                 }
2138         }
2139         ucontrol->value.enumerated.item[0] = item;
2140         return 0;
2141 }
2142
2143 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2144                                 struct snd_ctl_elem_value *ucontrol)
2145 {
2146         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2147         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2148         static unsigned int ctls[] = {
2149                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2150                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2151                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2152                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2153                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2154                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2155         };
2156         unsigned int old_ctl, new_ctl;
2157
2158         old_ctl = snd_hda_codec_read(codec, nid, 0,
2159                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2160         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2161         if (old_ctl != new_ctl) {
2162                 snd_hda_codec_write(codec, nid, 0,
2163                                     AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2164                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2165                                     (ucontrol->value.enumerated.item[0] >= 3 ?
2166                                      0xb080 : 0xb000));
2167                 return 1;
2168         }
2169         return 0;
2170 }
2171
2172 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2173                                  struct snd_ctl_elem_info *uinfo)
2174 {
2175         static char *texts[] = {
2176                 "Front", "Surround", "CLFE", "Side"
2177         };
2178         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2179         uinfo->count = 1;
2180         uinfo->value.enumerated.items = 4;
2181         if (uinfo->value.enumerated.item >= 4)
2182                 uinfo->value.enumerated.item = 3;
2183         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2184         return 0;
2185 }
2186
2187 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2188                                 struct snd_ctl_elem_value *ucontrol)
2189 {
2190         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2191         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2192         unsigned int sel;
2193
2194         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2195         ucontrol->value.enumerated.item[0] = sel & 3;
2196         return 0;
2197 }
2198
2199 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2200                                 struct snd_ctl_elem_value *ucontrol)
2201 {
2202         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2203         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2204         unsigned int sel;
2205
2206         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2207         if (ucontrol->value.enumerated.item[0] != sel) {
2208                 sel = ucontrol->value.enumerated.item[0] & 3;
2209                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2210                 return 1;
2211         }
2212         return 0;
2213 }
2214
2215 #define PIN_CTL_TEST(xname,nid) {                       \
2216                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2217                         .name = xname,                 \
2218                         .info = alc_test_pin_ctl_info, \
2219                         .get = alc_test_pin_ctl_get,   \
2220                         .put = alc_test_pin_ctl_put,   \
2221                         .private_value = nid           \
2222                         }
2223
2224 #define PIN_SRC_TEST(xname,nid) {                       \
2225                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2226                         .name = xname,                 \
2227                         .info = alc_test_pin_src_info, \
2228                         .get = alc_test_pin_src_get,   \
2229                         .put = alc_test_pin_src_put,   \
2230                         .private_value = nid           \
2231                         }
2232
2233 static struct snd_kcontrol_new alc880_test_mixer[] = {
2234         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2235         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2236         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2237         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2238         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2239         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2240         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2241         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2242         PIN_CTL_TEST("Front Pin Mode", 0x14),
2243         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2244         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2245         PIN_CTL_TEST("Side Pin Mode", 0x17),
2246         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2247         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2248         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2249         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2250         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2251         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2252         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2253         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2254         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2255         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2256         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2257         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2258         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2259         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2260         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2261         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2262         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2263         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2264         {
2265                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2266                 .name = "Channel Mode",
2267                 .info = alc_ch_mode_info,
2268                 .get = alc_ch_mode_get,
2269                 .put = alc_ch_mode_put,
2270         },
2271         { } /* end */
2272 };
2273
2274 static struct hda_verb alc880_test_init_verbs[] = {
2275         /* Unmute inputs of 0x0c - 0x0f */
2276         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2277         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2278         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2279         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2280         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2281         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2282         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2283         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2284         /* Vol output for 0x0c-0x0f */
2285         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2286         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2287         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2288         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2289         /* Set output pins 0x14-0x17 */
2290         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2291         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2292         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2293         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2294         /* Unmute output pins 0x14-0x17 */
2295         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2296         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2297         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2298         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2299         /* Set input pins 0x18-0x1c */
2300         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2301         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2302         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2303         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2304         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2305         /* Mute input pins 0x18-0x1b */
2306         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2307         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2308         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2309         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2310         /* ADC set up */
2311         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2312         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2313         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2314         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2315         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2316         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2317         /* Analog input/passthru */
2318         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2319         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2320         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2321         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2322         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2323         { }
2324 };
2325 #endif
2326
2327 /*
2328  */
2329
2330 static struct hda_board_config alc880_cfg_tbl[] = {
2331         /* Back 3 jack, front 2 jack */
2332         { .modelname = "3stack", .config = ALC880_3ST },
2333         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
2334         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
2335         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
2336         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
2337         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
2338         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
2339         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
2340         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
2341         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
2342         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
2343         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
2344         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
2345         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
2346         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
2347         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
2348         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
2349         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
2350         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
2351         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe212, .config = ALC880_3ST },
2352         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe213, .config = ALC880_3ST },
2353         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
2354         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe234, .config = ALC880_3ST },
2355         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
2356         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
2357         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
2358         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
2359         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
2360         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
2361         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
2362         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
2363         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
2364         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
2365         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
2366         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
2367         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
2368         /* TCL S700 */
2369         { .modelname = "tcl", .config = ALC880_TCL_S700 },
2370         { .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 },
2371
2372         /* Back 3 jack, front 2 jack (Internal add Aux-In) */
2373         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
2374         { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, 
2375         { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST },
2376
2377         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
2378         { .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
2379         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
2380         { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG },
2381
2382         /* Clevo laptops */
2383         { .modelname = "clevo", .config = ALC880_CLEVO },
2384         { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520,
2385           .config = ALC880_CLEVO }, /* Clevo m520G NB */
2386         { .pci_subvendor = 0x1558, .pci_subdevice = 0x0660,
2387           .config = ALC880_CLEVO }, /* Clevo m665n */
2388
2389         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
2390         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
2391         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
2392         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
2393
2394         /* Back 5 jack, front 2 jack */
2395         { .modelname = "5stack", .config = ALC880_5ST },
2396         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
2397         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
2398         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
2399         { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
2400         { .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST },
2401
2402         /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
2403         { .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
2404         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
2405         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
2406         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
2407         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
2408         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
2409         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
2410         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
2411         { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
2412         { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
2413         { .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560,
2414           .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */
2415         /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */
2416         { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
2417         /* note subvendor = 0 below */
2418         /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */
2419
2420         { .modelname = "w810", .config = ALC880_W810 },
2421         { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
2422
2423         { .modelname = "z71v", .config = ALC880_Z71V },
2424         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
2425
2426         { .modelname = "6stack", .config = ALC880_6ST },
2427         { .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */
2428         { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST },
2429         { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
2430         { .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */
2431
2432         { .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
2433         { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
2434         { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
2435         { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
2436         { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
2437         { .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG },
2438         { .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG },
2439         { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG },
2440         { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
2441         { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
2442         { .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */
2443         { .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */
2444
2445         { .modelname = "asus", .config = ALC880_ASUS },
2446         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
2447         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
2448         { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
2449         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
2450         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG },
2451         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
2452         { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c2, .config = ALC880_ASUS_DIG }, /* Asus W6A */
2453         { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
2454         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
2455         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
2456         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
2457         { .modelname = "asus-w1v", .config = ALC880_ASUS_W1V },
2458         { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
2459         { .modelname = "asus-dig", .config = ALC880_ASUS_DIG },
2460         { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */
2461         { .modelname = "asus-dig2", .config = ALC880_ASUS_DIG2 },
2462         { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
2463
2464         { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
2465         { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
2466         { .pci_subvendor = 0x1584, .pci_subdevice = 0x9070, .config = ALC880_UNIWILL },
2467         { .pci_subvendor = 0x1734, .pci_subdevice = 0x10ac, .config = ALC880_UNIWILL },
2468         { .pci_subvendor = 0x1584, .pci_subdevice = 0x9077, .config = ALC880_UNIWILL_P53 },             
2469
2470         { .modelname = "F1734", .config = ALC880_F1734 },
2471         { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
2472         { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 },
2473
2474         { .modelname = "lg", .config = ALC880_LG },
2475         { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
2476         { .pci_subvendor = 0x1854, .pci_subdevice = 0x0068, .config = ALC880_LG },
2477
2478         { .modelname = "lg-lw", .config = ALC880_LG_LW },
2479         { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
2480         { .pci_subvendor = 0x1854, .pci_subdevice = 0x0077, .config = ALC880_LG_LW },
2481
2482 #ifdef CONFIG_SND_DEBUG
2483         { .modelname = "test", .config = ALC880_TEST },
2484 #endif
2485         { .modelname = "auto", .config = ALC880_AUTO },
2486
2487         {}
2488 };
2489
2490 /*
2491  * ALC880 codec presets
2492  */
2493 static struct alc_config_preset alc880_presets[] = {
2494         [ALC880_3ST] = {
2495                 .mixers = { alc880_three_stack_mixer },
2496                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
2497                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2498                 .dac_nids = alc880_dac_nids,
2499                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2500                 .channel_mode = alc880_threestack_modes,
2501                 .need_dac_fix = 1,
2502                 .input_mux = &alc880_capture_source,
2503         },
2504         [ALC880_3ST_DIG] = {
2505                 .mixers = { alc880_three_stack_mixer },
2506                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
2507                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2508                 .dac_nids = alc880_dac_nids,
2509                 .dig_out_nid = ALC880_DIGOUT_NID,
2510                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2511                 .channel_mode = alc880_threestack_modes,
2512                 .need_dac_fix = 1,
2513                 .input_mux = &alc880_capture_source,
2514         },
2515         [ALC880_TCL_S700] = {
2516                 .mixers = { alc880_tcl_s700_mixer },
2517                 .init_verbs = { alc880_volume_init_verbs,
2518                                 alc880_pin_tcl_S700_init_verbs,
2519                                 alc880_gpio2_init_verbs },
2520                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2521                 .dac_nids = alc880_dac_nids,
2522                 .hp_nid = 0x03,
2523                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2524                 .channel_mode = alc880_2_jack_modes,
2525                 .input_mux = &alc880_capture_source,
2526         },
2527         [ALC880_5ST] = {
2528                 .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
2529                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
2530                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2531                 .dac_nids = alc880_dac_nids,
2532                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2533                 .channel_mode = alc880_fivestack_modes,
2534                 .input_mux = &alc880_capture_source,
2535         },
2536         [ALC880_5ST_DIG] = {
2537                 .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
2538                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
2539                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2540                 .dac_nids = alc880_dac_nids,
2541                 .dig_out_nid = ALC880_DIGOUT_NID,
2542                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2543                 .channel_mode = alc880_fivestack_modes,
2544                 .input_mux = &alc880_capture_source,
2545         },
2546         [ALC880_6ST] = {
2547                 .mixers = { alc880_six_stack_mixer },
2548                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
2549                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2550                 .dac_nids = alc880_6st_dac_nids,
2551                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2552                 .channel_mode = alc880_sixstack_modes,
2553                 .input_mux = &alc880_6stack_capture_source,
2554         },
2555         [ALC880_6ST_DIG] = {
2556                 .mixers = { alc880_six_stack_mixer },
2557                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
2558                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2559                 .dac_nids = alc880_6st_dac_nids,
2560                 .dig_out_nid = ALC880_DIGOUT_NID,
2561                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2562                 .channel_mode = alc880_sixstack_modes,
2563                 .input_mux = &alc880_6stack_capture_source,
2564         },
2565         [ALC880_W810] = {
2566                 .mixers = { alc880_w810_base_mixer },
2567                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
2568                                 alc880_gpio2_init_verbs },
2569                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2570                 .dac_nids = alc880_w810_dac_nids,
2571                 .dig_out_nid = ALC880_DIGOUT_NID,
2572                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2573                 .channel_mode = alc880_w810_modes,
2574                 .input_mux = &alc880_capture_source,
2575         },
2576         [ALC880_Z71V] = {
2577                 .mixers = { alc880_z71v_mixer },
2578                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
2579                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2580                 .dac_nids = alc880_z71v_dac_nids,
2581                 .dig_out_nid = ALC880_DIGOUT_NID,
2582                 .hp_nid = 0x03,
2583                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2584                 .channel_mode = alc880_2_jack_modes,
2585                 .input_mux = &alc880_capture_source,
2586         },
2587         [ALC880_F1734] = {
2588                 .mixers = { alc880_f1734_mixer },
2589                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
2590                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2591                 .dac_nids = alc880_f1734_dac_nids,
2592                 .hp_nid = 0x02,
2593                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2594                 .channel_mode = alc880_2_jack_modes,
2595                 .input_mux = &alc880_capture_source,
2596         },
2597         [ALC880_ASUS] = {
2598                 .mixers = { alc880_asus_mixer },
2599                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2600                                 alc880_gpio1_init_verbs },
2601                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2602                 .dac_nids = alc880_asus_dac_nids,
2603                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2604                 .channel_mode = alc880_asus_modes,
2605                 .need_dac_fix = 1,
2606                 .input_mux = &alc880_capture_source,
2607         },
2608         [ALC880_ASUS_DIG] = {
2609                 .mixers = { alc880_asus_mixer },
2610                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2611                                 alc880_gpio1_init_verbs },
2612                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2613                 .dac_nids = alc880_asus_dac_nids,
2614                 .dig_out_nid = ALC880_DIGOUT_NID,
2615                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2616                 .channel_mode = alc880_asus_modes,
2617                 .need_dac_fix = 1,
2618                 .input_mux = &alc880_capture_source,
2619         },
2620         [ALC880_ASUS_DIG2] = {
2621                 .mixers = { alc880_asus_mixer },
2622                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2623                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2624                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2625                 .dac_nids = alc880_asus_dac_nids,
2626                 .dig_out_nid = ALC880_DIGOUT_NID,
2627                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2628                 .channel_mode = alc880_asus_modes,
2629                 .need_dac_fix = 1,
2630                 .input_mux = &alc880_capture_source,
2631         },
2632         [ALC880_ASUS_W1V] = {
2633                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2634                 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2635                                 alc880_gpio1_init_verbs },
2636                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2637                 .dac_nids = alc880_asus_dac_nids,
2638                 .dig_out_nid = ALC880_DIGOUT_NID,
2639                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2640                 .channel_mode = alc880_asus_modes,
2641                 .need_dac_fix = 1,
2642                 .input_mux = &alc880_capture_source,
2643         },
2644         [ALC880_UNIWILL_DIG] = {
2645                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2646                 .init_verbs = { alc880_volume_init_verbs,
2647                                 alc880_pin_asus_init_verbs },
2648                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2649                 .dac_nids = alc880_asus_dac_nids,
2650                 .dig_out_nid = ALC880_DIGOUT_NID,
2651                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2652                 .channel_mode = alc880_asus_modes,
2653                 .need_dac_fix = 1,
2654                 .input_mux = &alc880_capture_source,
2655         },
2656         [ALC880_UNIWILL] = {
2657                 .mixers = { alc880_uniwill_mixer },
2658                 .init_verbs = { alc880_volume_init_verbs,
2659                                 alc880_uniwill_init_verbs },
2660                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2661                 .dac_nids = alc880_asus_dac_nids,
2662                 .dig_out_nid = ALC880_DIGOUT_NID,
2663                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2664                 .channel_mode = alc880_threestack_modes,
2665                 .need_dac_fix = 1,
2666                 .input_mux = &alc880_capture_source,
2667                 .unsol_event = alc880_uniwill_unsol_event,
2668                 .init_hook = alc880_uniwill_automute,
2669         },
2670         [ALC880_UNIWILL_P53] = {
2671                 .mixers = { alc880_uniwill_p53_mixer },
2672                 .init_verbs = { alc880_volume_init_verbs,
2673                                 alc880_uniwill_p53_init_verbs },
2674                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2675                 .dac_nids = alc880_asus_dac_nids,
2676                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2677                 .channel_mode = alc880_w810_modes,
2678                 .input_mux = &alc880_capture_source,
2679                 .unsol_event = alc880_uniwill_p53_unsol_event,
2680                 .init_hook = alc880_uniwill_p53_hp_automute,
2681         },
2682         [ALC880_CLEVO] = {
2683                 .mixers = { alc880_three_stack_mixer },
2684                 .init_verbs = { alc880_volume_init_verbs,
2685                                 alc880_pin_clevo_init_verbs },
2686                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2687                 .dac_nids = alc880_dac_nids,
2688                 .hp_nid = 0x03,
2689                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2690                 .channel_mode = alc880_threestack_modes,
2691                 .need_dac_fix = 1,
2692                 .input_mux = &alc880_capture_source,
2693         },
2694         [ALC880_LG] = {
2695                 .mixers = { alc880_lg_mixer },
2696                 .init_verbs = { alc880_volume_init_verbs,
2697                                 alc880_lg_init_verbs },
2698                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2699                 .dac_nids = alc880_lg_dac_nids,
2700                 .dig_out_nid = ALC880_DIGOUT_NID,
2701                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2702                 .channel_mode = alc880_lg_ch_modes,
2703                 .need_dac_fix = 1,
2704                 .input_mux = &alc880_lg_capture_source,
2705                 .unsol_event = alc880_lg_unsol_event,
2706                 .init_hook = alc880_lg_automute,
2707         },
2708         [ALC880_LG_LW] = {
2709                 .mixers = { alc880_lg_lw_mixer },
2710                 .init_verbs = { alc880_volume_init_verbs,
2711                                 alc880_lg_lw_init_verbs },
2712                 .num_dacs = 1, 
2713                 .dac_nids = alc880_dac_nids,
2714                 .dig_out_nid = ALC880_DIGOUT_NID,
2715                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2716                 .channel_mode = alc880_2_jack_modes,
2717                 .input_mux = &alc880_lg_lw_capture_source,
2718                 .unsol_event = alc880_lg_lw_unsol_event,
2719                 .init_hook = alc880_lg_lw_automute,
2720         },
2721 #ifdef CONFIG_SND_DEBUG
2722         [ALC880_TEST] = {
2723                 .mixers = { alc880_test_mixer },
2724                 .init_verbs = { alc880_test_init_verbs },
2725                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2726                 .dac_nids = alc880_test_dac_nids,
2727                 .dig_out_nid = ALC880_DIGOUT_NID,
2728                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2729                 .channel_mode = alc880_test_modes,
2730                 .input_mux = &alc880_test_capture_source,
2731         },
2732 #endif
2733 };
2734
2735 /*
2736  * Automatic parse of I/O pins from the BIOS configuration
2737  */
2738
2739 #define NUM_CONTROL_ALLOC       32
2740 #define NUM_VERB_ALLOC          32
2741
2742 enum {
2743         ALC_CTL_WIDGET_VOL,
2744         ALC_CTL_WIDGET_MUTE,
2745         ALC_CTL_BIND_MUTE,
2746 };
2747 static struct snd_kcontrol_new alc880_control_templates[] = {
2748         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2749         HDA_CODEC_MUTE(NULL, 0, 0, 0),
2750         HDA_BIND_MUTE(NULL, 0, 0, 0),
2751 };
2752
2753 /* add dynamic controls */
2754 static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
2755 {
2756         struct snd_kcontrol_new *knew;
2757
2758         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2759                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2760
2761                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2762                 if (! knew)
2763                         return -ENOMEM;
2764                 if (spec->kctl_alloc) {
2765                         memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2766                         kfree(spec->kctl_alloc);
2767                 }
2768                 spec->kctl_alloc = knew;
2769                 spec->num_kctl_alloc = num;
2770         }
2771
2772         knew = &spec->kctl_alloc[spec->num_kctl_used];
2773         *knew = alc880_control_templates[type];
2774         knew->name = kstrdup(name, GFP_KERNEL);
2775         if (! knew->name)
2776                 return -ENOMEM;
2777         knew->private_value = val;
2778         spec->num_kctl_used++;
2779         return 0;
2780 }
2781
2782 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
2783 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
2784 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
2785 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
2786 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
2787 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
2788 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
2789 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
2790 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
2791 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
2792 #define ALC880_PIN_CD_NID               0x1c
2793
2794 /* fill in the dac_nids table from the parsed pin configuration */
2795 static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
2796 {
2797         hda_nid_t nid;
2798         int assigned[4];
2799         int i, j;
2800
2801         memset(assigned, 0, sizeof(assigned));
2802         spec->multiout.dac_nids = spec->private_dac_nids;
2803
2804         /* check the pins hardwired to audio widget */
2805         for (i = 0; i < cfg->line_outs; i++) {
2806                 nid = cfg->line_out_pins[i];
2807                 if (alc880_is_fixed_pin(nid)) {
2808                         int idx = alc880_fixed_pin_idx(nid);
2809                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
2810                         assigned[idx] = 1;
2811                 }
2812         }
2813         /* left pins can be connect to any audio widget */
2814         for (i = 0; i < cfg->line_outs; i++) {
2815                 nid = cfg->line_out_pins[i];
2816                 if (alc880_is_fixed_pin(nid))
2817                         continue;
2818                 /* search for an empty channel */
2819                 for (j = 0; j < cfg->line_outs; j++) {
2820                         if (! assigned[j]) {
2821                                 spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
2822                                 assigned[j] = 1;
2823                                 break;
2824                         }
2825                 }
2826         }
2827         spec->multiout.num_dacs = cfg->line_outs;
2828         return 0;
2829 }
2830
2831 /* add playback controls from the parsed DAC table */
2832 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
2833                                              const struct auto_pin_cfg *cfg)
2834 {
2835         char name[32];
2836         static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2837         hda_nid_t nid;
2838         int i, err;
2839
2840         for (i = 0; i < cfg->line_outs; i++) {
2841                 if (! spec->multiout.dac_nids[i])
2842                         continue;
2843                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
2844                 if (i == 2) {
2845                         /* Center/LFE */
2846                         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
2847                                                HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
2848                                 return err;
2849                         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
2850                                                HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
2851                                 return err;
2852                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
2853                                                HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
2854                                 return err;
2855                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
2856                                                HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
2857                                 return err;
2858                 } else {
2859                         sprintf(name, "%s Playback Volume", chname[i]);
2860                         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2861                                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2862                                 return err;
2863                         sprintf(name, "%s Playback Switch", chname[i]);
2864                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2865                                                HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2866                                 return err;
2867                 }
2868         }
2869         return 0;
2870 }
2871
2872 /* add playback controls for speaker and HP outputs */
2873 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
2874                                         const char *pfx)
2875 {
2876         hda_nid_t nid;
2877         int err;
2878         char name[32];
2879
2880         if (! pin)
2881                 return 0;
2882
2883         if (alc880_is_fixed_pin(pin)) {
2884                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
2885                 /* specify the DAC as the extra output */
2886                 if (! spec->multiout.hp_nid)
2887                         spec->multiout.hp_nid = nid;
2888                 else
2889                         spec->multiout.extra_out_nid[0] = nid;
2890                 /* control HP volume/switch on the output mixer amp */
2891                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
2892                 sprintf(name, "%s Playback Volume", pfx);
2893                 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2894                                        HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2895                         return err;
2896                 sprintf(name, "%s Playback Switch", pfx);
2897                 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2898                                        HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2899                         return err;
2900         } else if (alc880_is_multi_pin(pin)) {
2901                 /* set manual connection */
2902                 /* we have only a switch on HP-out PIN */
2903                 sprintf(name, "%s Playback Switch", pfx);
2904                 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
2905                                        HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
2906                         return err;
2907         }
2908         return 0;
2909 }
2910
2911 /* create input playback/capture controls for the given pin */
2912 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
2913                             int idx, hda_nid_t mix_nid)
2914 {
2915         char name[32];
2916         int err;
2917
2918         sprintf(name, "%s Playback Volume", ctlname);
2919         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2920                                HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
2921                 return err;
2922         sprintf(name, "%s Playback Switch", ctlname);
2923         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
2924                                HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
2925                 return err;
2926         return 0;
2927 }
2928
2929 /* create playback/capture controls for input pins */
2930 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
2931                                                 const struct auto_pin_cfg *cfg)
2932 {
2933         struct hda_input_mux *imux = &spec->private_imux;
2934         int i, err, idx;
2935
2936         for (i = 0; i < AUTO_PIN_LAST; i++) {
2937                 if (alc880_is_input_pin(cfg->input_pins[i])) {
2938                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
2939                         err = new_analog_input(spec, cfg->input_pins[i],
2940                                                auto_pin_cfg_labels[i],
2941                                                idx, 0x0b);
2942                         if (err < 0)
2943                                 return err;
2944                         imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2945                         imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
2946                         imux->num_items++;
2947                 }
2948         }
2949         return 0;
2950 }
2951
2952 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
2953                                               hda_nid_t nid, int pin_type,
2954                                               int dac_idx)
2955 {
2956         /* set as output */
2957         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2958         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2959         /* need the manual connection? */
2960         if (alc880_is_multi_pin(nid)) {
2961                 struct alc_spec *spec = codec->spec;
2962                 int idx = alc880_multi_pin_idx(nid);
2963                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
2964                                     AC_VERB_SET_CONNECT_SEL,
2965                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
2966         }
2967 }
2968
2969 static void alc880_auto_init_multi_out(struct hda_codec *codec)
2970 {
2971         struct alc_spec *spec = codec->spec;
2972         int i;
2973
2974         for (i = 0; i < spec->autocfg.line_outs; i++) {
2975                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
2976                 alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2977         }
2978 }
2979
2980 static void alc880_auto_init_extra_out(struct hda_codec *codec)
2981 {
2982         struct alc_spec *spec = codec->spec;
2983         hda_nid_t pin;
2984
2985         pin = spec->autocfg.speaker_pins[0];
2986         if (pin) /* connect to front */
2987                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2988         pin = spec->autocfg.hp_pins[0];
2989         if (pin) /* connect to front */
2990                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2991 }
2992
2993 static void alc880_auto_init_analog_input(struct hda_codec *codec)
2994 {
2995         struct alc_spec *spec = codec->spec;
2996         int i;
2997
2998         for (i = 0; i < AUTO_PIN_LAST; i++) {
2999                 hda_nid_t nid = spec->autocfg.input_pins[i];
3000                 if (alc880_is_input_pin(nid)) {
3001                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3002                                             i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
3003                         if (nid != ALC880_PIN_CD_NID)
3004                                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3005                                                     AMP_OUT_MUTE);
3006                 }
3007         }
3008 }
3009
3010 /* parse the BIOS configuration and set up the alc_spec */
3011 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
3012 static int alc880_parse_auto_config(struct hda_codec *codec)
3013 {
3014         struct alc_spec *spec = codec->spec;
3015         int err;
3016         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3017
3018         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3019                                                 alc880_ignore)) < 0)
3020                 return err;
3021         if (! spec->autocfg.line_outs)
3022                 return 0; /* can't find valid BIOS pin config */
3023
3024         if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
3025             (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
3026             (err = alc880_auto_create_extra_out(spec,
3027                                                 spec->autocfg.speaker_pins[0],
3028                                                 "Speaker")) < 0 ||
3029             (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3030                                                 "Headphone")) < 0 ||
3031             (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
3032                 return err;
3033
3034         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3035
3036         if (spec->autocfg.dig_out_pin)
3037                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3038         if (spec->autocfg.dig_in_pin)
3039                 spec->dig_in_nid = ALC880_DIGIN_NID;
3040
3041         if (spec->kctl_alloc)
3042                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3043
3044         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3045
3046         spec->num_mux_defs = 1;
3047         spec->input_mux = &spec->private_imux;
3048
3049         return 1;
3050 }
3051
3052 /* additional initialization for auto-configuration model */
3053 static void alc880_auto_init(struct hda_codec *codec)
3054 {
3055         alc880_auto_init_multi_out(codec);
3056         alc880_auto_init_extra_out(codec);
3057         alc880_auto_init_analog_input(codec);
3058 }
3059
3060 /*
3061  * OK, here we have finally the patch for ALC880
3062  */
3063
3064 static int patch_alc880(struct hda_codec *codec)
3065 {
3066         struct alc_spec *spec;
3067         int board_config;
3068         int err;
3069
3070         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3071         if (spec == NULL)
3072                 return -ENOMEM;
3073
3074         codec->spec = spec;
3075
3076         board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
3077         if (board_config < 0 || board_config >= ALC880_MODEL_LAST) {
3078                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3079                        "trying auto-probe from BIOS...\n");
3080                 board_config = ALC880_AUTO;
3081         }
3082
3083         if (board_config == ALC880_AUTO) {
3084                 /* automatic parse from the BIOS config */
3085                 err = alc880_parse_auto_config(codec);
3086                 if (err < 0) {
3087                         alc_free(codec);
3088                         return err;
3089                 } else if (! err) {
3090                         printk(KERN_INFO
3091                                "hda_codec: Cannot set up configuration "
3092                                "from BIOS.  Using 3-stack mode...\n");
3093                         board_config = ALC880_3ST;
3094                 }
3095         }
3096
3097         if (board_config != ALC880_AUTO)
3098                 setup_preset(spec, &alc880_presets[board_config]);
3099
3100         spec->stream_name_analog = "ALC880 Analog";
3101         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3102         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3103
3104         spec->stream_name_digital = "ALC880 Digital";
3105         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3106         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3107
3108         if (! spec->adc_nids && spec->input_mux) {
3109                 /* check whether NID 0x07 is valid */
3110                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3111                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
3112                 if (wcap != AC_WID_AUD_IN) {
3113                         spec->adc_nids = alc880_adc_nids_alt;
3114                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3115                         spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
3116                         spec->num_mixers++;
3117                 } else {
3118                         spec->adc_nids = alc880_adc_nids;
3119                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3120                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3121                         spec->num_mixers++;
3122                 }
3123         }
3124
3125         codec->patch_ops = alc_patch_ops;
3126         if (board_config == ALC880_AUTO)
3127                 spec->init_hook = alc880_auto_init;
3128
3129         return 0;
3130 }
3131
3132
3133 /*
3134  * ALC260 support
3135  */
3136
3137 static hda_nid_t alc260_dac_nids[1] = {
3138         /* front */
3139         0x02,
3140 };
3141
3142 static hda_nid_t alc260_adc_nids[1] = {
3143         /* ADC0 */
3144         0x04,
3145 };
3146
3147 static hda_nid_t alc260_adc_nids_alt[1] = {
3148         /* ADC1 */
3149         0x05,
3150 };
3151
3152 static hda_nid_t alc260_hp_adc_nids[2] = {
3153         /* ADC1, 0 */
3154         0x05, 0x04
3155 };
3156
3157 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3158  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3159  */
3160 static hda_nid_t alc260_dual_adc_nids[2] = {
3161         /* ADC0, ADC1 */
3162         0x04, 0x05
3163 };
3164
3165 #define ALC260_DIGOUT_NID       0x03
3166 #define ALC260_DIGIN_NID        0x06
3167
3168 static struct hda_input_mux alc260_capture_source = {
3169         .num_items = 4,
3170         .items = {
3171                 { "Mic", 0x0 },
3172                 { "Front Mic", 0x1 },
3173                 { "Line", 0x2 },
3174                 { "CD", 0x4 },
3175         },
3176 };
3177
3178 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3179  * headphone jack and the internal CD lines since these are the only pins at
3180  * which audio can appear.  For flexibility, also allow the option of
3181  * recording the mixer output on the second ADC (ADC0 doesn't have a
3182  * connection to the mixer output).
3183  */
3184 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3185         {
3186                 .num_items = 3,
3187                 .items = {
3188                         { "Mic/Line", 0x0 },
3189                         { "CD", 0x4 },
3190                         { "Headphone", 0x2 },
3191                 },
3192         },
3193         {
3194                 .num_items = 4,
3195                 .items = {
3196                         { "Mic/Line", 0x0 },
3197                         { "CD", 0x4 },
3198                         { "Headphone", 0x2 },
3199                         { "Mixer", 0x5 },
3200                 },
3201         },
3202
3203 };
3204
3205 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3206  * the Fujitsu S702x, but jacks are marked differently.
3207  */
3208 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3209         {
3210                 .num_items = 4,
3211                 .items = {
3212                         { "Mic", 0x0 },
3213                         { "Line", 0x2 },
3214                         { "CD", 0x4 },
3215                         { "Headphone", 0x5 },
3216                 },
3217         },
3218         {
3219                 .num_items = 5,
3220                 .items = {
3221                         { "Mic", 0x0 },
3222                         { "Line", 0x2 },
3223                         { "CD", 0x4 },
3224                         { "Headphone", 0x6 },
3225                         { "Mixer", 0x5 },
3226                 },
3227         },
3228 };
3229 /*
3230  * This is just place-holder, so there's something for alc_build_pcms to look
3231  * at when it calculates the maximum number of channels. ALC260 has no mixer
3232  * element which allows changing the channel mode, so the verb list is
3233  * never used.
3234  */
3235 static struct hda_channel_mode alc260_modes[1] = {
3236         { 2, NULL },
3237 };
3238
3239
3240 /* Mixer combinations
3241  *
3242  * basic: base_output + input + pc_beep + capture
3243  * HP: base_output + input + capture_alt
3244  * HP_3013: hp_3013 + input + capture
3245  * fujitsu: fujitsu + capture
3246  * acer: acer + capture
3247  */
3248
3249 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3250         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3251         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3252         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3253         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3254         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3255         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3256         { } /* end */
3257 };      
3258
3259 static struct snd_kcontrol_new alc260_input_mixer[] = {
3260         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3261         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3262         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3263         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3264         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3265         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3266         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3267         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3268         { } /* end */
3269 };
3270
3271 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3272         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3273         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3274         { } /* end */
3275 };
3276
3277 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3278         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3279         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3280         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3281         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3282         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3283         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3284         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3285         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3286         { } /* end */
3287 };
3288
3289 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3290  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3291  */
3292 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3293         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3294         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3295         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3296         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3297         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3298         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3299         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3300         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3301         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3302         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3303         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3304         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3305         { } /* end */
3306 };
3307
3308 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3309  * versions of the ALC260 don't act on requests to enable mic bias from NID
3310  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3311  * datasheet doesn't mention this restriction.  At this stage it's not clear
3312  * whether this behaviour is intentional or is a hardware bug in chip
3313  * revisions available in early 2006.  Therefore for now allow the
3314  * "Headphone Jack Mode" control to span all choices, but if it turns out
3315  * that the lack of mic bias for this NID is intentional we could change the
3316  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3317  *
3318  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3319  * don't appear to make the mic bias available from the "line" jack, even
3320  * though the NID used for this jack (0x14) can supply it.  The theory is
3321  * that perhaps Acer have included blocking capacitors between the ALC260
3322  * and the output jack.  If this turns out to be the case for all such
3323  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3324  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3325  */
3326 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3327         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3328         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3329         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3330         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3331         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3332         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3333         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3334         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3335         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3336         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3337         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3338         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3339         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3340         { } /* end */
3341 };
3342
3343 /* capture mixer elements */
3344 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3345         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3346         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3347         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3348         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3349         {
3350                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3351                 /* The multiple "Capture Source" controls confuse alsamixer
3352                  * So call somewhat different..
3353                  * FIXME: the controls appear in the "playback" view!
3354                  */
3355                 /* .name = "Capture Source", */
3356                 .name = "Input Source",
3357                 .count = 2,
3358                 .info = alc_mux_enum_info,
3359                 .get = alc_mux_enum_get,
3360                 .put = alc_mux_enum_put,
3361         },
3362         { } /* end */
3363 };
3364
3365 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3366         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3367         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3368         {
3369                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3370                 /* The multiple "Capture Source" controls confuse alsamixer
3371                  * So call somewhat different..
3372                  * FIXME: the controls appear in the "playback" view!
3373                  */
3374                 /* .name = "Capture Source", */
3375                 .name = "Input Source",
3376                 .count = 1,
3377                 .info = alc_mux_enum_info,
3378                 .get = alc_mux_enum_get,
3379                 .put = alc_mux_enum_put,
3380         },
3381         { } /* end */
3382 };
3383
3384 /*
3385  * initialization verbs
3386  */
3387 static struct hda_verb alc260_init_verbs[] = {
3388         /* Line In pin widget for input */
3389         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3390         /* CD pin widget for input */
3391         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3392         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3393         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3394         /* Mic2 (front panel) pin widget for input and vref at 80% */
3395         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3396         /* LINE-2 is used for line-out in rear */
3397         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3398         /* select line-out */
3399         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3400         /* LINE-OUT pin */
3401         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3402         /* enable HP */
3403         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3404         /* enable Mono */
3405         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3406         /* mute capture amp left and right */
3407         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3408         /* set connection select to line in (default select for this ADC) */
3409         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3410         /* mute capture amp left and right */
3411         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3412         /* set connection select to line in (default select for this ADC) */
3413         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3414         /* set vol=0 Line-Out mixer amp left and right */
3415         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3416         /* unmute pin widget amp left and right (no gain on this amp) */
3417         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3418         /* set vol=0 HP mixer amp left and right */
3419         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3420         /* unmute pin widget amp left and right (no gain on this amp) */
3421         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3422         /* set vol=0 Mono mixer amp left and right */
3423         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3424         /* unmute pin widget amp left and right (no gain on this amp) */
3425         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3426         /* unmute LINE-2 out pin */
3427         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3428         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3429         /* mute CD */
3430         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3431         /* mute Line In */
3432         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3433         /* mute Mic */
3434         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3435         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3436         /* mute Front out path */
3437         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3438         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3439         /* mute Headphone out path */
3440         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3441         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3442         /* mute Mono out path */
3443         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3444         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3445         { }
3446 };
3447
3448 #if 0 /* should be identical with alc260_init_verbs? */
3449 static struct hda_verb alc260_hp_init_verbs[] = {
3450         /* Headphone and output */
3451         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3452         /* mono output */
3453         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3454         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3455         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3456         /* Mic2 (front panel) pin widget for input and vref at 80% */
3457         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3458         /* Line In pin widget for input */
3459         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3460         /* Line-2 pin widget for output */
3461         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3462         /* CD pin widget for input */
3463         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3464         /* unmute amp left and right */
3465         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3466         /* set connection select to line in (default select for this ADC) */
3467         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3468         /* unmute Line-Out mixer amp left and right (volume = 0) */
3469         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3470         /* mute pin widget amp left and right (no gain on this amp) */
3471         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3472         /* unmute HP mixer amp left and right (volume = 0) */
3473         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3474         /* mute pin widget amp left and right (no gain on this amp) */
3475         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3476         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3477         /* unmute CD */
3478         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3479         /* unmute Line In */
3480         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3481         /* unmute Mic */
3482         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3483         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3484         /* Unmute Front out path */
3485         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3486         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3487         /* Unmute Headphone out path */
3488         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3489         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3490         /* Unmute Mono out path */
3491         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3492         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3493         { }
3494 };
3495 #endif
3496
3497 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3498         /* Line out and output */
3499         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3500         /* mono output */
3501         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3502         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3503         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3504         /* Mic2 (front panel) pin widget for input and vref at 80% */
3505         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3506         /* Line In pin widget for input */
3507         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3508         /* Headphone pin widget for output */
3509         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3510         /* CD pin widget for input */
3511         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3512         /* unmute amp left and right */
3513         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3514         /* set connection select to line in (default select for this ADC) */
3515         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3516         /* unmute Line-Out mixer amp left and right (volume = 0) */
3517         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3518         /* mute pin widget amp left and right (no gain on this amp) */
3519         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3520         /* unmute HP mixer amp left and right (volume = 0) */
3521         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3522         /* mute pin widget amp left and right (no gain on this amp) */
3523         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3524         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3525         /* unmute CD */
3526         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3527         /* unmute Line In */
3528         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3529         /* unmute Mic */
3530         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3531         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3532         /* Unmute Front out path */
3533         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3534         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3535         /* Unmute Headphone out path */
3536         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3537         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3538         /* Unmute Mono out path */
3539         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3540         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3541         { }
3542 };
3543
3544 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3545  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3546  * audio = 0x16, internal speaker = 0x10.
3547  */
3548 static struct hda_verb alc260_fujitsu_init_verbs[] = {
3549         /* Disable all GPIOs */
3550         {0x01, AC_VERB_SET_GPIO_MASK, 0},
3551         /* Internal speaker is connected to headphone pin */
3552         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3553         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3554         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3555         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3556         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3557         /* Ensure all other unused pins are disabled and muted. */
3558         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3559         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3560         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3561         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3562         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3563         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3564         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3565         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3566
3567         /* Disable digital (SPDIF) pins */
3568         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3569         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3570
3571         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
3572          * when acting as an output.
3573          */
3574         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3575
3576         /* Start with output sum widgets muted and their output gains at min */
3577         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3578         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3579         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3580         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3581         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3582         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3583         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3584         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3585         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3586
3587         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3588         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3589         /* Unmute Line1 pin widget output buffer since it starts as an output.
3590          * If the pin mode is changed by the user the pin mode control will
3591          * take care of enabling the pin's input/output buffers as needed.
3592          * Therefore there's no need to enable the input buffer at this
3593          * stage.
3594          */
3595         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3596         /* Unmute input buffer of pin widget used for Line-in (no equiv 
3597          * mixer ctrl)
3598          */
3599         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3600
3601         /* Mute capture amp left and right */
3602         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3603         /* Set ADC connection select to match default mixer setting - line 
3604          * in (on mic1 pin)
3605          */
3606         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3607
3608         /* Do the same for the second ADC: mute capture input amp and
3609          * set ADC connection to line in (on mic1 pin)
3610          */
3611         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3612         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3613
3614         /* Mute all inputs to mixer widget (even unconnected ones) */
3615         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3616         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3617         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3618         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3619         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3620         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3621         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3622         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3623
3624         { }
3625 };
3626
3627 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3628  * similar laptops (adapted from Fujitsu init verbs).
3629  */
3630 static struct hda_verb alc260_acer_init_verbs[] = {
3631         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3632          * the headphone jack.  Turn this on and rely on the standard mute
3633          * methods whenever the user wants to turn these outputs off.
3634          */
3635         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3636         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3637         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3638         /* Internal speaker/Headphone jack is connected to Line-out pin */
3639         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3640         /* Internal microphone/Mic jack is connected to Mic1 pin */
3641         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3642         /* Line In jack is connected to Line1 pin */
3643         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3644         /* Ensure all other unused pins are disabled and muted. */
3645         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3646         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3647         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3648         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3649         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3650         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3651         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3652         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3653         /* Disable digital (SPDIF) pins */
3654         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3655         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3656
3657         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
3658          * bus when acting as outputs.
3659          */
3660         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3661         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3662
3663         /* Start with output sum widgets muted and their output gains at min */
3664         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3665         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3666         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3667         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3668         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3669         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3670         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3671         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3672         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3673
3674         /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
3675         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3676         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3677          * inputs. If the pin mode is changed by the user the pin mode control
3678          * will take care of enabling the pin's input/output buffers as needed.
3679          * Therefore there's no need to enable the input buffer at this
3680          * stage.
3681          */
3682         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3683         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3684
3685         /* Mute capture amp left and right */
3686         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3687         /* Set ADC connection select to match default mixer setting - mic
3688          * (on mic1 pin)
3689          */
3690         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3691
3692         /* Do similar with the second ADC: mute capture input amp and
3693          * set ADC connection to mic to match ALSA's default state.
3694          */
3695         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3696         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3697
3698         /* Mute all inputs to mixer widget (even unconnected ones) */
3699         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3700         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3701         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3702         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3703         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3704         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3705         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3706         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3707
3708         { }
3709 };
3710
3711 /* Test configuration for debugging, modelled after the ALC880 test
3712  * configuration.
3713  */
3714 #ifdef CONFIG_SND_DEBUG
3715 static hda_nid_t alc260_test_dac_nids[1] = {
3716         0x02,
3717 };
3718 static hda_nid_t alc260_test_adc_nids[2] = {
3719         0x04, 0x05,
3720 };
3721 /* For testing the ALC260, each input MUX needs its own definition since
3722  * the signal assignments are different.  This assumes that the first ADC 
3723  * is NID 0x04.
3724  */
3725 static struct hda_input_mux alc260_test_capture_sources[2] = {
3726         {
3727                 .num_items = 7,
3728                 .items = {
3729                         { "MIC1 pin", 0x0 },
3730                         { "MIC2 pin", 0x1 },
3731                         { "LINE1 pin", 0x2 },
3732                         { "LINE2 pin", 0x3 },
3733                         { "CD pin", 0x4 },
3734                         { "LINE-OUT pin", 0x5 },
3735                         { "HP-OUT pin", 0x6 },
3736                 },
3737         },
3738         {
3739                 .num_items = 8,
3740                 .items = {
3741                         { "MIC1 pin", 0x0 },
3742                         { "MIC2 pin", 0x1 },
3743                         { "LINE1 pin", 0x2 },
3744                         { "LINE2 pin", 0x3 },
3745                         { "CD pin", 0x4 },
3746                         { "Mixer", 0x5 },
3747                         { "LINE-OUT pin", 0x6 },
3748                         { "HP-OUT pin", 0x7 },
3749                 },
3750         },
3751 };
3752 static struct snd_kcontrol_new alc260_test_mixer[] = {
3753         /* Output driver widgets */
3754         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3755         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3756         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3757         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
3758         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3759         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
3760
3761         /* Modes for retasking pin widgets
3762          * Note: the ALC260 doesn't seem to act on requests to enable mic
3763          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
3764          * mention this restriction.  At this stage it's not clear whether
3765          * this behaviour is intentional or is a hardware bug in chip
3766          * revisions available at least up until early 2006.  Therefore for
3767          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
3768          * choices, but if it turns out that the lack of mic bias for these
3769          * NIDs is intentional we could change their modes from
3770          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3771          */
3772         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
3773         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
3774         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
3775         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
3776         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
3777         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
3778
3779         /* Loopback mixer controls */
3780         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
3781         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
3782         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
3783         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
3784         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
3785         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
3786         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
3787         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
3788         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3789         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3790         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3791         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3792         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
3793         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
3794         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
3795         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
3796
3797         /* Controls for GPIO pins, assuming they are configured as outputs */
3798         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
3799         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
3800         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
3801         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
3802
3803         /* Switches to allow the digital IO pins to be enabled.  The datasheet
3804          * is ambigious as to which NID is which; testing on laptops which
3805          * make this output available should provide clarification. 
3806          */
3807         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
3808         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
3809
3810         { } /* end */
3811 };
3812 static struct hda_verb alc260_test_init_verbs[] = {
3813         /* Enable all GPIOs as outputs with an initial value of 0 */
3814         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
3815         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
3816         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
3817
3818         /* Enable retasking pins as output, initially without power amp */
3819         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3820         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3821         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3822         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3823         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3824         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3825
3826         /* Disable digital (SPDIF) pins initially, but users can enable
3827          * them via a mixer switch.  In the case of SPDIF-out, this initverb
3828          * payload also sets the generation to 0, output to be in "consumer"
3829          * PCM format, copyright asserted, no pre-emphasis and no validity
3830          * control.
3831          */
3832         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3833         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3834
3835         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
3836          * OUT1 sum bus when acting as an output.
3837          */
3838         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3839         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
3840         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3841         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
3842
3843         /* Start with output sum widgets muted and their output gains at min */
3844         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3845         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3846         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3847         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3848         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3849         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3850         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3851         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3852         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3853
3854         /* Unmute retasking pin widget output buffers since the default
3855          * state appears to be output.  As the pin mode is changed by the
3856          * user the pin mode control will take care of enabling the pin's
3857          * input/output buffers as needed.
3858          */
3859         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3860         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3861         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3862         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3863         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3864         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3865         /* Also unmute the mono-out pin widget */
3866         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3867
3868         /* Mute capture amp left and right */
3869         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3870         /* Set ADC connection select to match default mixer setting (mic1
3871          * pin)
3872          */
3873         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3874
3875         /* Do the same for the second ADC: mute capture input amp and
3876          * set ADC connection to mic1 pin
3877          */
3878         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3879         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3880
3881         /* Mute all inputs to mixer widget (even unconnected ones) */
3882         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3883         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3884         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3885         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3886         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3887         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3888         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3889         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3890
3891         { }
3892 };
3893 #endif
3894
3895 static struct hda_pcm_stream alc260_pcm_analog_playback = {
3896         .substreams = 1,
3897         .channels_min = 2,
3898         .channels_max = 2,
3899 };
3900
3901 static struct hda_pcm_stream alc260_pcm_analog_capture = {
3902         .substreams = 1,
3903         .channels_min = 2,
3904         .channels_max = 2,
3905 };
3906
3907 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
3908 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
3909
3910 /*
3911  * for BIOS auto-configuration
3912  */
3913
3914 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
3915                                         const char *pfx)
3916 {
3917         hda_nid_t nid_vol;
3918         unsigned long vol_val, sw_val;
3919         char name[32];
3920         int err;
3921
3922         if (nid >= 0x0f && nid < 0x11) {
3923                 nid_vol = nid - 0x7;
3924                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3925                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3926         } else if (nid == 0x11) {
3927                 nid_vol = nid - 0x7;
3928                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
3929                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
3930         } else if (nid >= 0x12 && nid <= 0x15) {
3931                 nid_vol = 0x08;
3932                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3933                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3934         } else
3935                 return 0; /* N/A */
3936         
3937         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
3938         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
3939                 return err;
3940         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
3941         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
3942                 return err;
3943         return 1;
3944 }
3945
3946 /* add playback controls from the parsed DAC table */
3947 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
3948                                              const struct auto_pin_cfg *cfg)
3949 {
3950         hda_nid_t nid;
3951         int err;
3952
3953         spec->multiout.num_dacs = 1;
3954         spec->multiout.dac_nids = spec->private_dac_nids;
3955         spec->multiout.dac_nids[0] = 0x02;
3956
3957         nid = cfg->line_out_pins[0];
3958         if (nid) {
3959                 err = alc260_add_playback_controls(spec, nid, "Front");
3960                 if (err < 0)
3961                         return err;
3962         }
3963
3964         nid = cfg->speaker_pins[0];
3965         if (nid) {
3966                 err = alc260_add_playback_controls(spec, nid, "Speaker");
3967                 if (err < 0)
3968                         return err;
3969         }
3970
3971         nid = cfg->hp_pins[0];
3972         if (nid) {
3973                 err = alc260_add_playback_controls(spec, nid, "Headphone");
3974                 if (err < 0)
3975                         return err;
3976         }
3977         return 0;       
3978 }
3979
3980 /* create playback/capture controls for input pins */
3981 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
3982                                                 const struct auto_pin_cfg *cfg)
3983 {
3984         struct hda_input_mux *imux = &spec->private_imux;
3985         int i, err, idx;
3986
3987         for (i = 0; i < AUTO_PIN_LAST; i++) {
3988                 if (cfg->input_pins[i] >= 0x12) {
3989                         idx = cfg->input_pins[i] - 0x12;
3990                         err = new_analog_input(spec, cfg->input_pins[i],
3991                                                auto_pin_cfg_labels[i], idx, 0x07);
3992                         if (err < 0)
3993                                 return err;
3994                         imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3995                         imux->items[imux->num_items].index = idx;
3996                         imux->num_items++;
3997                 }
3998                 if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
3999                         idx = cfg->input_pins[i] - 0x09;
4000                         err = new_analog_input(spec, cfg->input_pins[i],
4001                                                auto_pin_cfg_labels[i], idx, 0x07);
4002                         if (err < 0)
4003                                 return err;
4004                         imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
4005                         imux->items[imux->num_items].index = idx;
4006                         imux->num_items++;
4007                 }
4008         }
4009         return 0;
4010 }
4011
4012 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4013                                               hda_nid_t nid, int pin_type,
4014                                               int sel_idx)
4015 {
4016         /* set as output */
4017         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
4018         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4019         /* need the manual connection? */
4020         if (nid >= 0x12) {
4021                 int idx = nid - 0x12;
4022                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4023                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4024                                     
4025         }
4026 }
4027
4028 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4029 {
4030         struct alc_spec *spec = codec->spec;
4031         hda_nid_t nid;
4032
4033         nid = spec->autocfg.line_out_pins[0];   
4034         if (nid)
4035                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4036         
4037         nid = spec->autocfg.speaker_pins[0];
4038         if (nid)
4039                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4040
4041         nid = spec->autocfg.hp_pins[0];
4042         if (nid)
4043                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4044 }       
4045
4046 #define ALC260_PIN_CD_NID               0x16
4047 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4048 {
4049         struct alc_spec *spec = codec->spec;
4050         int i;
4051
4052         for (i = 0; i < AUTO_PIN_LAST; i++) {
4053                 hda_nid_t nid = spec->autocfg.input_pins[i];
4054                 if (nid >= 0x12) {
4055                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4056                                             i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4057                         if (nid != ALC260_PIN_CD_NID)
4058                                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4059                                                     AMP_OUT_MUTE);
4060                 }
4061         }
4062 }
4063
4064 /*
4065  * generic initialization of ADC, input mixers and output mixers
4066  */
4067 static struct hda_verb alc260_volume_init_verbs[] = {
4068         /*
4069          * Unmute ADC0-1 and set the default input to mic-in
4070          */
4071         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4072         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4073         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4074         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4075         
4076         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4077          * mixer widget
4078          * Note: PASD motherboards uses the Line In 2 as the input for front panel
4079          * mic (mic 2)
4080          */
4081         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4082         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4083         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4084         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4085         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4086         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4087
4088         /*
4089          * Set up output mixers (0x08 - 0x0a)
4090          */
4091         /* set vol=0 to output mixers */
4092         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4093         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4094         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4095         /* set up input amps for analog loopback */
4096         /* Amp Indices: DAC = 0, mixer = 1 */
4097         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4098         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4099         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4100         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4101         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4102         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4103         
4104         { }
4105 };
4106
4107 static int alc260_parse_auto_config(struct hda_codec *codec)
4108 {
4109         struct alc_spec *spec = codec->spec;
4110         unsigned int wcap;
4111         int err;
4112         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4113
4114         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4115                                                 alc260_ignore)) < 0)
4116                 return err;
4117         if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
4118                 return err;
4119         if (! spec->kctl_alloc)
4120                 return 0; /* can't find valid BIOS pin config */
4121         if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
4122                 return err;
4123
4124         spec->multiout.max_channels = 2;
4125
4126         if (spec->autocfg.dig_out_pin)
4127                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4128         if (spec->kctl_alloc)
4129                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4130
4131         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4132
4133         spec->num_mux_defs = 1;
4134         spec->input_mux = &spec->private_imux;
4135
4136         /* check whether NID 0x04 is valid */
4137         wcap = get_wcaps(codec, 0x04);
4138         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4139         if (wcap != AC_WID_AUD_IN) {
4140                 spec->adc_nids = alc260_adc_nids_alt;
4141                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4142                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4143         } else {
4144                 spec->adc_nids = alc260_adc_nids;
4145                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4146                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4147         }
4148         spec->num_mixers++;
4149
4150         return 1;
4151 }
4152
4153 /* additional initialization for auto-configuration model */
4154 static void alc260_auto_init(struct hda_codec *codec)
4155 {
4156         alc260_auto_init_multi_out(codec);
4157         alc260_auto_init_analog_input(codec);
4158 }
4159
4160 /*
4161  * ALC260 configurations
4162  */
4163 static struct hda_board_config alc260_cfg_tbl[] = {
4164         { .modelname = "basic", .config = ALC260_BASIC },
4165         { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
4166           .config = ALC260_BASIC }, /* Sony VAIO */
4167         { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cc,
4168           .config = ALC260_BASIC }, /* Sony VAIO VGN-S3HP */
4169         { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cd,
4170           .config = ALC260_BASIC }, /* Sony VAIO */
4171         { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729,
4172           .config = ALC260_BASIC }, /* CTL Travel Master U553W */
4173         { .modelname = "hp", .config = ALC260_HP },
4174         { .modelname = "hp-3013", .config = ALC260_HP_3013 },
4175         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP_3013 },
4176         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
4177         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 },
4178         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
4179         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
4180         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
4181         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP },
4182         { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X },
4183         { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X },
4184         { .modelname = "acer", .config = ALC260_ACER },
4185         { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER },
4186 #ifdef CONFIG_SND_DEBUG
4187         { .modelname = "test", .config = ALC260_TEST },
4188 #endif
4189         { .modelname = "auto", .config = ALC260_AUTO },
4190         {}
4191 };
4192
4193 static struct alc_config_preset alc260_presets[] = {
4194         [ALC260_BASIC] = {
4195                 .mixers = { alc260_base_output_mixer,
4196                             alc260_input_mixer,
4197                             alc260_pc_beep_mixer,
4198                             alc260_capture_mixer },
4199                 .init_verbs = { alc260_init_verbs },
4200                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4201                 .dac_nids = alc260_dac_nids,
4202                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4203                 .adc_nids = alc260_adc_nids,
4204                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4205                 .channel_mode = alc260_modes,
4206                 .input_mux = &alc260_capture_source,
4207         },
4208         [ALC260_HP] = {
4209                 .mixers = { alc260_base_output_mixer,
4210                             alc260_input_mixer,
4211                             alc260_capture_alt_mixer },
4212                 .init_verbs = { alc260_init_verbs },
4213                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4214                 .dac_nids = alc260_dac_nids,
4215                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4216                 .adc_nids = alc260_hp_adc_nids,
4217                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4218                 .channel_mode = alc260_modes,
4219                 .input_mux = &alc260_capture_source,
4220         },
4221         [ALC260_HP_3013] = {
4222                 .mixers = { alc260_hp_3013_mixer,
4223                             alc260_input_mixer,
4224                             alc260_capture_alt_mixer },
4225                 .init_verbs = { alc260_hp_3013_init_verbs },
4226                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4227                 .dac_nids = alc260_dac_nids,
4228                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4229                 .adc_nids = alc260_hp_adc_nids,
4230                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4231                 .channel_mode = alc260_modes,
4232                 .input_mux = &alc260_capture_source,
4233         },
4234         [ALC260_FUJITSU_S702X] = {
4235                 .mixers = { alc260_fujitsu_mixer,
4236                             alc260_capture_mixer },
4237                 .init_verbs = { alc260_fujitsu_init_verbs },
4238                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4239                 .dac_nids = alc260_dac_nids,
4240                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4241                 .adc_nids = alc260_dual_adc_nids,
4242                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4243                 .channel_mode = alc260_modes,
4244                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4245                 .input_mux = alc260_fujitsu_capture_sources,
4246         },
4247         [ALC260_ACER] = {
4248                 .mixers = { alc260_acer_mixer,
4249                             alc260_capture_mixer },
4250                 .init_verbs = { alc260_acer_init_verbs },
4251                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4252                 .dac_nids = alc260_dac_nids,
4253                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4254                 .adc_nids = alc260_dual_adc_nids,
4255                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4256                 .channel_mode = alc260_modes,
4257                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4258                 .input_mux = alc260_acer_capture_sources,
4259         },
4260 #ifdef CONFIG_SND_DEBUG
4261         [ALC260_TEST] = {
4262                 .mixers = { alc260_test_mixer,
4263                             alc260_capture_mixer },
4264                 .init_verbs = { alc260_test_init_verbs },
4265                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4266                 .dac_nids = alc260_test_dac_nids,
4267                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4268                 .adc_nids = alc260_test_adc_nids,
4269                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4270                 .channel_mode = alc260_modes,
4271                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4272                 .input_mux = alc260_test_capture_sources,
4273         },
4274 #endif
4275 };
4276
4277 static int patch_alc260(struct hda_codec *codec)
4278 {
4279         struct alc_spec *spec;
4280         int err, board_config;
4281
4282         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4283         if (spec == NULL)
4284                 return -ENOMEM;
4285
4286         codec->spec = spec;
4287
4288         board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
4289         if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
4290                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4291                            "trying auto-probe from BIOS...\n");
4292                 board_config = ALC260_AUTO;
4293         }
4294
4295         if (board_config == ALC260_AUTO) {
4296                 /* automatic parse from the BIOS config */
4297                 err = alc260_parse_auto_config(codec);
4298                 if (err < 0) {
4299                         alc_free(codec);
4300                         return err;
4301                 } else if (! err) {
4302                         printk(KERN_INFO
4303                                "hda_codec: Cannot set up configuration "
4304                                "from BIOS.  Using base mode...\n");
4305                         board_config = ALC260_BASIC;
4306                 }
4307         }
4308
4309         if (board_config != ALC260_AUTO)
4310                 setup_preset(spec, &alc260_presets[board_config]);
4311
4312         spec->stream_name_analog = "ALC260 Analog";
4313         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4314         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4315
4316         spec->stream_name_digital = "ALC260 Digital";
4317         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4318         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4319
4320         codec->patch_ops = alc_patch_ops;
4321         if (board_config == ALC260_AUTO)
4322                 spec->init_hook = alc260_auto_init;
4323
4324         return 0;
4325 }
4326
4327
4328 /*
4329  * ALC882 support
4330  *
4331  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4332  * configuration.  Each pin widget can choose any input DACs and a mixer.
4333  * Each ADC is connected from a mixer of all inputs.  This makes possible
4334  * 6-channel independent captures.
4335  *
4336  * In addition, an independent DAC for the multi-playback (not used in this
4337  * driver yet).
4338  */
4339 #define ALC882_DIGOUT_NID       0x06
4340 #define ALC882_DIGIN_NID        0x0a
4341
4342 static struct hda_channel_mode alc882_ch_modes[1] = {
4343         { 8, NULL }
4344 };
4345
4346 static hda_nid_t alc882_dac_nids[4] = {
4347         /* front, rear, clfe, rear_surr */
4348         0x02, 0x03, 0x04, 0x05
4349 };
4350
4351 /* identical with ALC880 */
4352 #define alc882_adc_nids         alc880_adc_nids
4353 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4354
4355 /* input MUX */
4356 /* FIXME: should be a matrix-type input source selection */
4357
4358 static struct hda_input_mux alc882_capture_source = {
4359         .num_items = 4,
4360         .items = {
4361                 { "Mic", 0x0 },
4362                 { "Front Mic", 0x1 },
4363                 { "Line", 0x2 },
4364                 { "CD", 0x4 },
4365         },
4366 };
4367 #define alc882_mux_enum_info alc_mux_enum_info
4368 #define alc882_mux_enum_get alc_mux_enum_get
4369
4370 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
4371 {
4372         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4373         struct alc_spec *spec = codec->spec;
4374         const struct hda_input_mux *imux = spec->input_mux;
4375         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4376         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4377         hda_nid_t nid = capture_mixers[adc_idx];
4378         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4379         unsigned int i, idx;
4380
4381         idx = ucontrol->value.enumerated.item[0];
4382         if (idx >= imux->num_items)
4383                 idx = imux->num_items - 1;
4384         if (*cur_val == idx && ! codec->in_resume)
4385                 return 0;
4386         for (i = 0; i < imux->num_items; i++) {
4387                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4388                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4389                                     v | (imux->items[i].index << 8));
4390         }
4391         *cur_val = idx;
4392         return 1;
4393 }
4394
4395 /*
4396  * 6ch mode
4397  */
4398 static struct hda_verb alc882_sixstack_ch6_init[] = {
4399         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4400         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4401         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4402         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4403         { } /* end */
4404 };
4405
4406 /*
4407  * 8ch mode
4408  */
4409 static struct hda_verb alc882_sixstack_ch8_init[] = {
4410         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4411         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4412         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4413         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4414         { } /* end */
4415 };
4416
4417 static struct hda_channel_mode alc882_sixstack_modes[2] = {
4418         { 6, alc882_sixstack_ch6_init },
4419         { 8, alc882_sixstack_ch8_init },
4420 };
4421
4422 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4423  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4424  */
4425 static struct snd_kcontrol_new alc882_base_mixer[] = {
4426         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4427         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4428         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4429         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4430         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4431         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4432         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4433         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4434         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4435         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4436         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4437         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4438         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4439         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4440         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4441         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4442         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4443         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4444         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4445         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4446         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4447         { } /* end */
4448 };
4449
4450 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4451         {
4452                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4453                 .name = "Channel Mode",
4454                 .info = alc_ch_mode_info,
4455                 .get = alc_ch_mode_get,
4456                 .put = alc_ch_mode_put,
4457         },
4458         { } /* end */
4459 };
4460
4461 static struct hda_verb alc882_init_verbs[] = {
4462         /* Front mixer: unmute input/output amp left and right (volume = 0) */
4463         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4464         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4465         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4466         /* Rear mixer */
4467         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4468         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4469         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4470         /* CLFE mixer */
4471         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4472         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4473         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4474         /* Side mixer */
4475         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4476         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4477         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4478
4479         /* Front Pin: output 0 (0x0c) */
4480         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4481         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4482         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4483         /* Rear Pin: output 1 (0x0d) */
4484         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4485         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4486         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4487         /* CLFE Pin: output 2 (0x0e) */
4488         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4489         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4490         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4491         /* Side Pin: output 3 (0x0f) */
4492         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4493         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4494         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4495         /* Mic (rear) pin: input vref at 80% */
4496         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4497         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4498         /* Front Mic pin: input vref at 80% */
4499         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4500         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4501         /* Line In pin: input */
4502         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4503         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4504         /* Line-2 In: Headphone output (output 0 - 0x0c) */
4505         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4506         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4507         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
4508         /* CD pin widget for input */
4509         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4510
4511         /* FIXME: use matrix-type input source selection */
4512         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4513         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4514         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4515         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4516         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4517         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4518         /* Input mixer2 */
4519         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4520         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4521         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4522         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4523         /* Input mixer3 */
4524         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4525         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4526         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4527         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4528         /* ADC1: mute amp left and right */
4529         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4530         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4531         /* ADC2: mute amp left and right */
4532         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4533         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4534         /* ADC3: mute amp left and right */
4535         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4536         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4537
4538         { }
4539 };
4540
4541 static struct hda_verb alc882_eapd_verbs[] = {
4542         /* change to EAPD mode */
4543         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4544         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4545         { } 
4546 };
4547
4548 /*
4549  * generic initialization of ADC, input mixers and output mixers
4550  */
4551 static struct hda_verb alc882_auto_init_verbs[] = {
4552         /*
4553          * Unmute ADC0-2 and set the default input to mic-in
4554          */
4555         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4556         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4557         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4558         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4559         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4560         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4561
4562         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4563          * mixer widget
4564          * Note: PASD motherboards uses the Line In 2 as the input for front panel
4565          * mic (mic 2)
4566          */
4567         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4568         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4569         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4570         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4571         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4572         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4573
4574         /*
4575          * Set up output mixers (0x0c - 0x0f)
4576          */
4577         /* set vol=0 to output mixers */
4578         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4579         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4580         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4581         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4582         /* set up input amps for analog loopback */
4583         /* Amp Indices: DAC = 0, mixer = 1 */
4584         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4585         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4586         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4587         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4588         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4589         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4590         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4591         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4592         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4593         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4594
4595         /* FIXME: use matrix-type input source selection */
4596         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4597         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4598         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4599         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4600         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4601         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4602         /* Input mixer2 */
4603         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4604         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4605         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4606         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4607         /* Input mixer3 */
4608         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4609         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4610         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4611         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4612
4613         { }
4614 };
4615
4616 /* capture mixer elements */
4617 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
4618         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4619         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4620         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
4621         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
4622         {
4623                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4624                 /* The multiple "Capture Source" controls confuse alsamixer
4625                  * So call somewhat different..
4626                  * FIXME: the controls appear in the "playback" view!
4627                  */
4628                 /* .name = "Capture Source", */
4629                 .name = "Input Source",
4630                 .count = 2,
4631                 .info = alc882_mux_enum_info,
4632                 .get = alc882_mux_enum_get,
4633                 .put = alc882_mux_enum_put,
4634         },
4635         { } /* end */
4636 };
4637
4638 static struct snd_kcontrol_new alc882_capture_mixer[] = {
4639         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
4640         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
4641         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
4642         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
4643         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
4644         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
4645         {
4646                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4647                 /* The multiple "Capture Source" controls confuse alsamixer
4648                  * So call somewhat different..
4649                  * FIXME: the controls appear in the "playback" view!
4650                  */
4651                 /* .name = "Capture Source", */
4652                 .name = "Input Source",
4653                 .count = 3,
4654                 .info = alc882_mux_enum_info,
4655                 .get = alc882_mux_enum_get,
4656                 .put = alc882_mux_enum_put,
4657         },
4658         { } /* end */
4659 };
4660
4661 /* pcm configuration: identiacal with ALC880 */
4662 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
4663 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
4664 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
4665 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
4666
4667 /*
4668  * configuration and preset
4669  */
4670 static struct hda_board_config alc882_cfg_tbl[] = {
4671         { .modelname = "3stack-dig", .config = ALC882_3ST_DIG },
4672         { .modelname = "6stack-dig", .config = ALC882_6ST_DIG },
4673         { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668,
4674           .config = ALC882_6ST_DIG }, /* MSI  */
4675         { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668,
4676           .config = ALC882_6ST_DIG }, /* Foxconn */
4677         { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668,
4678           .config = ALC882_6ST_DIG }, /* ECS to Intel*/
4679         { .modelname = "arima", .config = ALC882_ARIMA },
4680         { .pci_subvendor = 0x161f, .pci_subdevice = 0x2054,
4681           .config = ALC882_ARIMA }, /* Arima W820Di1 */
4682         { .modelname = "auto", .config = ALC882_AUTO },
4683         {}
4684 };
4685
4686 static struct alc_config_preset alc882_presets[] = {
4687         [ALC882_3ST_DIG] = {
4688                 .mixers = { alc882_base_mixer },
4689                 .init_verbs = { alc882_init_verbs },
4690                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4691                 .dac_nids = alc882_dac_nids,
4692                 .dig_out_nid = ALC882_DIGOUT_NID,
4693                 .dig_in_nid = ALC882_DIGIN_NID,
4694                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
4695                 .channel_mode = alc882_ch_modes,
4696                 .need_dac_fix = 1,
4697                 .input_mux = &alc882_capture_source,
4698         },
4699         [ALC882_6ST_DIG] = {
4700                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
4701                 .init_verbs = { alc882_init_verbs },
4702                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4703                 .dac_nids = alc882_dac_nids,
4704                 .dig_out_nid = ALC882_DIGOUT_NID,
4705                 .dig_in_nid = ALC882_DIGIN_NID,
4706                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4707                 .channel_mode = alc882_sixstack_modes,
4708                 .input_mux = &alc882_capture_source,
4709         },
4710         [ALC882_ARIMA] = {
4711                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
4712                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
4713                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4714                 .dac_nids = alc882_dac_nids,
4715                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4716                 .channel_mode = alc882_sixstack_modes,
4717                 .input_mux = &alc882_capture_source,
4718         },
4719 };
4720
4721
4722 /*
4723  * BIOS auto configuration
4724  */
4725 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
4726                                               hda_nid_t nid, int pin_type,
4727                                               int dac_idx)
4728 {
4729         /* set as output */
4730         struct alc_spec *spec = codec->spec;
4731         int idx; 
4732         
4733         if (spec->multiout.dac_nids[dac_idx] == 0x25)
4734                 idx = 4;
4735         else
4736                 idx = spec->multiout.dac_nids[dac_idx] - 2;
4737
4738         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
4739         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4740         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
4741
4742 }
4743
4744 static void alc882_auto_init_multi_out(struct hda_codec *codec)
4745 {
4746         struct alc_spec *spec = codec->spec;
4747         int i;
4748
4749         for (i = 0; i <= HDA_SIDE; i++) {
4750                 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 
4751                 if (nid)
4752                         alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
4753         }
4754 }
4755
4756 static void alc882_auto_init_hp_out(struct hda_codec *codec)
4757 {
4758         struct alc_spec *spec = codec->spec;
4759         hda_nid_t pin;
4760
4761         pin = spec->autocfg.hp_pins[0];
4762         if (pin) /* connect to front */
4763                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
4764 }
4765
4766 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
4767 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
4768
4769 static void alc882_auto_init_analog_input(struct hda_codec *codec)
4770 {
4771         struct alc_spec *spec = codec->spec;
4772         int i;
4773
4774         for (i = 0; i < AUTO_PIN_LAST; i++) {
4775                 hda_nid_t nid = spec->autocfg.input_pins[i];
4776                 if (alc882_is_input_pin(nid)) {
4777                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4778                                             i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4779                         if (nid != ALC882_PIN_CD_NID)
4780                                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4781                                                     AMP_OUT_MUTE);
4782                 }
4783         }
4784 }
4785
4786 /* almost identical with ALC880 parser... */
4787 static int alc882_parse_auto_config(struct hda_codec *codec)
4788 {
4789         struct alc_spec *spec = codec->spec;
4790         int err = alc880_parse_auto_config(codec);
4791
4792         if (err < 0)
4793                 return err;
4794         else if (err > 0)
4795                 /* hack - override the init verbs */
4796                 spec->init_verbs[0] = alc882_auto_init_verbs;
4797         return err;
4798 }
4799
4800 /* additional initialization for auto-configuration model */
4801 static void alc882_auto_init(struct hda_codec *codec)
4802 {
4803         alc882_auto_init_multi_out(codec);
4804         alc882_auto_init_hp_out(codec);
4805         alc882_auto_init_analog_input(codec);
4806 }
4807
4808 static int patch_alc882(struct hda_codec *codec)
4809 {
4810         struct alc_spec *spec;
4811         int err, board_config;
4812
4813         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4814         if (spec == NULL)
4815                 return -ENOMEM;
4816
4817         codec->spec = spec;
4818
4819         board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl);
4820
4821         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
4822                 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
4823                        "trying auto-probe from BIOS...\n");
4824                 board_config = ALC882_AUTO;
4825         }
4826
4827         if (board_config == ALC882_AUTO) {
4828                 /* automatic parse from the BIOS config */
4829                 err = alc882_parse_auto_config(codec);
4830                 if (err < 0) {
4831                         alc_free(codec);
4832                         return err;
4833                 } else if (! err) {
4834                         printk(KERN_INFO
4835                                "hda_codec: Cannot set up configuration "
4836                                "from BIOS.  Using base mode...\n");
4837                         board_config = ALC882_3ST_DIG;
4838                 }
4839         }
4840
4841         if (board_config != ALC882_AUTO)
4842                 setup_preset(spec, &alc882_presets[board_config]);
4843
4844         spec->stream_name_analog = "ALC882 Analog";
4845         spec->stream_analog_playback = &alc882_pcm_analog_playback;
4846         spec->stream_analog_capture = &alc882_pcm_analog_capture;
4847
4848         spec->stream_name_digital = "ALC882 Digital";
4849         spec->stream_digital_playback = &alc882_pcm_digital_playback;
4850         spec->stream_digital_capture = &alc882_pcm_digital_capture;
4851
4852         if (! spec->adc_nids && spec->input_mux) {
4853                 /* check whether NID 0x07 is valid */
4854                 unsigned int wcap = get_wcaps(codec, 0x07);
4855                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4856                 if (wcap != AC_WID_AUD_IN) {
4857                         spec->adc_nids = alc882_adc_nids_alt;
4858                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
4859                         spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
4860                         spec->num_mixers++;
4861                 } else {
4862                         spec->adc_nids = alc882_adc_nids;
4863                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
4864                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
4865                         spec->num_mixers++;
4866                 }
4867         }
4868
4869         codec->patch_ops = alc_patch_ops;
4870         if (board_config == ALC882_AUTO)
4871                 spec->init_hook = alc882_auto_init;
4872
4873         return 0;
4874 }
4875
4876 /*
4877  * ALC883 support
4878  *
4879  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
4880  * configuration.  Each pin widget can choose any input DACs and a mixer.
4881  * Each ADC is connected from a mixer of all inputs.  This makes possible
4882  * 6-channel independent captures.
4883  *
4884  * In addition, an independent DAC for the multi-playback (not used in this
4885  * driver yet).
4886  */
4887 #define ALC883_DIGOUT_NID       0x06
4888 #define ALC883_DIGIN_NID        0x0a
4889
4890 static hda_nid_t alc883_dac_nids[4] = {
4891         /* front, rear, clfe, rear_surr */
4892         0x02, 0x04, 0x03, 0x05
4893 };
4894
4895 static hda_nid_t alc883_adc_nids[2] = {
4896         /* ADC1-2 */
4897         0x08, 0x09,
4898 };
4899 /* input MUX */
4900 /* FIXME: should be a matrix-type input source selection */
4901
4902 static struct hda_input_mux alc883_capture_source = {
4903         .num_items = 4,
4904         .items = {
4905                 { "Mic", 0x0 },
4906                 { "Front Mic", 0x1 },
4907                 { "Line", 0x2 },
4908                 { "CD", 0x4 },
4909         },
4910 };
4911 #define alc883_mux_enum_info alc_mux_enum_info
4912 #define alc883_mux_enum_get alc_mux_enum_get
4913
4914 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
4915                                struct snd_ctl_elem_value *ucontrol)
4916 {
4917         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4918         struct alc_spec *spec = codec->spec;
4919         const struct hda_input_mux *imux = spec->input_mux;
4920         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4921         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4922         hda_nid_t nid = capture_mixers[adc_idx];
4923         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4924         unsigned int i, idx;
4925
4926         idx = ucontrol->value.enumerated.item[0];
4927         if (idx >= imux->num_items)
4928                 idx = imux->num_items - 1;
4929         if (*cur_val == idx && ! codec->in_resume)
4930                 return 0;
4931         for (i = 0; i < imux->num_items; i++) {
4932                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4933                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4934                                     v | (imux->items[i].index << 8));
4935         }
4936         *cur_val = idx;
4937         return 1;
4938 }
4939 /*
4940  * 2ch mode
4941  */
4942 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4943         { 2, NULL }
4944 };
4945
4946 /*
4947  * 2ch mode
4948  */
4949 static struct hda_verb alc883_3ST_ch2_init[] = {
4950         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4951         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4952         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4953         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4954         { } /* end */
4955 };
4956
4957 /*
4958  * 6ch mode
4959  */
4960 static struct hda_verb alc883_3ST_ch6_init[] = {
4961         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4962         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4963         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4964         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4965         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4966         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4967         { } /* end */
4968 };
4969
4970 static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
4971         { 2, alc883_3ST_ch2_init },
4972         { 6, alc883_3ST_ch6_init },
4973 };
4974
4975 /*
4976  * 6ch mode
4977  */
4978 static struct hda_verb alc883_sixstack_ch6_init[] = {
4979         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4980         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4981         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4982         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4983         { } /* end */
4984 };
4985
4986 /*
4987  * 8ch mode
4988  */
4989 static struct hda_verb alc883_sixstack_ch8_init[] = {
4990         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4991         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4992         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4993         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4994         { } /* end */
4995 };
4996
4997 static struct hda_channel_mode alc883_sixstack_modes[2] = {
4998         { 6, alc883_sixstack_ch6_init },
4999         { 8, alc883_sixstack_ch8_init },
5000 };
5001
5002 static struct hda_verb alc883_medion_eapd_verbs[] = {
5003         /* eanable EAPD on medion laptop */
5004         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5005         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5006         { }
5007 };
5008
5009 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5010  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5011  */
5012
5013 static struct snd_kcontrol_new alc883_base_mixer[] = {
5014         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5015         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5016         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5017         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5018         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5019         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5020         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5021         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5022         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5023         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5024         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5025         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5026         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5027         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5028         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5029         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5030         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5031         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5032         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5033         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5034         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5035         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5036         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5037         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5038         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5039         {
5040                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5041                 /* .name = "Capture Source", */
5042                 .name = "Input Source",
5043                 .count = 2,
5044                 .info = alc883_mux_enum_info,
5045                 .get = alc883_mux_enum_get,
5046                 .put = alc883_mux_enum_put,
5047         },
5048         { } /* end */
5049 };
5050
5051 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5052         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5053         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5054         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5055         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5056         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5057         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5058         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5059         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5060         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5061         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5062         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5063         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5064         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5065         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5066         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5067         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5068         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5069         {
5070                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5071                 /* .name = "Capture Source", */
5072                 .name = "Input Source",
5073                 .count = 2,
5074                 .info = alc883_mux_enum_info,
5075                 .get = alc883_mux_enum_get,
5076                 .put = alc883_mux_enum_put,
5077         },
5078         { } /* end */
5079 };
5080
5081 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5082         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5083         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5084         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5085         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5086         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5087         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5088         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5089         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5090         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5091         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5092         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5093         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5094         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5095         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5096         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5097         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5098         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5099         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5100         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5101         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5102         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5103         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5104         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5105         {
5106                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5107                 /* .name = "Capture Source", */
5108                 .name = "Input Source",
5109                 .count = 2,
5110                 .info = alc883_mux_enum_info,
5111                 .get = alc883_mux_enum_get,
5112                 .put = alc883_mux_enum_put,
5113         },
5114         { } /* end */
5115 };
5116
5117 static snd_kcontrol_new_t alc883_fivestack_mixer[] = {
5118         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5119         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5120         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5121         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5122         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5123         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5124         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5125         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5126         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5127         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5128         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5129         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5130         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5131         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5132         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5133         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5134         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5135         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5136         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5137         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5138         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5139
5140         {
5141                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5142                 /* .name = "Capture Source", */
5143                 .name = "Input Source",
5144                 .count = 1,
5145                 .info = alc883_mux_enum_info,
5146                 .get = alc883_mux_enum_get,
5147                 .put = alc883_mux_enum_put,
5148         },
5149         { } /* end */
5150 };
5151
5152 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5153         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5154         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5155         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5156         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5157         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5158         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5159         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5160         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5161         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5167         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5168         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5169         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5170         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5171         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5172         {
5173                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5174                 /* .name = "Capture Source", */
5175                 .name = "Input Source",
5176                 .count = 2,
5177                 .info = alc883_mux_enum_info,
5178                 .get = alc883_mux_enum_get,
5179                 .put = alc883_mux_enum_put,
5180         },
5181         { } /* end */
5182 };      
5183
5184 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5185         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5186         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5187         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5188         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5189         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5190         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5191         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5192         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5193         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5194         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5195         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5196         {
5197                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5198                 /* .name = "Capture Source", */
5199                 .name = "Input Source",
5200                 .count = 2,
5201                 .info = alc883_mux_enum_info,
5202                 .get = alc883_mux_enum_get,
5203                 .put = alc883_mux_enum_put,
5204         },
5205         { } /* end */
5206 };      
5207
5208 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
5209         {
5210                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5211                 .name = "Channel Mode",
5212                 .info = alc_ch_mode_info,
5213                 .get = alc_ch_mode_get,
5214                 .put = alc_ch_mode_put,
5215         },
5216         { } /* end */
5217 };
5218
5219 static struct hda_verb alc883_init_verbs[] = {
5220         /* ADC1: mute amp left and right */
5221         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5222         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5223         /* ADC2: mute amp left and right */
5224         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5225         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5226         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5227         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5228         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5229         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5230         /* Rear mixer */
5231         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5232         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5233         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5234         /* CLFE mixer */
5235         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5236         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5237         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5238         /* Side mixer */
5239         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5240         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5241         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5242
5243         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5244         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5245         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5246         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5247         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5248
5249         /* Front Pin: output 0 (0x0c) */
5250         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5251         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5252         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5253         /* Rear Pin: output 1 (0x0d) */
5254         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5255         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5256         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5257         /* CLFE Pin: output 2 (0x0e) */
5258         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5259         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5260         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5261         /* Side Pin: output 3 (0x0f) */
5262         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5263         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5264         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5265         /* Mic (rear) pin: input vref at 80% */
5266         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5267         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5268         /* Front Mic pin: input vref at 80% */
5269         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5270         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5271         /* Line In pin: input */
5272         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5273         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5274         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5275         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5276         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5277         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5278         /* CD pin widget for input */
5279         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5280
5281         /* FIXME: use matrix-type input source selection */
5282         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5283         /* Input mixer2 */
5284         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5285         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5286         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5287         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5288         /* Input mixer3 */
5289         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5290         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5291         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5292         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5293         { }
5294 };
5295
5296 static struct hda_verb alc883_tagra_verbs[] = {
5297         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5298         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5299
5300         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5301         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5302         
5303         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5304         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5305         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5306
5307         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5308         {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 
5309         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 
5310         {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 
5311
5312         { } /* end */
5313 };
5314
5315 /* toggle speaker-output according to the hp-jack state */
5316 static void alc883_tagra_automute(struct hda_codec *codec)
5317 {
5318         unsigned int present;
5319
5320         present = snd_hda_codec_read(codec, 0x14, 0,
5321                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5322         snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5323                                  0x80, present ? 0x80 : 0);
5324         snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5325                                  0x80, present ? 0x80 : 0);
5326         snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5327 }
5328
5329 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
5330 {
5331         if ((res >> 26) == ALC880_HP_EVENT)
5332                 alc883_tagra_automute(codec);
5333 }
5334
5335 /*
5336  * generic initialization of ADC, input mixers and output mixers
5337  */
5338 static struct hda_verb alc883_auto_init_verbs[] = {
5339         /*
5340          * Unmute ADC0-2 and set the default input to mic-in
5341          */
5342         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5343         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5344         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5345         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5346
5347         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5348          * mixer widget
5349          * Note: PASD motherboards uses the Line In 2 as the input for front panel
5350          * mic (mic 2)
5351          */
5352         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5353         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5354         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5355         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5356         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5357         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5358
5359         /*
5360          * Set up output mixers (0x0c - 0x0f)
5361          */
5362         /* set vol=0 to output mixers */
5363         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5364         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5365         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5366         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5367         /* set up input amps for analog loopback */
5368         /* Amp Indices: DAC = 0, mixer = 1 */
5369         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5370         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5371         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5372         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5373         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5374         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5375         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5376         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5377         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5378         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5379
5380         /* FIXME: use matrix-type input source selection */
5381         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5382         /* Input mixer1 */
5383         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5384         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5385         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5386         //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5387         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5388         /* Input mixer2 */
5389         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5390         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5391         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5392         //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5393         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5394
5395         { }
5396 };
5397
5398 /* capture mixer elements */
5399 static struct snd_kcontrol_new alc883_capture_mixer[] = {
5400         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5401         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5402         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5403         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5404         {
5405                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5406                 /* The multiple "Capture Source" controls confuse alsamixer
5407                  * So call somewhat different..
5408                  * FIXME: the controls appear in the "playback" view!
5409                  */
5410                 /* .name = "Capture Source", */
5411                 .name = "Input Source",
5412                 .count = 2,
5413                 .info = alc882_mux_enum_info,
5414                 .get = alc882_mux_enum_get,
5415                 .put = alc882_mux_enum_put,
5416         },
5417         { } /* end */
5418 };
5419
5420 /* pcm configuration: identiacal with ALC880 */
5421 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
5422 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
5423 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
5424 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
5425
5426 /*
5427  * configuration and preset
5428  */
5429 static struct hda_board_config alc883_cfg_tbl[] = {
5430         { .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG },
5431         { .modelname = "3stack-6ch-dig", .config = ALC883_3ST_6ch_DIG },
5432         { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668,
5433           .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/
5434         { .modelname = "3stack-6ch", .config = ALC883_3ST_6ch },
5435         { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d,
5436           .config = ALC883_3ST_6ch }, 
5437         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd601,
5438           .config = ALC883_3ST_6ch }, /* D102GGC */
5439         { .modelname = "6stack-dig", .config = ALC883_6ST_DIG },
5440         { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668,
5441           .config = ALC883_6ST_DIG }, /* MSI  */
5442         { .pci_subvendor = 0x1462, .pci_subdevice = 0x7280,
5443           .config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */
5444         { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668,
5445           .config = ALC883_6ST_DIG }, /* Foxconn */
5446         { .pci_subvendor = 0x1462, .pci_subdevice = 0x7187,
5447           .config = ALC883_6ST_DIG }, /* MSI */
5448         { .modelname = "targa-dig", .config = ALC883_TARGA_DIG },
5449         { .pci_subvendor = 0x1462, .pci_subdevice = 0x4314,
5450           .config = ALC883_TARGA_DIG }, /* MSI */
5451         { .pci_subvendor = 0x1462, .pci_subdevice = 0x3fcc,
5452           .config = ALC883_TARGA_DIG }, /* MSI */
5453         { .pci_subvendor = 0x1462, .pci_subdevice = 0x3fc1,
5454           .config = ALC883_TARGA_DIG }, /* MSI */
5455         { .pci_subvendor = 0x1462, .pci_subdevice = 0x3fc3,
5456           .config = ALC883_TARGA_DIG }, /* MSI */
5457         { .pci_subvendor = 0x1462, .pci_subdevice = 0x4314,
5458           .config = ALC883_TARGA_DIG }, /* MSI */
5459         { .pci_subvendor = 0x1462, .pci_subdevice = 0x4319,
5460           .config = ALC883_TARGA_DIG }, /* MSI */
5461         { .pci_subvendor = 0x1462, .pci_subdevice = 0x3ef9,
5462           .config = ALC883_TARGA_DIG }, /* MSI */
5463         { .pci_subvendor = 0x1462, .pci_subdevice = 0x4324,
5464           .config = ALC883_TARGA_DIG }, /* MSI */
5465         { .modelname = "targa-2ch-dig", .config = ALC883_TARGA_2ch_DIG },
5466         { .pci_subvendor = 0x1462, .pci_subdevice = 0x0579,
5467           .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5468         { .pci_subvendor = 0x1462, .pci_subdevice = 0xa422,
5469           .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5470         { .pci_subvendor = 0x1462, .pci_subdevice = 0x3b7f,
5471           .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5472         { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD },
5473         { .modelname = "acer", .config = ALC883_ACER },
5474         { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/,
5475           .config = ALC883_ACER },
5476         { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102,
5477           .config = ALC883_ACER },
5478         { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f,
5479           .config = ALC883_ACER },
5480         { .pci_subvendor = 0x161f, .pci_subdevice = 0x2054,
5481           .modelname = "medion", .config = ALC883_MEDION },
5482         { .modelname = "laptop-eapd", .config = ALC883_LAPTOP_EAPD },
5483         { .pci_subvendor = 0x1558, .pci_subdevice = 0,
5484           .config = ALC883_LAPTOP_EAPD }, /* Clevo */
5485         { .modelname = "auto", .config = ALC883_AUTO },
5486         {}
5487 };
5488
5489 static struct alc_config_preset alc883_presets[] = {
5490         [ALC883_3ST_2ch_DIG] = {
5491                 .mixers = { alc883_3ST_2ch_mixer },
5492                 .init_verbs = { alc883_init_verbs },
5493                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5494                 .dac_nids = alc883_dac_nids,
5495                 .dig_out_nid = ALC883_DIGOUT_NID,
5496                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5497                 .adc_nids = alc883_adc_nids,
5498                 .dig_in_nid = ALC883_DIGIN_NID,
5499                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5500                 .channel_mode = alc883_3ST_2ch_modes,
5501                 .input_mux = &alc883_capture_source,
5502         },
5503         [ALC883_3ST_6ch_DIG] = {
5504                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
5505                 .init_verbs = { alc883_init_verbs },
5506                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5507                 .dac_nids = alc883_dac_nids,
5508                 .dig_out_nid = ALC883_DIGOUT_NID,
5509                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5510                 .adc_nids = alc883_adc_nids,
5511                 .dig_in_nid = ALC883_DIGIN_NID,
5512                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5513                 .channel_mode = alc883_3ST_6ch_modes,
5514                 .need_dac_fix = 1,
5515                 .input_mux = &alc883_capture_source,
5516         },      
5517         [ALC883_3ST_6ch] = {
5518                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
5519                 .init_verbs = { alc883_init_verbs },
5520                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5521                 .dac_nids = alc883_dac_nids,
5522                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5523                 .adc_nids = alc883_adc_nids,
5524                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5525                 .channel_mode = alc883_3ST_6ch_modes,
5526                 .need_dac_fix = 1,
5527                 .input_mux = &alc883_capture_source,
5528         },      
5529         [ALC883_6ST_DIG] = {
5530                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5531                 .init_verbs = { alc883_init_verbs },
5532                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5533                 .dac_nids = alc883_dac_nids,
5534                 .dig_out_nid = ALC883_DIGOUT_NID,
5535                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5536                 .adc_nids = alc883_adc_nids,
5537                 .dig_in_nid = ALC883_DIGIN_NID,
5538                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5539                 .channel_mode = alc883_sixstack_modes,
5540                 .input_mux = &alc883_capture_source,
5541         },
5542         [ALC883_TARGA_DIG] = {
5543                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
5544                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5545                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5546                 .dac_nids = alc883_dac_nids,
5547                 .dig_out_nid = ALC883_DIGOUT_NID,
5548                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5549                 .adc_nids = alc883_adc_nids,
5550                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5551                 .channel_mode = alc883_3ST_6ch_modes,
5552                 .need_dac_fix = 1,
5553                 .input_mux = &alc883_capture_source,
5554                 .unsol_event = alc883_tagra_unsol_event,
5555                 .init_hook = alc883_tagra_automute,
5556         },
5557         [ALC883_TARGA_2ch_DIG] = {
5558                 .mixers = { alc883_tagra_2ch_mixer},
5559                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5560                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5561                 .dac_nids = alc883_dac_nids,
5562                 .dig_out_nid = ALC883_DIGOUT_NID,
5563                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5564                 .adc_nids = alc883_adc_nids,
5565                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5566                 .channel_mode = alc883_3ST_2ch_modes,
5567                 .input_mux = &alc883_capture_source,
5568                 .unsol_event = alc883_tagra_unsol_event,
5569                 .init_hook = alc883_tagra_automute,
5570         },
5571         [ALC888_DEMO_BOARD] = {
5572                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5573                 .init_verbs = { alc883_init_verbs },
5574                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5575                 .dac_nids = alc883_dac_nids,
5576                 .dig_out_nid = ALC883_DIGOUT_NID,
5577                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5578                 .adc_nids = alc883_adc_nids,
5579                 .dig_in_nid = ALC883_DIGIN_NID,
5580                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5581                 .channel_mode = alc883_sixstack_modes,
5582                 .input_mux = &alc883_capture_source,
5583         },
5584         [ALC883_ACER] = {
5585                 .mixers = { alc883_base_mixer,
5586                             alc883_chmode_mixer },
5587                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
5588                  * and the headphone jack.  Turn this on and rely on the
5589                  * standard mute methods whenever the user wants to turn
5590                  * these outputs off.
5591                  */
5592                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
5593                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5594                 .dac_nids = alc883_dac_nids,
5595                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5596                 .adc_nids = alc883_adc_nids,
5597                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5598                 .channel_mode = alc883_3ST_2ch_modes,
5599                 .input_mux = &alc883_capture_source,
5600         },
5601         [ALC883_MEDION] = {
5602                 .mixers = { alc883_fivestack_mixer,
5603                             alc883_chmode_mixer },
5604                 .init_verbs = { alc883_init_verbs,
5605                                 alc883_medion_eapd_verbs },
5606                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5607                 .dac_nids = alc883_dac_nids,
5608                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5609                 .adc_nids = alc883_adc_nids,
5610                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5611                 .channel_mode = alc883_sixstack_modes,
5612                 .input_mux = &alc883_capture_source,
5613         },
5614         [ALC883_LAPTOP_EAPD] = {
5615                 .mixers = { alc883_base_mixer,
5616                             alc883_chmode_mixer },
5617                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
5618                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5619                 .dac_nids = alc883_dac_nids,
5620                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5621                 .adc_nids = alc883_adc_nids,
5622                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5623                 .channel_mode = alc883_3ST_2ch_modes,
5624                 .input_mux = &alc883_capture_source,
5625         },
5626 };
5627
5628
5629 /*
5630  * BIOS auto configuration
5631  */
5632 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
5633                                               hda_nid_t nid, int pin_type,
5634                                               int dac_idx)
5635 {
5636         /* set as output */
5637         struct alc_spec *spec = codec->spec;
5638         int idx; 
5639         
5640         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5641                 idx = 4;
5642         else
5643                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5644
5645         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5646                             pin_type);
5647         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5648                             AMP_OUT_UNMUTE);
5649         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5650
5651 }
5652
5653 static void alc883_auto_init_multi_out(struct hda_codec *codec)
5654 {
5655         struct alc_spec *spec = codec->spec;
5656         int i;
5657
5658         for (i = 0; i <= HDA_SIDE; i++) {
5659                 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 
5660                 if (nid)
5661                         alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
5662         }
5663 }
5664
5665 static void alc883_auto_init_hp_out(struct hda_codec *codec)
5666 {
5667         struct alc_spec *spec = codec->spec;
5668         hda_nid_t pin;
5669
5670         pin = spec->autocfg.hp_pins[0];
5671         if (pin) /* connect to front */
5672                 /* use dac 0 */
5673                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5674 }
5675
5676 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
5677 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
5678
5679 static void alc883_auto_init_analog_input(struct hda_codec *codec)
5680 {
5681         struct alc_spec *spec = codec->spec;
5682         int i;
5683
5684         for (i = 0; i < AUTO_PIN_LAST; i++) {
5685                 hda_nid_t nid = spec->autocfg.input_pins[i];
5686                 if (alc883_is_input_pin(nid)) {
5687                         snd_hda_codec_write(codec, nid, 0,
5688                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5689                                             (i <= AUTO_PIN_FRONT_MIC ?
5690                                              PIN_VREF80 : PIN_IN));
5691                         if (nid != ALC883_PIN_CD_NID)
5692                                 snd_hda_codec_write(codec, nid, 0,
5693                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5694                                                     AMP_OUT_MUTE);
5695                 }
5696         }
5697 }
5698
5699 /* almost identical with ALC880 parser... */
5700 static int alc883_parse_auto_config(struct hda_codec *codec)
5701 {
5702         struct alc_spec *spec = codec->spec;
5703         int err = alc880_parse_auto_config(codec);
5704
5705         if (err < 0)
5706                 return err;
5707         else if (err > 0)
5708                 /* hack - override the init verbs */
5709                 spec->init_verbs[0] = alc883_auto_init_verbs;
5710                 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
5711                 spec->num_mixers++;
5712         return err;
5713 }
5714
5715 /* additional initialization for auto-configuration model */
5716 static void alc883_auto_init(struct hda_codec *codec)
5717 {
5718         alc883_auto_init_multi_out(codec);
5719         alc883_auto_init_hp_out(codec);
5720         alc883_auto_init_analog_input(codec);
5721 }
5722
5723 static int patch_alc883(struct hda_codec *codec)
5724 {
5725         struct alc_spec *spec;
5726         int err, board_config;
5727
5728         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5729         if (spec == NULL)
5730                 return -ENOMEM;
5731
5732         codec->spec = spec;
5733
5734         board_config = snd_hda_check_board_config(codec, alc883_cfg_tbl);
5735         if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
5736                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
5737                        "trying auto-probe from BIOS...\n");
5738                 board_config = ALC883_AUTO;
5739         }
5740
5741         if (board_config == ALC883_AUTO) {
5742                 /* automatic parse from the BIOS config */
5743                 err = alc883_parse_auto_config(codec);
5744                 if (err < 0) {
5745                         alc_free(codec);
5746                         return err;
5747                 } else if (! err) {
5748                         printk(KERN_INFO
5749                                "hda_codec: Cannot set up configuration "
5750                                "from BIOS.  Using base mode...\n");
5751                         board_config = ALC883_3ST_2ch_DIG;
5752                 }
5753         }
5754
5755         if (board_config != ALC883_AUTO)
5756                 setup_preset(spec, &alc883_presets[board_config]);
5757
5758         spec->stream_name_analog = "ALC883 Analog";
5759         spec->stream_analog_playback = &alc883_pcm_analog_playback;
5760         spec->stream_analog_capture = &alc883_pcm_analog_capture;
5761
5762         spec->stream_name_digital = "ALC883 Digital";
5763         spec->stream_digital_playback = &alc883_pcm_digital_playback;
5764         spec->stream_digital_capture = &alc883_pcm_digital_capture;
5765
5766         if (! spec->adc_nids && spec->input_mux) {
5767                 spec->adc_nids = alc883_adc_nids;
5768                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
5769         }
5770
5771         codec->patch_ops = alc_patch_ops;
5772         if (board_config == ALC883_AUTO)
5773                 spec->init_hook = alc883_auto_init;
5774
5775         return 0;
5776 }
5777
5778 /*
5779  * ALC262 support
5780  */
5781
5782 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
5783 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
5784
5785 #define alc262_dac_nids         alc260_dac_nids
5786 #define alc262_adc_nids         alc882_adc_nids
5787 #define alc262_adc_nids_alt     alc882_adc_nids_alt
5788
5789 #define alc262_modes            alc260_modes
5790 #define alc262_capture_source   alc882_capture_source
5791
5792 static struct snd_kcontrol_new alc262_base_mixer[] = {
5793         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5794         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5795         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5796         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5797         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5798         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5799         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5800         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5801         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5802         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5803         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5804            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
5805         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
5806         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5807         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5808         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5809         { } /* end */
5810 };
5811
5812 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
5813         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5814         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5815         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5816         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5817         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5818         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5819         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5820         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5821         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5822         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5823         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5824            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
5825         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
5826         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5827         { } /* end */
5828 };
5829
5830 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
5831         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5832         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5833         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5834         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5835         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5836
5837         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5838         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5839         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5840         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5841         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5842         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5843         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5844         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5845         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5846         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
5847         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
5848         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
5849         { } /* end */
5850 };
5851
5852 #define alc262_capture_mixer            alc882_capture_mixer
5853 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
5854
5855 /*
5856  * generic initialization of ADC, input mixers and output mixers
5857  */
5858 static struct hda_verb alc262_init_verbs[] = {
5859         /*
5860          * Unmute ADC0-2 and set the default input to mic-in
5861          */
5862         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5863         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5864         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5865         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5866         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5867         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5868
5869         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5870          * mixer widget
5871          * Note: PASD motherboards uses the Line In 2 as the input for front panel
5872          * mic (mic 2)
5873          */
5874         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5875         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5876         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5877         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5878         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5879         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5880
5881         /*
5882          * Set up output mixers (0x0c - 0x0e)
5883          */
5884         /* set vol=0 to output mixers */
5885         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5886         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5887         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5888         /* set up input amps for analog loopback */
5889         /* Amp Indices: DAC = 0, mixer = 1 */
5890         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5891         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5892         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5893         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5894         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5895         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5896
5897         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5898         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5899         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5900         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5901         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5902         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5903
5904         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5905         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5906         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5907         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5908         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5909         
5910         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5911         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5912         
5913         /* FIXME: use matrix-type input source selection */
5914         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5915         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5916         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5917         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5918         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5919         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5920         /* Input mixer2 */
5921         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5922         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5923         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5924         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5925         /* Input mixer3 */
5926         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5927         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5928         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5929         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},      
5930
5931         { }
5932 };
5933
5934 static struct hda_verb alc262_hippo_unsol_verbs[] = {
5935         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5936         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5937         {}
5938 };
5939
5940 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
5941         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5942         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5943         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5944
5945         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5946         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5947         {}
5948 };
5949
5950 /* mute/unmute internal speaker according to the hp jack and mute state */
5951 static void alc262_hippo_automute(struct hda_codec *codec, int force)
5952 {
5953         struct alc_spec *spec = codec->spec;
5954         unsigned int mute;
5955
5956         if (force || ! spec->sense_updated) {
5957                 unsigned int present;
5958                 /* need to execute and sync at first */
5959                 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
5960                 present = snd_hda_codec_read(codec, 0x15, 0,
5961                                          AC_VERB_GET_PIN_SENSE, 0);
5962                 spec->jack_present = (present & 0x80000000) != 0;
5963                 spec->sense_updated = 1;
5964         }
5965         if (spec->jack_present) {
5966                 /* mute internal speaker */
5967                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5968                                          0x80, 0x80);
5969                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5970                                          0x80, 0x80);
5971         } else {
5972                 /* unmute internal speaker if necessary */
5973                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
5974                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5975                                          0x80, mute & 0x80);
5976                 mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
5977                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5978                                          0x80, mute & 0x80);
5979         }
5980 }
5981
5982 /* unsolicited event for HP jack sensing */
5983 static void alc262_hippo_unsol_event(struct hda_codec *codec,
5984                                        unsigned int res)
5985 {
5986         if ((res >> 26) != ALC880_HP_EVENT)
5987                 return;
5988         alc262_hippo_automute(codec, 1);
5989 }
5990
5991 static void alc262_hippo1_automute(struct hda_codec *codec, int force)
5992 {
5993         struct alc_spec *spec = codec->spec;
5994         unsigned int mute;
5995
5996         if (force || ! spec->sense_updated) {
5997                 unsigned int present;
5998                 /* need to execute and sync at first */
5999                 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
6000                 present = snd_hda_codec_read(codec, 0x1b, 0,
6001                                          AC_VERB_GET_PIN_SENSE, 0);
6002                 spec->jack_present = (present & 0x80000000) != 0;
6003                 spec->sense_updated = 1;
6004         }
6005         if (spec->jack_present) {
6006                 /* mute internal speaker */
6007                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6008                                          0x80, 0x80);
6009                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6010                                          0x80, 0x80);
6011         } else {
6012                 /* unmute internal speaker if necessary */
6013                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
6014                 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6015                                          0x80, mute & 0x80);
6016                 mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
6017                 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6018                                          0x80, mute & 0x80);
6019         }
6020 }
6021
6022 /* unsolicited event for HP jack sensing */
6023 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
6024                                        unsigned int res)
6025 {
6026         if ((res >> 26) != ALC880_HP_EVENT)
6027                 return;
6028         alc262_hippo1_automute(codec, 1);
6029 }
6030
6031 /*
6032  * fujitsu model
6033  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
6034  */
6035
6036 #define ALC_HP_EVENT    0x37
6037
6038 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
6039         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
6040         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6041         {}
6042 };
6043
6044 static struct hda_input_mux alc262_fujitsu_capture_source = {
6045         .num_items = 2,
6046         .items = {
6047                 { "Mic", 0x0 },
6048                 { "CD", 0x4 },
6049         },
6050 };
6051
6052 static struct hda_input_mux alc262_HP_capture_source = {
6053         .num_items = 5,
6054         .items = {
6055                 { "Mic", 0x0 },
6056                 { "Front Mic", 0x3 },
6057                 { "Line", 0x2 },
6058                 { "CD", 0x4 },
6059                 { "AUX IN", 0x6 },
6060         },
6061 };
6062
6063 /* mute/unmute internal speaker according to the hp jack and mute state */
6064 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
6065 {
6066         struct alc_spec *spec = codec->spec;
6067         unsigned int mute;
6068
6069         if (force || ! spec->sense_updated) {
6070                 unsigned int present;
6071                 /* need to execute and sync at first */
6072                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
6073                 present = snd_hda_codec_read(codec, 0x14, 0,
6074                                          AC_VERB_GET_PIN_SENSE, 0);
6075                 spec->jack_present = (present & 0x80000000) != 0;
6076                 spec->sense_updated = 1;
6077         }
6078         if (spec->jack_present) {
6079                 /* mute internal speaker */
6080                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6081                                          0x80, 0x80);
6082                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6083                                          0x80, 0x80);
6084         } else {
6085                 /* unmute internal speaker if necessary */
6086                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
6087                 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6088                                          0x80, mute & 0x80);
6089                 mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
6090                 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6091                                          0x80, mute & 0x80);
6092         }
6093 }
6094
6095 /* unsolicited event for HP jack sensing */
6096 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
6097                                        unsigned int res)
6098 {
6099         if ((res >> 26) != ALC_HP_EVENT)
6100                 return;
6101         alc262_fujitsu_automute(codec, 1);
6102 }
6103
6104 /* bind volumes of both NID 0x0c and 0x0d */
6105 static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
6106                                          struct snd_ctl_elem_value *ucontrol)
6107 {
6108         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6109         long *valp = ucontrol->value.integer.value;
6110         int change;
6111
6112         change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
6113                                           0x7f, valp[0] & 0x7f);
6114         change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
6115                                            0x7f, valp[1] & 0x7f);
6116         snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
6117                                  0x7f, valp[0] & 0x7f);
6118         snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
6119                                  0x7f, valp[1] & 0x7f);
6120         return change;
6121 }
6122
6123 /* bind hp and internal speaker mute (with plug check) */
6124 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
6125                                          struct snd_ctl_elem_value *ucontrol)
6126 {
6127         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6128         long *valp = ucontrol->value.integer.value;
6129         int change;
6130
6131         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6132                                           0x80, valp[0] ? 0 : 0x80);
6133         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6134                                            0x80, valp[1] ? 0 : 0x80);
6135         if (change || codec->in_resume)
6136                 alc262_fujitsu_automute(codec, codec->in_resume);
6137         return change;
6138 }
6139
6140 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
6141         {
6142                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6143                 .name = "Master Playback Volume",
6144                 .info = snd_hda_mixer_amp_volume_info,
6145                 .get = snd_hda_mixer_amp_volume_get,
6146                 .put = alc262_fujitsu_master_vol_put,
6147                 .tlv = { .c = snd_hda_mixer_amp_tlv },
6148                 .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
6149         },
6150         {
6151                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6152                 .name = "Master Playback Switch",
6153                 .info = snd_hda_mixer_amp_switch_info,
6154                 .get = snd_hda_mixer_amp_switch_get,
6155                 .put = alc262_fujitsu_master_sw_put,
6156                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
6157         },
6158         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6159         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6160         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6161         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6162         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6163         { } /* end */
6164 };
6165
6166 /* additional init verbs for Benq laptops */
6167 static struct hda_verb alc262_EAPD_verbs[] = {
6168         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6169         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
6170         {}
6171 };
6172
6173 /* add playback controls from the parsed DAC table */
6174 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
6175 {
6176         hda_nid_t nid;
6177         int err;
6178
6179         spec->multiout.num_dacs = 1;    /* only use one dac */
6180         spec->multiout.dac_nids = spec->private_dac_nids;
6181         spec->multiout.dac_nids[0] = 2;
6182
6183         nid = cfg->line_out_pins[0];
6184         if (nid) {
6185                 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
6186                                        HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
6187                         return err;
6188                 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
6189                                        HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6190                         return err;
6191         }
6192
6193         nid = cfg->speaker_pins[0];
6194         if (nid) {
6195                 if (nid == 0x16) {
6196                         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
6197                                                HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
6198                                 return err;
6199                         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
6200                                                HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
6201                                 return err;
6202                 } else {
6203                         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
6204                                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6205                                 return err;
6206                 }
6207         }
6208         nid = cfg->hp_pins[0];
6209         if (nid) {
6210                 /* spec->multiout.hp_nid = 2; */
6211                 if (nid == 0x16) {
6212                         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
6213                                                HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
6214                                 return err;
6215                         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
6216                                                HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
6217                                 return err;
6218                 } else {
6219                         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
6220                                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6221                                 return err;
6222                 }
6223         }
6224         return 0;       
6225 }
6226
6227 /* identical with ALC880 */
6228 #define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
6229
6230 /*
6231  * generic initialization of ADC, input mixers and output mixers
6232  */
6233 static struct hda_verb alc262_volume_init_verbs[] = {
6234         /*
6235          * Unmute ADC0-2 and set the default input to mic-in
6236          */
6237         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6238         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6239         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6240         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6241         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6242         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6243
6244         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6245          * mixer widget
6246          * Note: PASD motherboards uses the Line In 2 as the input for front panel
6247          * mic (mic 2)
6248          */
6249         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6250         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6251         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6252         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6253         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6254         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6255
6256         /*
6257          * Set up output mixers (0x0c - 0x0f)
6258          */
6259         /* set vol=0 to output mixers */
6260         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6261         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6262         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6263         
6264         /* set up input amps for analog loopback */
6265         /* Amp Indices: DAC = 0, mixer = 1 */
6266         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6267         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6268         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6269         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6270         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6271         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6272
6273         /* FIXME: use matrix-type input source selection */
6274         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6275         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6276         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6277         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6278         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6279         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6280         /* Input mixer2 */
6281         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6282         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6283         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6284         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6285         /* Input mixer3 */
6286         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6287         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6288         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6289         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6290
6291         { }
6292 };
6293
6294 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
6295         /*
6296          * Unmute ADC0-2 and set the default input to mic-in
6297          */
6298         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6299         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6300         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6301         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6302         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6303         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6304
6305         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6306          * mixer widget
6307          * Note: PASD motherboards uses the Line In 2 as the input for front panel
6308          * mic (mic 2)
6309          */
6310         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6311         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6312         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6313         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6314         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6315         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6316         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
6317         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
6318         
6319         /*
6320          * Set up output mixers (0x0c - 0x0e)
6321          */
6322         /* set vol=0 to output mixers */
6323         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6324         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6325         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6326
6327         /* set up input amps for analog loopback */
6328         /* Amp Indices: DAC = 0, mixer = 1 */
6329         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6330         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6331         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6332         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6333         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6334         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6335
6336         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6337         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6338         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6339
6340         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6341         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6342
6343         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6344         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6345
6346         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6347         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6348         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6349         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6350         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6351
6352         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
6353         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6354         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6355         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
6356         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6357         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6358
6359
6360         /* FIXME: use matrix-type input source selection */
6361         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6362         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6363         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6364         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6365         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6366         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6367         /* Input mixer2 */
6368         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6369         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6370         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6371         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6372         /* Input mixer3 */
6373         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6374         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6375         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6376         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6377
6378         { }
6379 };
6380
6381 /* pcm configuration: identiacal with ALC880 */
6382 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
6383 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
6384 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
6385 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
6386
6387 /*
6388  * BIOS auto configuration
6389  */
6390 static int alc262_parse_auto_config(struct hda_codec *codec)
6391 {
6392         struct alc_spec *spec = codec->spec;
6393         int err;
6394         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
6395
6396         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6397                                                 alc262_ignore)) < 0)
6398                 return err;
6399         if (! spec->autocfg.line_outs)
6400                 return 0; /* can't find valid BIOS pin config */
6401         if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
6402             (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
6403                 return err;
6404
6405         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6406
6407         if (spec->autocfg.dig_out_pin)
6408                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
6409         if (spec->autocfg.dig_in_pin)
6410                 spec->dig_in_nid = ALC262_DIGIN_NID;
6411
6412         if (spec->kctl_alloc)
6413                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
6414
6415         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
6416         spec->num_mux_defs = 1;
6417         spec->input_mux = &spec->private_imux;
6418
6419         return 1;
6420 }
6421
6422 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
6423 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
6424 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
6425
6426
6427 /* init callback for auto-configuration model -- overriding the default init */
6428 static void alc262_auto_init(struct hda_codec *codec)
6429 {
6430         alc262_auto_init_multi_out(codec);
6431         alc262_auto_init_hp_out(codec);
6432         alc262_auto_init_analog_input(codec);
6433 }
6434
6435 /*
6436  * configuration and preset
6437  */
6438 static struct hda_board_config alc262_cfg_tbl[] = {
6439         { .modelname = "basic", .config = ALC262_BASIC },
6440         { .modelname = "hippo",
6441           .pci_subvendor =0x1002, .pci_subdevice = 0x437b,
6442           .config = ALC262_HIPPO},
6443         { .modelname = "hippo",
6444           .pci_subvendor = 0x104d, .pci_subdevice = 0x8203,
6445           .config = ALC262_HIPPO }, /* Sony UX-90s */
6446         { .modelname = "hippo_1",
6447           .pci_subvendor =0x17ff, .pci_subdevice = 0x058f,
6448           .config = ALC262_HIPPO_1},
6449         { .modelname = "fujitsu", .config = ALC262_FUJITSU },
6450         { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397,
6451           .config = ALC262_FUJITSU },
6452         { .modelname = "hp-bpc", .config = ALC262_HP_BPC },
6453         { .pci_subvendor = 0x103c, .pci_subdevice = 0x280c,
6454           .config = ALC262_HP_BPC }, /* xw4400 */
6455         { .pci_subvendor = 0x103c, .pci_subdevice = 0x2801,
6456           .config = ALC262_HP_BPC }, /* q965 */
6457         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014,
6458           .config = ALC262_HP_BPC }, /* xw6400 */
6459         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015,
6460           .config = ALC262_HP_BPC }, /* xw8400 */
6461         { .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe,
6462           .config = ALC262_HP_BPC }, /* xw9400 */
6463         { .modelname = "benq", .config = ALC262_BENQ_ED8 },
6464         { .pci_subvendor = 0x17ff, .pci_subdevice = 0x0560,
6465           .config = ALC262_BENQ_ED8 },
6466         { .modelname = "auto", .config = ALC262_AUTO },
6467         {}
6468 };
6469
6470 static struct alc_config_preset alc262_presets[] = {
6471         [ALC262_BASIC] = {
6472                 .mixers = { alc262_base_mixer },
6473                 .init_verbs = { alc262_init_verbs },
6474                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6475                 .dac_nids = alc262_dac_nids,
6476                 .hp_nid = 0x03,
6477                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6478                 .channel_mode = alc262_modes,
6479                 .input_mux = &alc262_capture_source,
6480         },
6481         [ALC262_HIPPO] = {
6482                 .mixers = { alc262_base_mixer },
6483                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
6484                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6485                 .dac_nids = alc262_dac_nids,
6486                 .hp_nid = 0x03,
6487                 .dig_out_nid = ALC262_DIGOUT_NID,
6488                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6489                 .channel_mode = alc262_modes,
6490                 .input_mux = &alc262_capture_source,
6491                 .unsol_event = alc262_hippo_unsol_event,
6492         },
6493         [ALC262_HIPPO_1] = {
6494                 .mixers = { alc262_hippo1_mixer },
6495                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
6496                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6497                 .dac_nids = alc262_dac_nids,
6498                 .hp_nid = 0x02,
6499                 .dig_out_nid = ALC262_DIGOUT_NID,
6500                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6501                 .channel_mode = alc262_modes,
6502                 .input_mux = &alc262_capture_source,
6503                 .unsol_event = alc262_hippo1_unsol_event,
6504         },
6505         [ALC262_FUJITSU] = {
6506                 .mixers = { alc262_fujitsu_mixer },
6507                 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
6508                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6509                 .dac_nids = alc262_dac_nids,
6510                 .hp_nid = 0x03,
6511                 .dig_out_nid = ALC262_DIGOUT_NID,
6512                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6513                 .channel_mode = alc262_modes,
6514                 .input_mux = &alc262_fujitsu_capture_source,
6515                 .unsol_event = alc262_fujitsu_unsol_event,
6516         },
6517         [ALC262_HP_BPC] = {
6518                 .mixers = { alc262_HP_BPC_mixer },
6519                 .init_verbs = { alc262_HP_BPC_init_verbs },
6520                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6521                 .dac_nids = alc262_dac_nids,
6522                 .hp_nid = 0x03,
6523                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6524                 .channel_mode = alc262_modes,
6525                 .input_mux = &alc262_HP_capture_source,
6526         },      
6527         [ALC262_BENQ_ED8] = {
6528                 .mixers = { alc262_base_mixer },
6529                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
6530                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6531                 .dac_nids = alc262_dac_nids,
6532                 .hp_nid = 0x03,
6533                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6534                 .channel_mode = alc262_modes,
6535                 .input_mux = &alc262_capture_source,
6536         },              
6537 };
6538
6539 static int patch_alc262(struct hda_codec *codec)
6540 {
6541         struct alc_spec *spec;
6542         int board_config;
6543         int err;
6544
6545         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
6546         if (spec == NULL)
6547                 return -ENOMEM;
6548
6549         codec->spec = spec;
6550 #if 0
6551         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is under-run */
6552         {
6553         int tmp;
6554         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
6555         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
6556         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
6557         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
6558         }
6559 #endif
6560
6561         board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl);
6562         
6563         if (board_config < 0 || board_config >= ALC262_MODEL_LAST) {
6564                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
6565                        "trying auto-probe from BIOS...\n");
6566                 board_config = ALC262_AUTO;
6567         }
6568
6569         if (board_config == ALC262_AUTO) {
6570                 /* automatic parse from the BIOS config */
6571                 err = alc262_parse_auto_config(codec);
6572                 if (err < 0) {
6573                         alc_free(codec);
6574                         return err;
6575                 } else if (! err) {
6576                         printk(KERN_INFO
6577                                "hda_codec: Cannot set up configuration "
6578                                "from BIOS.  Using base mode...\n");
6579                         board_config = ALC262_BASIC;
6580                 }
6581         }
6582
6583         if (board_config != ALC262_AUTO)
6584                 setup_preset(spec, &alc262_presets[board_config]);
6585
6586         spec->stream_name_analog = "ALC262 Analog";
6587         spec->stream_analog_playback = &alc262_pcm_analog_playback;
6588         spec->stream_analog_capture = &alc262_pcm_analog_capture;
6589                 
6590         spec->stream_name_digital = "ALC262 Digital";
6591         spec->stream_digital_playback = &alc262_pcm_digital_playback;
6592         spec->stream_digital_capture = &alc262_pcm_digital_capture;
6593
6594         if (! spec->adc_nids && spec->input_mux) {
6595                 /* check whether NID 0x07 is valid */
6596                 unsigned int wcap = get_wcaps(codec, 0x07);
6597
6598                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
6599                 if (wcap != AC_WID_AUD_IN) {
6600                         spec->adc_nids = alc262_adc_nids_alt;
6601                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
6602                         spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
6603                         spec->num_mixers++;
6604                 } else {
6605                         spec->adc_nids = alc262_adc_nids;
6606                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
6607                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
6608                         spec->num_mixers++;
6609                 }
6610         }
6611
6612         codec->patch_ops = alc_patch_ops;
6613         if (board_config == ALC262_AUTO)
6614                 spec->init_hook = alc262_auto_init;
6615                 
6616         return 0;
6617 }
6618
6619 /*
6620  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
6621  */
6622
6623 /*
6624  * set the path ways for 2 channel output
6625  * need to set the codec line out and mic 1 pin widgets to inputs
6626  */
6627 static struct hda_verb alc861_threestack_ch2_init[] = {
6628         /* set pin widget 1Ah (line in) for input */
6629         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6630         /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
6631         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6632
6633         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
6634 #if 0
6635         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6636         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
6637 #endif
6638         { } /* end */
6639 };
6640 /*
6641  * 6ch mode
6642  * need to set the codec line out and mic 1 pin widgets to outputs
6643  */
6644 static struct hda_verb alc861_threestack_ch6_init[] = {
6645         /* set pin widget 1Ah (line in) for output (Back Surround)*/
6646         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6647         /* set pin widget 18h (mic1) for output (CLFE)*/
6648         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6649
6650         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
6651         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
6652
6653         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
6654 #if 0
6655         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6656         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
6657 #endif
6658         { } /* end */
6659 };
6660
6661 static struct hda_channel_mode alc861_threestack_modes[2] = {
6662         { 2, alc861_threestack_ch2_init },
6663         { 6, alc861_threestack_ch6_init },
6664 };
6665 /* Set mic1 as input and unmute the mixer */
6666 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
6667         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6668         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6669         { } /* end */
6670 };
6671 /* Set mic1 as output and mute mixer */
6672 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
6673         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6674         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6675         { } /* end */
6676 };
6677
6678 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
6679         { 2, alc861_uniwill_m31_ch2_init },
6680         { 4, alc861_uniwill_m31_ch4_init },
6681 };
6682
6683 /* Set mic1 and line-in as input and unmute the mixer */
6684 static struct hda_verb alc861_asus_ch2_init[] = {
6685         /* set pin widget 1Ah (line in) for input */
6686         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6687         /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
6688         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6689
6690         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
6691 #if 0
6692         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6693         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
6694 #endif
6695         { } /* end */
6696 };
6697 /* Set mic1 nad line-in as output and mute mixer */
6698 static struct hda_verb alc861_asus_ch6_init[] = {
6699         /* set pin widget 1Ah (line in) for output (Back Surround)*/
6700         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6701         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
6702         /* set pin widget 18h (mic1) for output (CLFE)*/
6703         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6704         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
6705         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
6706         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
6707
6708         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
6709 #if 0
6710         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6711         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
6712 #endif
6713         { } /* end */
6714 };
6715
6716 static struct hda_channel_mode alc861_asus_modes[2] = {
6717         { 2, alc861_asus_ch2_init },
6718         { 6, alc861_asus_ch6_init },
6719 };
6720
6721 /* patch-ALC861 */
6722
6723 static struct snd_kcontrol_new alc861_base_mixer[] = {
6724         /* output mixer control */
6725         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6726         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6727         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6728         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6729         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
6730
6731         /*Input mixer control */
6732         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6733            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6734         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6735         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6736         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6737         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6738         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6739         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6740         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6741         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6742  
6743         /* Capture mixer control */
6744         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6745         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6746         {
6747                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6748                 .name = "Capture Source",
6749                 .count = 1,
6750                 .info = alc_mux_enum_info,
6751                 .get = alc_mux_enum_get,
6752                 .put = alc_mux_enum_put,
6753         },
6754         { } /* end */
6755 };
6756
6757 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
6758         /* output mixer control */
6759         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6760         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6761         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6762         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6763         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
6764
6765         /* Input mixer control */
6766         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6767            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6768         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6769         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6770         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6771         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6772         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6773         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6774         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6775         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6776  
6777         /* Capture mixer control */
6778         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6779         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6780         {
6781                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6782                 .name = "Capture Source",
6783                 .count = 1,
6784                 .info = alc_mux_enum_info,
6785                 .get = alc_mux_enum_get,
6786                 .put = alc_mux_enum_put,
6787         },
6788         {
6789                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6790                 .name = "Channel Mode",
6791                 .info = alc_ch_mode_info,
6792                 .get = alc_ch_mode_get,
6793                 .put = alc_ch_mode_put,
6794                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
6795         },
6796         { } /* end */
6797 };
6798
6799 static snd_kcontrol_new_t alc861_toshiba_mixer[] = {
6800         /* output mixer control */
6801         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6802         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6803         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6804         
6805         /*Capture mixer control */
6806         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6807         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6808         {
6809                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6810                 .name = "Capture Source",
6811                 .count = 1,
6812                 .info = alc_mux_enum_info,
6813                 .get = alc_mux_enum_get,
6814                 .put = alc_mux_enum_put,
6815         },
6816
6817         { } /* end */
6818 };      
6819
6820 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
6821         /* output mixer control */
6822         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6823         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6824         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6825         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6826         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
6827
6828         /* Input mixer control */
6829         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6830            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6831         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6832         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6833         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6834         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6835         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6836         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6837         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6838         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6839  
6840         /* Capture mixer control */
6841         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6842         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6843         {
6844                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6845                 .name = "Capture Source",
6846                 .count = 1,
6847                 .info = alc_mux_enum_info,
6848                 .get = alc_mux_enum_get,
6849                 .put = alc_mux_enum_put,
6850         },
6851         {
6852                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6853                 .name = "Channel Mode",
6854                 .info = alc_ch_mode_info,
6855                 .get = alc_ch_mode_get,
6856                 .put = alc_ch_mode_put,
6857                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
6858         },
6859         { } /* end */
6860 };                      
6861
6862 static struct snd_kcontrol_new alc861_asus_mixer[] = {
6863         /* output mixer control */
6864         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6865         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6866         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6867         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6868         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
6869
6870         /* Input mixer control */
6871         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6872         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6873         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6874         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6875         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6876         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6877         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6878         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6879         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6880         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */
6881  
6882         /* Capture mixer control */
6883         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6884         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6885         {
6886                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6887                 .name = "Capture Source",
6888                 .count = 1,
6889                 .info = alc_mux_enum_info,
6890                 .get = alc_mux_enum_get,
6891                 .put = alc_mux_enum_put,
6892         },
6893         {
6894                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6895                 .name = "Channel Mode",
6896                 .info = alc_ch_mode_info,
6897                 .get = alc_ch_mode_get,
6898                 .put = alc_ch_mode_put,
6899                 .private_value = ARRAY_SIZE(alc861_asus_modes),
6900         },
6901         { }
6902 };                      
6903
6904         
6905 /*
6906  * generic initialization of ADC, input mixers and output mixers
6907  */
6908 static struct hda_verb alc861_base_init_verbs[] = {
6909         /*
6910          * Unmute ADC0 and set the default input to mic-in
6911          */
6912         /* port-A for surround (rear panel) */
6913         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6914         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
6915         /* port-B for mic-in (rear panel) with vref */
6916         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6917         /* port-C for line-in (rear panel) */
6918         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6919         /* port-D for Front */
6920         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6921         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
6922         /* port-E for HP out (front panel) */
6923         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
6924         /* route front PCM to HP */
6925         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
6926         /* port-F for mic-in (front panel) with vref */
6927         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6928         /* port-G for CLFE (rear panel) */
6929         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6930         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6931         /* port-H for side (rear panel) */
6932         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6933         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
6934         /* CD-in */
6935         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6936         /* route front mic to ADC1*/
6937         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6938         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6939         
6940         /* Unmute DAC0~3 & spdif out*/
6941         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6942         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6943         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6944         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6945         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6946         
6947         /* Unmute Mixer 14 (mic) 1c (Line in)*/
6948         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6949         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6950         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6951         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6952         
6953         /* Unmute Stereo Mixer 15 */
6954         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6955         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6956         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6957         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
6958
6959         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6960         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6961         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6962         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6963         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6964         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6965         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6966         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6967         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
6968         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6969
6970         { }
6971 };
6972
6973 static struct hda_verb alc861_threestack_init_verbs[] = {
6974         /*
6975          * Unmute ADC0 and set the default input to mic-in
6976          */
6977         /* port-A for surround (rear panel) */
6978         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6979         /* port-B for mic-in (rear panel) with vref */
6980         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6981         /* port-C for line-in (rear panel) */
6982         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6983         /* port-D for Front */
6984         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6985         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
6986         /* port-E for HP out (front panel) */
6987         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
6988         /* route front PCM to HP */
6989         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
6990         /* port-F for mic-in (front panel) with vref */
6991         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6992         /* port-G for CLFE (rear panel) */
6993         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6994         /* port-H for side (rear panel) */
6995         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6996         /* CD-in */
6997         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6998         /* route front mic to ADC1*/
6999         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7000         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7001         /* Unmute DAC0~3 & spdif out*/
7002         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7003         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7004         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7005         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7006         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7007         
7008         /* Unmute Mixer 14 (mic) 1c (Line in)*/
7009         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7010         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7011         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7012         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7013         
7014         /* Unmute Stereo Mixer 15 */
7015         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7016         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7017         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7018         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
7019
7020         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7021         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7022         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7023         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7024         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7025         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7026         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7027         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7028         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
7029         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7030         { }
7031 };
7032
7033 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
7034         /*
7035          * Unmute ADC0 and set the default input to mic-in
7036          */
7037         /* port-A for surround (rear panel) */
7038         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7039         /* port-B for mic-in (rear panel) with vref */
7040         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7041         /* port-C for line-in (rear panel) */
7042         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7043         /* port-D for Front */
7044         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7045         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
7046         /* port-E for HP out (front panel) */
7047         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80
7048         /* route front PCM to HP */
7049         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
7050         /* port-F for mic-in (front panel) with vref */
7051         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7052         /* port-G for CLFE (rear panel) */
7053         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7054         /* port-H for side (rear panel) */
7055         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7056         /* CD-in */
7057         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7058         /* route front mic to ADC1*/
7059         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7060         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7061         /* Unmute DAC0~3 & spdif out*/
7062         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7063         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7064         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7065         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7066         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7067         
7068         /* Unmute Mixer 14 (mic) 1c (Line in)*/
7069         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7070         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7071         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7072         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7073         
7074         /* Unmute Stereo Mixer 15 */
7075         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7076         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7077         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7078         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
7079
7080         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7081         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7082         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7083         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7084         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7085         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7086         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7087         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7088         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
7089         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7090         { }
7091 };
7092
7093 static struct hda_verb alc861_asus_init_verbs[] = {
7094         /*
7095          * Unmute ADC0 and set the default input to mic-in
7096          */
7097         /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/
7098         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
7099         /* route front PCM to HP */
7100         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
7101         /* port-B for mic-in (rear panel) with vref */
7102         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7103         /* port-C for line-in (rear panel) */
7104         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7105         /* port-D for Front */
7106         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7107         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
7108         /* port-E for HP out (front panel) */
7109         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */
7110         /* route front PCM to HP */
7111         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
7112         /* port-F for mic-in (front panel) with vref */
7113         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7114         /* port-G for CLFE (rear panel) */
7115         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7116         /* port-H for side (rear panel) */
7117         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7118         /* CD-in */
7119         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7120         /* route front mic to ADC1*/
7121         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7122         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7123         /* Unmute DAC0~3 & spdif out*/
7124         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7125         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7126         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7127         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7128         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7129         /* Unmute Mixer 14 (mic) 1c (Line in)*/
7130         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7131         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7132         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7133         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7134         
7135         /* Unmute Stereo Mixer 15 */
7136         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7137         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7138         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7139         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, /* Output 0~12 step */
7140
7141         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7142         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7143         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7144         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7145         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7146         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7147         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7148         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7149         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */
7150         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7151         { }
7152 };
7153
7154
7155 /*
7156  * generic initialization of ADC, input mixers and output mixers
7157  */
7158 static struct hda_verb alc861_auto_init_verbs[] = {
7159         /*
7160          * Unmute ADC0 and set the default input to mic-in
7161          */
7162 //      {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7163         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7164         
7165         /* Unmute DAC0~3 & spdif out*/
7166         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7167         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7168         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7169         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7170         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7171         
7172         /* Unmute Mixer 14 (mic) 1c (Line in)*/
7173         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7174         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7175         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7176         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7177         
7178         /* Unmute Stereo Mixer 15 */
7179         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7180         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7181         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7182         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
7183
7184         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7185         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7186         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7187         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7188         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7189         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7190         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7191         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7192
7193         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7194         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7195         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},    
7196         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},            
7197         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7198         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7199         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},    
7200         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},    
7201
7202         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  // set Mic 1
7203
7204         { }
7205 };
7206
7207 static struct hda_verb alc861_toshiba_init_verbs[] = {
7208         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7209         
7210         { }
7211 };
7212
7213 /* toggle speaker-output according to the hp-jack state */
7214 static void alc861_toshiba_automute(struct hda_codec *codec)
7215 {
7216         unsigned int present;
7217
7218         present = snd_hda_codec_read(codec, 0x0f, 0,
7219                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7220         snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
7221                                  0x80, present ? 0x80 : 0);
7222         snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
7223                                  0x80, present ? 0x80 : 0);
7224         snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
7225                                  0x80, present ? 0 : 0x80);
7226         snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
7227                                  0x80, present ? 0 : 0x80);
7228 }
7229
7230 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
7231                                        unsigned int res)
7232 {
7233         /* Looks like the unsol event is incompatible with the standard
7234          * definition.  6bit tag is placed at 26 bit!
7235          */
7236         if ((res >> 26) == ALC880_HP_EVENT)
7237                 alc861_toshiba_automute(codec);
7238 }
7239
7240 /* pcm configuration: identiacal with ALC880 */
7241 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
7242 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
7243 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
7244 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
7245
7246
7247 #define ALC861_DIGOUT_NID       0x07
7248
7249 static struct hda_channel_mode alc861_8ch_modes[1] = {
7250         { 8, NULL }
7251 };
7252
7253 static hda_nid_t alc861_dac_nids[4] = {
7254         /* front, surround, clfe, side */
7255         0x03, 0x06, 0x05, 0x04
7256 };
7257
7258 static hda_nid_t alc660_dac_nids[3] = {
7259         /* front, clfe, surround */
7260         0x03, 0x05, 0x06
7261 };
7262
7263 static hda_nid_t alc861_adc_nids[1] = {
7264         /* ADC0-2 */
7265         0x08,
7266 };
7267
7268 static struct hda_input_mux alc861_capture_source = {
7269         .num_items = 5,
7270         .items = {
7271                 { "Mic", 0x0 },
7272                 { "Front Mic", 0x3 },
7273                 { "Line", 0x1 },
7274                 { "CD", 0x4 },
7275                 { "Mixer", 0x5 },
7276         },
7277 };
7278
7279 /* fill in the dac_nids table from the parsed pin configuration */
7280 static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
7281 {
7282         int i;
7283         hda_nid_t nid;
7284
7285         spec->multiout.dac_nids = spec->private_dac_nids;
7286         for (i = 0; i < cfg->line_outs; i++) {
7287                 nid = cfg->line_out_pins[i];
7288                 if (nid) {
7289                         if (i >= ARRAY_SIZE(alc861_dac_nids))
7290                                 continue;
7291                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
7292                 }
7293         }
7294         spec->multiout.num_dacs = cfg->line_outs;
7295         return 0;
7296 }
7297
7298 /* add playback controls from the parsed DAC table */
7299 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
7300                                              const struct auto_pin_cfg *cfg)
7301 {
7302         char name[32];
7303         static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
7304         hda_nid_t nid;
7305         int i, idx, err;
7306
7307         for (i = 0; i < cfg->line_outs; i++) {
7308                 nid = spec->multiout.dac_nids[i];
7309                 if (! nid)
7310                         continue;
7311                 if (nid == 0x05) {
7312                         /* Center/LFE */
7313                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
7314                                                HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
7315                                 return err;
7316                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
7317                                                HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
7318                                 return err;
7319                 } else {
7320                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
7321                                 if (nid == alc861_dac_nids[idx])
7322                                         break;
7323                         sprintf(name, "%s Playback Switch", chname[idx]);
7324                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
7325                                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
7326                                 return err;
7327                 }
7328         }
7329         return 0;
7330 }
7331
7332 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
7333 {
7334         int err;
7335         hda_nid_t nid;
7336
7337         if (! pin)
7338                 return 0;
7339
7340         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
7341                 nid = 0x03;
7342                 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
7343                                        HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
7344                         return err;
7345                 spec->multiout.hp_nid = nid;
7346         }
7347         return 0;
7348 }
7349
7350 /* create playback/capture controls for input pins */
7351 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
7352 {
7353         struct hda_input_mux *imux = &spec->private_imux;
7354         int i, err, idx, idx1;
7355
7356         for (i = 0; i < AUTO_PIN_LAST; i++) {
7357                 switch(cfg->input_pins[i]) {
7358                 case 0x0c:
7359                         idx1 = 1;
7360                         idx = 2;        // Line In
7361                         break;
7362                 case 0x0f:
7363                         idx1 = 2;
7364                         idx = 2;        // Line In
7365                         break;
7366                 case 0x0d:
7367                         idx1 = 0;
7368                         idx = 1;        // Mic In 
7369                         break;
7370                 case 0x10:      
7371                         idx1 = 3;
7372                         idx = 1;        // Mic In 
7373                         break;
7374                 case 0x11:
7375                         idx1 = 4;
7376                         idx = 0;        // CD
7377                         break;
7378                 default:
7379                         continue;
7380                 }
7381
7382                 err = new_analog_input(spec, cfg->input_pins[i],
7383                                        auto_pin_cfg_labels[i], idx, 0x15);
7384                 if (err < 0)
7385                         return err;
7386
7387                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
7388                 imux->items[imux->num_items].index = idx1;
7389                 imux->num_items++;      
7390         }
7391         return 0;
7392 }
7393
7394 static struct snd_kcontrol_new alc861_capture_mixer[] = {
7395         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7396         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7397
7398         {
7399                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7400                 /* The multiple "Capture Source" controls confuse alsamixer
7401                  * So call somewhat different..
7402                  *FIXME: the controls appear in the "playback" view!
7403                  */
7404                 /* .name = "Capture Source", */
7405                 .name = "Input Source",
7406                 .count = 1,
7407                 .info = alc_mux_enum_info,
7408                 .get = alc_mux_enum_get,
7409                 .put = alc_mux_enum_put,
7410         },
7411         { } /* end */
7412 };
7413
7414 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
7415                                               int pin_type, int dac_idx)
7416 {
7417         /* set as output */
7418
7419         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
7420         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
7421
7422 }
7423
7424 static void alc861_auto_init_multi_out(struct hda_codec *codec)
7425 {
7426         struct alc_spec *spec = codec->spec;
7427         int i;
7428
7429         for (i = 0; i < spec->autocfg.line_outs; i++) {
7430                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7431                 if (nid)
7432                         alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
7433         }
7434 }
7435
7436 static void alc861_auto_init_hp_out(struct hda_codec *codec)
7437 {
7438         struct alc_spec *spec = codec->spec;
7439         hda_nid_t pin;
7440
7441         pin = spec->autocfg.hp_pins[0];
7442         if (pin) /* connect to front */
7443                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
7444 }
7445
7446 static void alc861_auto_init_analog_input(struct hda_codec *codec)
7447 {
7448         struct alc_spec *spec = codec->spec;
7449         int i;
7450
7451         for (i = 0; i < AUTO_PIN_LAST; i++) {
7452                 hda_nid_t nid = spec->autocfg.input_pins[i];
7453                 if ((nid>=0x0c) && (nid <=0x11)) {
7454                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7455                                             i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
7456                 }
7457         }
7458 }
7459
7460 /* parse the BIOS configuration and set up the alc_spec */
7461 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
7462 static int alc861_parse_auto_config(struct hda_codec *codec)
7463 {
7464         struct alc_spec *spec = codec->spec;
7465         int err;
7466         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
7467
7468         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7469                                                 alc861_ignore)) < 0)
7470                 return err;
7471         if (! spec->autocfg.line_outs)
7472                 return 0; /* can't find valid BIOS pin config */
7473
7474         if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
7475             (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
7476             (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 ||
7477             (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
7478                 return err;
7479
7480         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7481
7482         if (spec->autocfg.dig_out_pin)
7483                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
7484
7485         if (spec->kctl_alloc)
7486                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7487
7488         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
7489
7490         spec->num_mux_defs = 1;
7491         spec->input_mux = &spec->private_imux;
7492
7493         spec->adc_nids = alc861_adc_nids;
7494         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
7495         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
7496         spec->num_mixers++;
7497
7498         return 1;
7499 }
7500
7501 /* additional initialization for auto-configuration model */
7502 static void alc861_auto_init(struct hda_codec *codec)
7503 {
7504         alc861_auto_init_multi_out(codec);
7505         alc861_auto_init_hp_out(codec);
7506         alc861_auto_init_analog_input(codec);
7507 }
7508
7509
7510 /*
7511  * configuration and preset
7512  */
7513 static struct hda_board_config alc861_cfg_tbl[] = {
7514         { .modelname = "3stack", .config = ALC861_3ST },
7515         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600,
7516           .config = ALC861_3ST },
7517         { .modelname = "3stack-660", .config = ALC660_3ST },
7518         { .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7,
7519           .config = ALC660_3ST },
7520         { .modelname = "3stack-dig", .config = ALC861_3ST_DIG },
7521         { .modelname = "6stack-dig", .config = ALC861_6ST_DIG },
7522         { .modelname = "uniwill-m31", .config = ALC861_UNIWILL_M31},
7523         { .pci_subvendor = 0x1584, .pci_subdevice = 0x9072,
7524           .config = ALC861_UNIWILL_M31 },
7525         { .modelname = "toshiba", .config = ALC861_TOSHIBA },
7526         { .pci_subvendor = 0x1179, .pci_subdevice = 0xff10,
7527           .config = ALC861_TOSHIBA },
7528         { .modelname = "asus", .config = ALC861_ASUS},
7529         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1393,
7530           .config = ALC861_ASUS },
7531         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1338,
7532           .config = ALC861_ASUS },
7533         { .modelname = "auto", .config = ALC861_AUTO },
7534         {}
7535 };
7536
7537 static struct alc_config_preset alc861_presets[] = {
7538         [ALC861_3ST] = {
7539                 .mixers = { alc861_3ST_mixer },
7540                 .init_verbs = { alc861_threestack_init_verbs },
7541                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7542                 .dac_nids = alc861_dac_nids,
7543                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7544                 .channel_mode = alc861_threestack_modes,
7545                 .need_dac_fix = 1,
7546                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7547                 .adc_nids = alc861_adc_nids,
7548                 .input_mux = &alc861_capture_source,
7549         },
7550         [ALC861_3ST_DIG] = {
7551                 .mixers = { alc861_base_mixer },
7552                 .init_verbs = { alc861_threestack_init_verbs },
7553                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7554                 .dac_nids = alc861_dac_nids,
7555                 .dig_out_nid = ALC861_DIGOUT_NID,
7556                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7557                 .channel_mode = alc861_threestack_modes,
7558                 .need_dac_fix = 1,
7559                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7560                 .adc_nids = alc861_adc_nids,
7561                 .input_mux = &alc861_capture_source,
7562         },
7563         [ALC861_6ST_DIG] = {
7564                 .mixers = { alc861_base_mixer },
7565                 .init_verbs = { alc861_base_init_verbs },
7566                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7567                 .dac_nids = alc861_dac_nids,
7568                 .dig_out_nid = ALC861_DIGOUT_NID,
7569                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
7570                 .channel_mode = alc861_8ch_modes,
7571                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7572                 .adc_nids = alc861_adc_nids,
7573                 .input_mux = &alc861_capture_source,
7574         },
7575         [ALC660_3ST] = {
7576                 .mixers = { alc861_3ST_mixer },
7577                 .init_verbs = { alc861_threestack_init_verbs },
7578                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
7579                 .dac_nids = alc660_dac_nids,
7580                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7581                 .channel_mode = alc861_threestack_modes,
7582                 .need_dac_fix = 1,
7583                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7584                 .adc_nids = alc861_adc_nids,
7585                 .input_mux = &alc861_capture_source,
7586         },
7587         [ALC861_UNIWILL_M31] = {
7588                 .mixers = { alc861_uniwill_m31_mixer },
7589                 .init_verbs = { alc861_uniwill_m31_init_verbs },
7590                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7591                 .dac_nids = alc861_dac_nids,
7592                 .dig_out_nid = ALC861_DIGOUT_NID,
7593                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
7594                 .channel_mode = alc861_uniwill_m31_modes,
7595                 .need_dac_fix = 1,
7596                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7597                 .adc_nids = alc861_adc_nids,
7598                 .input_mux = &alc861_capture_source,
7599         },
7600         [ALC861_TOSHIBA] = {
7601                 .mixers = { alc861_toshiba_mixer },
7602                 .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs },
7603                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7604                 .dac_nids = alc861_dac_nids,
7605                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7606                 .channel_mode = alc883_3ST_2ch_modes,
7607                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7608                 .adc_nids = alc861_adc_nids,
7609                 .input_mux = &alc861_capture_source,
7610                 .unsol_event = alc861_toshiba_unsol_event,
7611                 .init_hook = alc861_toshiba_automute,
7612         },
7613         [ALC861_ASUS] = {
7614                 .mixers = { alc861_asus_mixer },
7615                 .init_verbs = { alc861_asus_init_verbs },
7616                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7617                 .dac_nids = alc861_dac_nids,
7618                 .dig_out_nid = ALC861_DIGOUT_NID,
7619                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
7620                 .channel_mode = alc861_asus_modes,
7621                 .need_dac_fix = 1,
7622                 .hp_nid = 0x06,
7623                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7624                 .adc_nids = alc861_adc_nids,
7625                 .input_mux = &alc861_capture_source,
7626         },
7627 };      
7628
7629
7630 static int patch_alc861(struct hda_codec *codec)
7631 {
7632         struct alc_spec *spec;
7633         int board_config;
7634         int err;
7635
7636         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
7637         if (spec == NULL)
7638                 return -ENOMEM;
7639
7640         codec->spec = spec;     
7641
7642         board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl);
7643
7644         if (board_config < 0 || board_config >= ALC861_MODEL_LAST) {
7645                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
7646                        "trying auto-probe from BIOS...\n");
7647                 board_config = ALC861_AUTO;
7648         }
7649
7650         if (board_config == ALC861_AUTO) {
7651                 /* automatic parse from the BIOS config */
7652                 err = alc861_parse_auto_config(codec);
7653                 if (err < 0) {
7654                         alc_free(codec);
7655                         return err;
7656                 } else if (! err) {
7657                         printk(KERN_INFO
7658                                "hda_codec: Cannot set up configuration "
7659                                "from BIOS.  Using base mode...\n");
7660                    board_config = ALC861_3ST_DIG;
7661                 }
7662         }
7663
7664         if (board_config != ALC861_AUTO)
7665                 setup_preset(spec, &alc861_presets[board_config]);
7666
7667         spec->stream_name_analog = "ALC861 Analog";
7668         spec->stream_analog_playback = &alc861_pcm_analog_playback;
7669         spec->stream_analog_capture = &alc861_pcm_analog_capture;
7670
7671         spec->stream_name_digital = "ALC861 Digital";
7672         spec->stream_digital_playback = &alc861_pcm_digital_playback;
7673         spec->stream_digital_capture = &alc861_pcm_digital_capture;
7674
7675         codec->patch_ops = alc_patch_ops;
7676         if (board_config == ALC861_AUTO)
7677                 spec->init_hook = alc861_auto_init;
7678                 
7679         return 0;
7680 }
7681
7682 /*
7683  * patch entries
7684  */
7685 struct hda_codec_preset snd_hda_preset_realtek[] = {
7686         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
7687         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
7688         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
7689         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
7690         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
7691         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
7692         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
7693         { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861",
7694           .patch = patch_alc861 },
7695         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
7696           .patch = patch_alc861 },
7697         { .id = 0x10ec0660, .name = "ALC660", .patch = patch_alc861 },
7698         {} /* terminator */
7699 };