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