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