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