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