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