[ALSA] hda: minor correction to fujitsu ALC260 initverbs
[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 output sum widgets muted and their output gains at min */
2725         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2726         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2727         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2728         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2729         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2730         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2731         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2732         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2733         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2734
2735         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
2736         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2737         /* Unmute Line1 pin widget amp left and right (no equiv mixer ctrl) */
2738         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2739         /* Unmute Line1 pin widget input for when this pin is used as input
2740          * (no equiv mixer ctrl).  Having input and output unmuted doesn't
2741          * seem to cause a problem.
2742          */
2743         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2744         /* Unmute pin widget used for Line-in (no equiv mixer ctrl) */
2745         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2746
2747         /* Mute capture amp left and right */
2748         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2749         /* Set ADC connection select to match default mixer setting - line 
2750          * in (on mic1 pin)
2751          */
2752         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
2753
2754         /* Do the same for the second ADC: mute capture input amp and
2755          * set ADC connection to line in
2756          */
2757         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2758         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
2759
2760         /* Mute all inputs to mixer widget (even unconnected ones) */
2761         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
2762         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
2763         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
2764         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
2765         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
2766         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
2767         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
2768         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
2769
2770         { }
2771 };
2772
2773 static struct hda_pcm_stream alc260_pcm_analog_playback = {
2774         .substreams = 1,
2775         .channels_min = 2,
2776         .channels_max = 2,
2777 };
2778
2779 static struct hda_pcm_stream alc260_pcm_analog_capture = {
2780         .substreams = 1,
2781         .channels_min = 2,
2782         .channels_max = 2,
2783 };
2784
2785 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
2786 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
2787
2788 /*
2789  * for BIOS auto-configuration
2790  */
2791
2792 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
2793                                         const char *pfx)
2794 {
2795         hda_nid_t nid_vol;
2796         unsigned long vol_val, sw_val;
2797         char name[32];
2798         int err;
2799
2800         if (nid >= 0x0f && nid < 0x11) {
2801                 nid_vol = nid - 0x7;
2802                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
2803                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
2804         } else if (nid == 0x11) {
2805                 nid_vol = nid - 0x7;
2806                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
2807                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
2808         } else if (nid >= 0x12 && nid <= 0x15) {
2809                 nid_vol = 0x08;
2810                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
2811                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
2812         } else
2813                 return 0; /* N/A */
2814         
2815         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
2816         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
2817                 return err;
2818         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
2819         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
2820                 return err;
2821         return 1;
2822 }
2823
2824 /* add playback controls from the parsed DAC table */
2825 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
2826                                              const struct auto_pin_cfg *cfg)
2827 {
2828         hda_nid_t nid;
2829         int err;
2830
2831         spec->multiout.num_dacs = 1;
2832         spec->multiout.dac_nids = spec->private_dac_nids;
2833         spec->multiout.dac_nids[0] = 0x02;
2834
2835         nid = cfg->line_out_pins[0];
2836         if (nid) {
2837                 err = alc260_add_playback_controls(spec, nid, "Front");
2838                 if (err < 0)
2839                         return err;
2840         }
2841
2842         nid = cfg->speaker_pin;
2843         if (nid) {
2844                 err = alc260_add_playback_controls(spec, nid, "Speaker");
2845                 if (err < 0)
2846                         return err;
2847         }
2848
2849         nid = cfg->hp_pin;
2850         if (nid) {
2851                 err = alc260_add_playback_controls(spec, nid, "Headphone");
2852                 if (err < 0)
2853                         return err;
2854         }
2855         return 0;       
2856 }
2857
2858 /* create playback/capture controls for input pins */
2859 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
2860                                                 const struct auto_pin_cfg *cfg)
2861 {
2862         struct hda_input_mux *imux = &spec->private_imux;
2863         int i, err, idx;
2864
2865         for (i = 0; i < AUTO_PIN_LAST; i++) {
2866                 if (cfg->input_pins[i] >= 0x12) {
2867                         idx = cfg->input_pins[i] - 0x12;
2868                         err = new_analog_input(spec, cfg->input_pins[i],
2869                                                auto_pin_cfg_labels[i], idx, 0x07);
2870                         if (err < 0)
2871                                 return err;
2872                         imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2873                         imux->items[imux->num_items].index = idx;
2874                         imux->num_items++;
2875                 }
2876                 if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
2877                         idx = cfg->input_pins[i] - 0x09;
2878                         err = new_analog_input(spec, cfg->input_pins[i],
2879                                                auto_pin_cfg_labels[i], idx, 0x07);
2880                         if (err < 0)
2881                                 return err;
2882                         imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2883                         imux->items[imux->num_items].index = idx;
2884                         imux->num_items++;
2885                 }
2886         }
2887         return 0;
2888 }
2889
2890 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
2891                                               hda_nid_t nid, int pin_type,
2892                                               int sel_idx)
2893 {
2894         /* set as output */
2895         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2896         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2897         /* need the manual connection? */
2898         if (nid >= 0x12) {
2899                 int idx = nid - 0x12;
2900                 snd_hda_codec_write(codec, idx + 0x0b, 0,
2901                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
2902                                     
2903         }
2904 }
2905
2906 static void alc260_auto_init_multi_out(struct hda_codec *codec)
2907 {
2908         struct alc_spec *spec = codec->spec;
2909         hda_nid_t nid;
2910
2911         nid = spec->autocfg.line_out_pins[0];   
2912         if (nid)
2913                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
2914         
2915         nid = spec->autocfg.speaker_pin;
2916         if (nid)
2917                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
2918
2919         nid = spec->autocfg.hp_pin;
2920         if (nid)
2921                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
2922 }       
2923
2924 #define ALC260_PIN_CD_NID               0x16
2925 static void alc260_auto_init_analog_input(struct hda_codec *codec)
2926 {
2927         struct alc_spec *spec = codec->spec;
2928         int i;
2929
2930         for (i = 0; i < AUTO_PIN_LAST; i++) {
2931                 hda_nid_t nid = spec->autocfg.input_pins[i];
2932                 if (nid >= 0x12) {
2933                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2934                                             i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2935                         if (nid != ALC260_PIN_CD_NID)
2936                                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2937                                                     AMP_OUT_MUTE);
2938                 }
2939         }
2940 }
2941
2942 /*
2943  * generic initialization of ADC, input mixers and output mixers
2944  */
2945 static struct hda_verb alc260_volume_init_verbs[] = {
2946         /*
2947          * Unmute ADC0-1 and set the default input to mic-in
2948          */
2949         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
2950         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2951         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
2952         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2953         
2954         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2955          * mixer widget
2956          * Note: PASD motherboards uses the Line In 2 as the input for front panel
2957          * mic (mic 2)
2958          */
2959         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2960         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2961         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2962         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2963         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2964         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2965
2966         /*
2967          * Set up output mixers (0x08 - 0x0a)
2968          */
2969         /* set vol=0 to output mixers */
2970         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2971         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2972         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2973         /* set up input amps for analog loopback */
2974         /* Amp Indices: DAC = 0, mixer = 1 */
2975         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2976         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2977         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2978         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2979         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2980         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2981         
2982         { }
2983 };
2984
2985 static int alc260_parse_auto_config(struct hda_codec *codec)
2986 {
2987         struct alc_spec *spec = codec->spec;
2988         unsigned int wcap;
2989         int err;
2990         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
2991
2992         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
2993                                                 alc260_ignore)) < 0)
2994                 return err;
2995         if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
2996                 return err;
2997         if (! spec->kctl_alloc)
2998                 return 0; /* can't find valid BIOS pin config */
2999         if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
3000                 return err;
3001
3002         spec->multiout.max_channels = 2;
3003
3004         if (spec->autocfg.dig_out_pin)
3005                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
3006         if (spec->kctl_alloc)
3007                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3008
3009         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
3010
3011         spec->input_mux = &spec->private_imux;
3012
3013         /* check whether NID 0x04 is valid */
3014         wcap = get_wcaps(codec, 0x04);
3015         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
3016         if (wcap != AC_WID_AUD_IN) {
3017                 spec->adc_nids = alc260_adc_nids_alt;
3018                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
3019                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
3020         } else {
3021                 spec->adc_nids = alc260_adc_nids;
3022                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
3023                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
3024         }
3025         spec->num_mixers++;
3026
3027         return 1;
3028 }
3029
3030 /* init callback for auto-configuration model -- overriding the default init */
3031 static int alc260_auto_init(struct hda_codec *codec)
3032 {
3033         alc_init(codec);
3034         alc260_auto_init_multi_out(codec);
3035         alc260_auto_init_analog_input(codec);
3036         return 0;
3037 }
3038
3039 /*
3040  * ALC260 configurations
3041  */
3042 static struct hda_board_config alc260_cfg_tbl[] = {
3043         { .modelname = "basic", .config = ALC260_BASIC },
3044         { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
3045           .config = ALC260_BASIC }, /* Sony VAIO */
3046         { .modelname = "hp", .config = ALC260_HP },
3047         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP },
3048         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
3049         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP },
3050         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
3051         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
3052         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
3053         { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP },
3054         { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X },
3055         { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X },
3056         { .modelname = "auto", .config = ALC260_AUTO },
3057         {}
3058 };
3059
3060 static struct alc_config_preset alc260_presets[] = {
3061         [ALC260_BASIC] = {
3062                 .mixers = { alc260_base_output_mixer,
3063                             alc260_input_mixer,
3064                             alc260_pc_beep_mixer,
3065                             alc260_capture_mixer },
3066                 .init_verbs = { alc260_init_verbs },
3067                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3068                 .dac_nids = alc260_dac_nids,
3069                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
3070                 .adc_nids = alc260_adc_nids,
3071                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3072                 .channel_mode = alc260_modes,
3073                 .input_mux = &alc260_capture_source,
3074         },
3075         [ALC260_HP] = {
3076                 .mixers = { alc260_base_output_mixer,
3077                             alc260_input_mixer,
3078                             alc260_capture_alt_mixer },
3079                 .init_verbs = { alc260_hp_init_verbs },
3080                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3081                 .dac_nids = alc260_dac_nids,
3082                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
3083                 .adc_nids = alc260_hp_adc_nids,
3084                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3085                 .channel_mode = alc260_modes,
3086                 .input_mux = &alc260_capture_source,
3087         },
3088         [ALC260_HP_3013] = {
3089                 .mixers = { alc260_hp_3013_mixer,
3090                             alc260_input_mixer,
3091                             alc260_capture_alt_mixer },
3092                 .init_verbs = { alc260_hp_3013_init_verbs },
3093                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3094                 .dac_nids = alc260_dac_nids,
3095                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
3096                 .adc_nids = alc260_hp_adc_nids,
3097                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3098                 .channel_mode = alc260_modes,
3099                 .input_mux = &alc260_capture_source,
3100         },
3101         [ALC260_FUJITSU_S702X] = {
3102                 .mixers = { alc260_fujitsu_mixer,
3103                             alc260_capture_mixer },
3104                 .init_verbs = { alc260_fujitsu_init_verbs },
3105                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3106                 .dac_nids = alc260_dac_nids,
3107                 .num_adc_nids = ARRAY_SIZE(alc260_fujitsu_adc_nids),
3108                 .adc_nids = alc260_fujitsu_adc_nids,
3109                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
3110                 .channel_mode = alc260_modes,
3111                 .input_mux = &alc260_fujitsu_capture_source,
3112         },
3113 };
3114
3115 static int patch_alc260(struct hda_codec *codec)
3116 {
3117         struct alc_spec *spec;
3118         int err, board_config;
3119
3120         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3121         if (spec == NULL)
3122                 return -ENOMEM;
3123
3124         codec->spec = spec;
3125
3126         board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
3127         if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
3128                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n");
3129                 board_config = ALC260_AUTO;
3130         }
3131
3132         if (board_config == ALC260_AUTO) {
3133                 /* automatic parse from the BIOS config */
3134                 err = alc260_parse_auto_config(codec);
3135                 if (err < 0) {
3136                         alc_free(codec);
3137                         return err;
3138                 } else if (! err) {
3139                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
3140                         board_config = ALC260_BASIC;
3141                 }
3142         }
3143
3144         if (board_config != ALC260_AUTO)
3145                 setup_preset(spec, &alc260_presets[board_config]);
3146
3147         spec->stream_name_analog = "ALC260 Analog";
3148         spec->stream_analog_playback = &alc260_pcm_analog_playback;
3149         spec->stream_analog_capture = &alc260_pcm_analog_capture;
3150
3151         spec->stream_name_digital = "ALC260 Digital";
3152         spec->stream_digital_playback = &alc260_pcm_digital_playback;
3153         spec->stream_digital_capture = &alc260_pcm_digital_capture;
3154
3155         codec->patch_ops = alc_patch_ops;
3156         if (board_config == ALC260_AUTO)
3157                 codec->patch_ops.init = alc260_auto_init;
3158
3159         return 0;
3160 }
3161
3162
3163 /*
3164  * ALC882 support
3165  *
3166  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
3167  * configuration.  Each pin widget can choose any input DACs and a mixer.
3168  * Each ADC is connected from a mixer of all inputs.  This makes possible
3169  * 6-channel independent captures.
3170  *
3171  * In addition, an independent DAC for the multi-playback (not used in this
3172  * driver yet).
3173  */
3174 #define ALC882_DIGOUT_NID       0x06
3175 #define ALC882_DIGIN_NID        0x0a
3176
3177 static struct hda_channel_mode alc882_ch_modes[1] = {
3178         { 8, NULL }
3179 };
3180
3181 static hda_nid_t alc882_dac_nids[4] = {
3182         /* front, rear, clfe, rear_surr */
3183         0x02, 0x03, 0x04, 0x05
3184 };
3185
3186 /* identical with ALC880 */
3187 #define alc882_adc_nids         alc880_adc_nids
3188 #define alc882_adc_nids_alt     alc880_adc_nids_alt
3189
3190 /* input MUX */
3191 /* FIXME: should be a matrix-type input source selection */
3192
3193 static struct hda_input_mux alc882_capture_source = {
3194         .num_items = 4,
3195         .items = {
3196                 { "Mic", 0x0 },
3197                 { "Front Mic", 0x1 },
3198                 { "Line", 0x2 },
3199                 { "CD", 0x4 },
3200         },
3201 };
3202
3203 #define alc882_mux_enum_info alc_mux_enum_info
3204 #define alc882_mux_enum_get alc_mux_enum_get
3205
3206 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3207 {
3208         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3209         struct alc_spec *spec = codec->spec;
3210         const struct hda_input_mux *imux = spec->input_mux;
3211         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
3212         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
3213         hda_nid_t nid = capture_mixers[adc_idx];
3214         unsigned int *cur_val = &spec->cur_mux[adc_idx];
3215         unsigned int i, idx;
3216
3217         idx = ucontrol->value.enumerated.item[0];
3218         if (idx >= imux->num_items)
3219                 idx = imux->num_items - 1;
3220         if (*cur_val == idx && ! codec->in_resume)
3221                 return 0;
3222         for (i = 0; i < imux->num_items; i++) {
3223                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
3224                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3225                                     v | (imux->items[i].index << 8));
3226         }
3227         *cur_val = idx;
3228         return 1;
3229 }
3230
3231 /*
3232  * 6ch mode
3233  */
3234 static struct hda_verb alc882_sixstack_ch6_init[] = {
3235         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
3236         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3237         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3238         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3239         { } /* end */
3240 };
3241
3242 /*
3243  * 8ch mode
3244  */
3245 static struct hda_verb alc882_sixstack_ch8_init[] = {
3246         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3247         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3248         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3249         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
3250         { } /* end */
3251 };
3252
3253 static struct hda_channel_mode alc882_sixstack_modes[2] = {
3254         { 6, alc882_sixstack_ch6_init },
3255         { 8, alc882_sixstack_ch8_init },
3256 };
3257
3258 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
3259  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
3260  */
3261 static struct snd_kcontrol_new alc882_base_mixer[] = {
3262         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3263         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3264         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3265         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3266         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3267         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3268         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3269         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3270         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3271         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3272         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3273         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3274         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3275         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3276         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3277         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3278         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3279         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3280         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3281         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
3282         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
3283         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
3284         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
3285         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
3286         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
3287         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
3288         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
3289         {
3290                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3291                 /* .name = "Capture Source", */
3292                 .name = "Input Source",
3293                 .count = 3,
3294                 .info = alc882_mux_enum_info,
3295                 .get = alc882_mux_enum_get,
3296                 .put = alc882_mux_enum_put,
3297         },
3298         { } /* end */
3299 };
3300
3301 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
3302         {
3303                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3304                 .name = "Channel Mode",
3305                 .info = alc_ch_mode_info,
3306                 .get = alc_ch_mode_get,
3307                 .put = alc_ch_mode_put,
3308         },
3309         { } /* end */
3310 };
3311
3312 static struct hda_verb alc882_init_verbs[] = {
3313         /* Front mixer: unmute input/output amp left and right (volume = 0) */
3314         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3315         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3316         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3317         /* Rear mixer */
3318         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3319         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3320         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3321         /* CLFE mixer */
3322         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3323         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3324         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3325         /* Side mixer */
3326         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3327         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3328         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3329
3330         /* Front Pin: output 0 (0x0c) */
3331         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3332         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3333         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
3334         /* Rear Pin: output 1 (0x0d) */
3335         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3336         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3337         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
3338         /* CLFE Pin: output 2 (0x0e) */
3339         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3340         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3341         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
3342         /* Side Pin: output 3 (0x0f) */
3343         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3344         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3345         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
3346         /* Mic (rear) pin: input vref at 80% */
3347         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3348         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3349         /* Front Mic pin: input vref at 80% */
3350         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3351         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3352         /* Line In pin: input */
3353         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3354         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3355         /* Line-2 In: Headphone output (output 0 - 0x0c) */
3356         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3357         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3358         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3359         /* CD pin widget for input */
3360         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3361
3362         /* FIXME: use matrix-type input source selection */
3363         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
3364         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
3365         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3366         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3367         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3368         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3369         /* Input mixer2 */
3370         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3371         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3372         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3373         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3374         /* Input mixer3 */
3375         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3376         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3377         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3378         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3379         /* ADC1: mute amp left and right */
3380         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3381         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3382         /* ADC2: mute amp left and right */
3383         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3384         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3385         /* ADC3: mute amp left and right */
3386         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3387         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3388
3389         { }
3390 };
3391
3392 /*
3393  * generic initialization of ADC, input mixers and output mixers
3394  */
3395 static struct hda_verb alc882_auto_init_verbs[] = {
3396         /*
3397          * Unmute ADC0-2 and set the default input to mic-in
3398          */
3399         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3400         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3401         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3402         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3403         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3404         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3405
3406         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3407          * mixer widget
3408          * Note: PASD motherboards uses the Line In 2 as the input for front panel
3409          * mic (mic 2)
3410          */
3411         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3412         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3413         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3414         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3415         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3416         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3417
3418         /*
3419          * Set up output mixers (0x0c - 0x0f)
3420          */
3421         /* set vol=0 to output mixers */
3422         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3423         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3424         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3425         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3426         /* set up input amps for analog loopback */
3427         /* Amp Indices: DAC = 0, mixer = 1 */
3428         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3429         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3430         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3431         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3432         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3433         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3434         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3435         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3436         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3437         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3438
3439         /* FIXME: use matrix-type input source selection */
3440         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
3441         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
3442         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3443         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3444         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3445         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3446         /* Input mixer2 */
3447         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3448         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3449         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3450         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3451         /* Input mixer3 */
3452         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3453         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3454         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3455         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3456
3457         { }
3458 };
3459
3460 /* capture mixer elements */
3461 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
3462         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3463         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3464         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
3465         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
3466         {
3467                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3468                 /* The multiple "Capture Source" controls confuse alsamixer
3469                  * So call somewhat different..
3470                  * FIXME: the controls appear in the "playback" view!
3471                  */
3472                 /* .name = "Capture Source", */
3473                 .name = "Input Source",
3474                 .count = 2,
3475                 .info = alc882_mux_enum_info,
3476                 .get = alc882_mux_enum_get,
3477                 .put = alc882_mux_enum_put,
3478         },
3479         { } /* end */
3480 };
3481
3482 static struct snd_kcontrol_new alc882_capture_mixer[] = {
3483         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
3484         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
3485         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
3486         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
3487         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
3488         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
3489         {
3490                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3491                 /* The multiple "Capture Source" controls confuse alsamixer
3492                  * So call somewhat different..
3493                  * FIXME: the controls appear in the "playback" view!
3494                  */
3495                 /* .name = "Capture Source", */
3496                 .name = "Input Source",
3497                 .count = 3,
3498                 .info = alc882_mux_enum_info,
3499                 .get = alc882_mux_enum_get,
3500                 .put = alc882_mux_enum_put,
3501         },
3502         { } /* end */
3503 };
3504
3505 /* pcm configuration: identiacal with ALC880 */
3506 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
3507 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
3508 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
3509 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
3510
3511 /*
3512  * configuration and preset
3513  */
3514 static struct hda_board_config alc882_cfg_tbl[] = {
3515         { .modelname = "3stack-dig", .config = ALC882_3ST_DIG },
3516         { .modelname = "6stack-dig", .config = ALC882_6ST_DIG },
3517         { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI  */
3518         { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */
3519         { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */
3520         { .modelname = "auto", .config = ALC882_AUTO },
3521         {}
3522 };
3523
3524 static struct alc_config_preset alc882_presets[] = {
3525         [ALC882_3ST_DIG] = {
3526                 .mixers = { alc882_base_mixer },
3527                 .init_verbs = { alc882_init_verbs },
3528                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3529                 .dac_nids = alc882_dac_nids,
3530                 .dig_out_nid = ALC882_DIGOUT_NID,
3531                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3532                 .adc_nids = alc882_adc_nids,
3533                 .dig_in_nid = ALC882_DIGIN_NID,
3534                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3535                 .channel_mode = alc882_ch_modes,
3536                 .input_mux = &alc882_capture_source,
3537         },
3538         [ALC882_6ST_DIG] = {
3539                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
3540                 .init_verbs = { alc882_init_verbs },
3541                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3542                 .dac_nids = alc882_dac_nids,
3543                 .dig_out_nid = ALC882_DIGOUT_NID,
3544                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3545                 .adc_nids = alc882_adc_nids,
3546                 .dig_in_nid = ALC882_DIGIN_NID,
3547                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
3548                 .channel_mode = alc882_sixstack_modes,
3549                 .input_mux = &alc882_capture_source,
3550         },
3551 };
3552
3553
3554 /*
3555  * BIOS auto configuration
3556  */
3557 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
3558                                               hda_nid_t nid, int pin_type,
3559                                               int dac_idx)
3560 {
3561         /* set as output */
3562         struct alc_spec *spec = codec->spec;
3563         int idx; 
3564         
3565         if (spec->multiout.dac_nids[dac_idx] == 0x25)
3566                 idx = 4;
3567         else
3568                 idx = spec->multiout.dac_nids[dac_idx] - 2;
3569
3570         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
3571         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
3572         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
3573
3574 }
3575
3576 static void alc882_auto_init_multi_out(struct hda_codec *codec)
3577 {
3578         struct alc_spec *spec = codec->spec;
3579         int i;
3580
3581         for (i = 0; i <= HDA_SIDE; i++) {
3582                 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 
3583                 if (nid)
3584                         alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
3585         }
3586 }
3587
3588 static void alc882_auto_init_hp_out(struct hda_codec *codec)
3589 {
3590         struct alc_spec *spec = codec->spec;
3591         hda_nid_t pin;
3592
3593         pin = spec->autocfg.hp_pin;
3594         if (pin) /* connect to front */
3595                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
3596 }
3597
3598 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
3599 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
3600
3601 static void alc882_auto_init_analog_input(struct hda_codec *codec)
3602 {
3603         struct alc_spec *spec = codec->spec;
3604         int i;
3605
3606         for (i = 0; i < AUTO_PIN_LAST; i++) {
3607                 hda_nid_t nid = spec->autocfg.input_pins[i];
3608                 if (alc882_is_input_pin(nid)) {
3609                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3610                                             i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
3611                         if (nid != ALC882_PIN_CD_NID)
3612                                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3613                                                     AMP_OUT_MUTE);
3614                 }
3615         }
3616 }
3617
3618 /* almost identical with ALC880 parser... */
3619 static int alc882_parse_auto_config(struct hda_codec *codec)
3620 {
3621         struct alc_spec *spec = codec->spec;
3622         int err = alc880_parse_auto_config(codec);
3623
3624         if (err < 0)
3625                 return err;
3626         else if (err > 0)
3627                 /* hack - override the init verbs */
3628                 spec->init_verbs[0] = alc882_auto_init_verbs;
3629         return err;
3630 }
3631
3632 /* init callback for auto-configuration model -- overriding the default init */
3633 static int alc882_auto_init(struct hda_codec *codec)
3634 {
3635         alc_init(codec);
3636         alc882_auto_init_multi_out(codec);
3637         alc882_auto_init_hp_out(codec);
3638         alc882_auto_init_analog_input(codec);
3639         return 0;
3640 }
3641
3642 /*
3643  *  ALC882 Headphone poll in 3.5.1a or 3.5.2
3644  */
3645
3646 static int patch_alc882(struct hda_codec *codec)
3647 {
3648         struct alc_spec *spec;
3649         int err, board_config;
3650
3651         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3652         if (spec == NULL)
3653                 return -ENOMEM;
3654
3655         codec->spec = spec;
3656
3657         board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl);
3658
3659         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
3660                 printk(KERN_INFO "hda_codec: Unknown model for ALC882, trying auto-probe from BIOS...\n");
3661                 board_config = ALC882_AUTO;
3662         }
3663
3664         if (board_config == ALC882_AUTO) {
3665                 /* automatic parse from the BIOS config */
3666                 err = alc882_parse_auto_config(codec);
3667                 if (err < 0) {
3668                         alc_free(codec);
3669                         return err;
3670                 } else if (! err) {
3671                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
3672                         board_config = ALC882_3ST_DIG;
3673                 }
3674         }
3675
3676         if (board_config != ALC882_AUTO)
3677                 setup_preset(spec, &alc882_presets[board_config]);
3678
3679         spec->stream_name_analog = "ALC882 Analog";
3680         spec->stream_analog_playback = &alc882_pcm_analog_playback;
3681         spec->stream_analog_capture = &alc882_pcm_analog_capture;
3682
3683         spec->stream_name_digital = "ALC882 Digital";
3684         spec->stream_digital_playback = &alc882_pcm_digital_playback;
3685         spec->stream_digital_capture = &alc882_pcm_digital_capture;
3686
3687         if (! spec->adc_nids && spec->input_mux) {
3688                 /* check whether NID 0x07 is valid */
3689                 unsigned int wcap = get_wcaps(codec, 0x07);
3690                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
3691                 if (wcap != AC_WID_AUD_IN) {
3692                         spec->adc_nids = alc882_adc_nids_alt;
3693                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
3694                         spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
3695                         spec->num_mixers++;
3696                 } else {
3697                         spec->adc_nids = alc882_adc_nids;
3698                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
3699                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
3700                         spec->num_mixers++;
3701                 }
3702         }
3703
3704         codec->patch_ops = alc_patch_ops;
3705         if (board_config == ALC882_AUTO)
3706                 codec->patch_ops.init = alc882_auto_init;
3707
3708         return 0;
3709 }
3710
3711 /*
3712  * ALC262 support
3713  */
3714
3715 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
3716 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
3717
3718 #define alc262_dac_nids         alc260_dac_nids
3719 #define alc262_adc_nids         alc882_adc_nids
3720 #define alc262_adc_nids_alt     alc882_adc_nids_alt
3721
3722 #define alc262_modes            alc260_modes
3723 #define alc262_capture_source   alc882_capture_source
3724
3725 static struct snd_kcontrol_new alc262_base_mixer[] = {
3726         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3727         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3728         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3729         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3730         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3731         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3732         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3733         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3734         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3735         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3736         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
3737            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
3738         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
3739         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3740         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3741         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
3742         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3743         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3744         {
3745                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3746                 .name = "Capture Source",
3747                 .count = 1,
3748                 .info = alc882_mux_enum_info,
3749                 .get = alc882_mux_enum_get,
3750                 .put = alc882_mux_enum_put,
3751         },
3752         { } /* end */
3753 };                      
3754         
3755 #define alc262_capture_mixer            alc882_capture_mixer
3756 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
3757
3758 /*
3759  * generic initialization of ADC, input mixers and output mixers
3760  */
3761 static struct hda_verb alc262_init_verbs[] = {
3762         /*
3763          * Unmute ADC0-2 and set the default input to mic-in
3764          */
3765         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3766         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3767         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3768         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3769         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3770         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3771
3772         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3773          * mixer widget
3774          * Note: PASD motherboards uses the Line In 2 as the input for front panel
3775          * mic (mic 2)
3776          */
3777         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3778         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3779         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3780         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3781         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3782         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3783
3784         /*
3785          * Set up output mixers (0x0c - 0x0e)
3786          */
3787         /* set vol=0 to output mixers */
3788         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3789         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3790         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3791         /* set up input amps for analog loopback */
3792         /* Amp Indices: DAC = 0, mixer = 1 */
3793         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3794         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3795         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3796         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3797         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3798         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3799
3800         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3801         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3802         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3803         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3804         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3805         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3806
3807         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3808         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3809         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3810         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3811         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3812         
3813         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
3814         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
3815         
3816         /* FIXME: use matrix-type input source selection */
3817         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
3818         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
3819         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3820         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3821         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3822         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3823         /* Input mixer2 */
3824         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3825         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3826         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3827         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3828         /* Input mixer3 */
3829         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3830         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3831         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3832         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},      
3833
3834         { }
3835 };
3836
3837 /* add playback controls from the parsed DAC table */
3838 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
3839 {
3840         hda_nid_t nid;
3841         int err;
3842
3843         spec->multiout.num_dacs = 1;    /* only use one dac */
3844         spec->multiout.dac_nids = spec->private_dac_nids;
3845         spec->multiout.dac_nids[0] = 2;
3846
3847         nid = cfg->line_out_pins[0];
3848         if (nid) {
3849                 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
3850                                        HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
3851                         return err;
3852                 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
3853                                        HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
3854                         return err;
3855         }
3856
3857         nid = cfg->speaker_pin;
3858         if (nid) {
3859                 if (nid == 0x16) {
3860                         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
3861                                                HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
3862                                 return err;
3863                         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
3864                                                HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
3865                                 return err;
3866                 } else {
3867                         if (! cfg->line_out_pins[0])
3868                                 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
3869                                                HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
3870                                         return err;
3871                         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
3872                                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
3873                                 return err;
3874                 }
3875         }
3876         nid = cfg->hp_pin;
3877         if (nid) {
3878                 /* spec->multiout.hp_nid = 2; */
3879                 if (nid == 0x16) {
3880                         if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
3881                                                HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
3882                                 return err;
3883                         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
3884                                                HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
3885                                 return err;
3886                 } else {
3887                         if (! cfg->line_out_pins[0])
3888                                 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
3889                                                HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
3890                                         return err;
3891                         if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
3892                                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
3893                                 return err;
3894                 }
3895         }
3896         return 0;       
3897 }
3898
3899 /* identical with ALC880 */
3900 #define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
3901
3902 /*
3903  * generic initialization of ADC, input mixers and output mixers
3904  */
3905 static struct hda_verb alc262_volume_init_verbs[] = {
3906         /*
3907          * Unmute ADC0-2 and set the default input to mic-in
3908          */
3909         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3910         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3911         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3912         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3913         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3914         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3915
3916         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3917          * mixer widget
3918          * Note: PASD motherboards uses the Line In 2 as the input for front panel
3919          * mic (mic 2)
3920          */
3921         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3922         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3923         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3924         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3925         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3926         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3927
3928         /*
3929          * Set up output mixers (0x0c - 0x0f)
3930          */
3931         /* set vol=0 to output mixers */
3932         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3933         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3934         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3935         
3936         /* set up input amps for analog loopback */
3937         /* Amp Indices: DAC = 0, mixer = 1 */
3938         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3939         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3940         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3941         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3942         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3943         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3944
3945         /* FIXME: use matrix-type input source selection */
3946         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
3947         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
3948         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3949         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3950         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3951         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3952         /* Input mixer2 */
3953         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3954         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3955         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3956         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3957         /* Input mixer3 */
3958         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3959         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
3960         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
3961         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
3962
3963         { }
3964 };
3965
3966 /* pcm configuration: identiacal with ALC880 */
3967 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
3968 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
3969 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
3970 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
3971
3972 /*
3973  * BIOS auto configuration
3974  */
3975 static int alc262_parse_auto_config(struct hda_codec *codec)
3976 {
3977         struct alc_spec *spec = codec->spec;
3978         int err;
3979         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
3980
3981         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3982                                                 alc262_ignore)) < 0)
3983                 return err;
3984         if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
3985             ! spec->autocfg.hp_pin)
3986                 return 0; /* can't find valid BIOS pin config */
3987         if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
3988             (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
3989                 return err;
3990
3991         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3992
3993         if (spec->autocfg.dig_out_pin)
3994                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
3995         if (spec->autocfg.dig_in_pin)
3996                 spec->dig_in_nid = ALC262_DIGIN_NID;
3997
3998         if (spec->kctl_alloc)
3999                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4000
4001         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
4002         spec->input_mux = &spec->private_imux;
4003
4004         return 1;
4005 }
4006
4007 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
4008 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
4009 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
4010
4011
4012 /* init callback for auto-configuration model -- overriding the default init */
4013 static int alc262_auto_init(struct hda_codec *codec)
4014 {
4015         alc_init(codec);
4016         alc262_auto_init_multi_out(codec);
4017         alc262_auto_init_hp_out(codec);
4018         alc262_auto_init_analog_input(codec);
4019         return 0;
4020 }
4021
4022 /*
4023  * configuration and preset
4024  */
4025 static struct hda_board_config alc262_cfg_tbl[] = {
4026         { .modelname = "basic", .config = ALC262_BASIC },
4027         { .modelname = "auto", .config = ALC262_AUTO },
4028         {}
4029 };
4030
4031 static struct alc_config_preset alc262_presets[] = {
4032         [ALC262_BASIC] = {
4033                 .mixers = { alc262_base_mixer },
4034                 .init_verbs = { alc262_init_verbs },
4035                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
4036                 .dac_nids = alc262_dac_nids,
4037                 .hp_nid = 0x03,
4038                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
4039                 .channel_mode = alc262_modes,
4040                 .input_mux = &alc262_capture_source,
4041         },
4042 };
4043
4044 static int patch_alc262(struct hda_codec *codec)
4045 {
4046         struct alc_spec *spec;
4047         int board_config;
4048         int err;
4049
4050         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
4051         if (spec == NULL)
4052                 return -ENOMEM;
4053
4054         codec->spec = spec;
4055 #if 0
4056         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is under-run */
4057         {
4058         int tmp;
4059         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
4060         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
4061         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
4062         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
4063         }
4064 #endif
4065
4066         board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl);
4067         if (board_config < 0 || board_config >= ALC262_MODEL_LAST) {
4068                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...\n");
4069                 board_config = ALC262_AUTO;
4070         }
4071
4072         if (board_config == ALC262_AUTO) {
4073                 /* automatic parse from the BIOS config */
4074                 err = alc262_parse_auto_config(codec);
4075                 if (err < 0) {
4076                         alc_free(codec);
4077                         return err;
4078                 } else if (! err) {
4079                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
4080                         board_config = ALC262_BASIC;
4081                 }
4082         }
4083
4084         if (board_config != ALC262_AUTO)
4085                 setup_preset(spec, &alc262_presets[board_config]);
4086
4087         spec->stream_name_analog = "ALC262 Analog";
4088         spec->stream_analog_playback = &alc262_pcm_analog_playback;
4089         spec->stream_analog_capture = &alc262_pcm_analog_capture;
4090                 
4091         spec->stream_name_digital = "ALC262 Digital";
4092         spec->stream_digital_playback = &alc262_pcm_digital_playback;
4093         spec->stream_digital_capture = &alc262_pcm_digital_capture;
4094
4095         if (! spec->adc_nids && spec->input_mux) {
4096                 /* check whether NID 0x07 is valid */
4097                 unsigned int wcap = get_wcaps(codec, 0x07);
4098
4099                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4100                 if (wcap != AC_WID_AUD_IN) {
4101                         spec->adc_nids = alc262_adc_nids_alt;
4102                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
4103                         spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
4104                         spec->num_mixers++;
4105                 } else {
4106                         spec->adc_nids = alc262_adc_nids;
4107                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
4108                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
4109                         spec->num_mixers++;
4110                 }
4111         }
4112
4113         codec->patch_ops = alc_patch_ops;
4114         if (board_config == ALC262_AUTO)
4115                 codec->patch_ops.init = alc262_auto_init;
4116         
4117         return 0;
4118 }
4119
4120
4121 /*
4122  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
4123  */
4124
4125 /*
4126  * set the path ways for 2 channel output
4127  * need to set the codec line out and mic 1 pin widgets to inputs
4128  */
4129 static struct hda_verb alc861_threestack_ch2_init[] = {
4130         /* set pin widget 1Ah (line in) for input */
4131         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4132         /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
4133         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4134
4135         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
4136         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, //mic
4137         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, //line in
4138         { } /* end */
4139 };
4140 /*
4141  * 6ch mode
4142  * need to set the codec line out and mic 1 pin widgets to outputs
4143  */
4144 static struct hda_verb alc861_threestack_ch6_init[] = {
4145         /* set pin widget 1Ah (line in) for output (Back Surround)*/
4146         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4147         /* set pin widget 18h (mic1) for output (CLFE)*/
4148         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4149
4150         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
4151         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
4152
4153         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
4154         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, //mic
4155         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, //line in
4156         { } /* end */
4157 };
4158
4159 static struct hda_channel_mode alc861_threestack_modes[2] = {
4160         { 2, alc861_threestack_ch2_init },
4161         { 6, alc861_threestack_ch6_init },
4162 };
4163
4164 /* patch-ALC861 */
4165
4166 static struct snd_kcontrol_new alc861_base_mixer[] = {
4167         /* output mixer control */
4168         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
4169         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
4170         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
4171         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
4172         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
4173
4174         /*Input mixer control */
4175         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
4176            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
4177         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
4178         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
4179         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
4180         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
4181         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
4182         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
4183         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
4184         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
4185  
4186         /* Capture mixer control */
4187         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4188         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4189         {
4190                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4191                 .name = "Capture Source",
4192                 .count = 1,
4193                 .info = alc_mux_enum_info,
4194                 .get = alc_mux_enum_get,
4195                 .put = alc_mux_enum_put,
4196         },
4197         { } /* end */
4198 };
4199
4200 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
4201         /* output mixer control */
4202         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
4203         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
4204         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
4205         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
4206         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
4207
4208         /* Input mixer control */
4209         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
4210            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
4211         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
4212         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
4213         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
4214         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
4215         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
4216         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
4217         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
4218         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
4219  
4220         /* Capture mixer control */
4221         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4222         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4223         {
4224                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4225                 .name = "Capture Source",
4226                 .count = 1,
4227                 .info = alc_mux_enum_info,
4228                 .get = alc_mux_enum_get,
4229                 .put = alc_mux_enum_put,
4230         },
4231         {
4232                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4233                 .name = "Channel Mode",
4234                 .info = alc_ch_mode_info,
4235                 .get = alc_ch_mode_get,
4236                 .put = alc_ch_mode_put,
4237                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
4238         },
4239         { } /* end */
4240 };                      
4241         
4242 /*
4243  * generic initialization of ADC, input mixers and output mixers
4244  */
4245 static struct hda_verb alc861_base_init_verbs[] = {
4246         /*
4247          * Unmute ADC0 and set the default input to mic-in
4248          */
4249         /* port-A for surround (rear panel) */
4250         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4251         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
4252         /* port-B for mic-in (rear panel) with vref */
4253         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4254         /* port-C for line-in (rear panel) */
4255         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4256         /* port-D for Front */
4257         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4258         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
4259         /* port-E for HP out (front panel) */
4260         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
4261         /* route front PCM to HP */
4262         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
4263         /* port-F for mic-in (front panel) with vref */
4264         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4265         /* port-G for CLFE (rear panel) */
4266         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4267         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
4268         /* port-H for side (rear panel) */
4269         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4270         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
4271         /* CD-in */
4272         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4273         /* route front mic to ADC1*/
4274         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4275         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4276         
4277         /* Unmute DAC0~3 & spdif out*/
4278         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4279         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4280         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4281         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4282         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4283         
4284         /* Unmute Mixer 14 (mic) 1c (Line in)*/
4285         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4286         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4287         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4288         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4289         
4290         /* Unmute Stereo Mixer 15 */
4291         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4292         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4293         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4294         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
4295
4296         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4297         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4298         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4299         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4300         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4301         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4302         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4303         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4304         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
4305         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4306
4307         { }
4308 };
4309
4310 static struct hda_verb alc861_threestack_init_verbs[] = {
4311         /*
4312          * Unmute ADC0 and set the default input to mic-in
4313          */
4314         /* port-A for surround (rear panel) */
4315         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4316         /* port-B for mic-in (rear panel) with vref */
4317         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4318         /* port-C for line-in (rear panel) */
4319         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4320         /* port-D for Front */
4321         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
4322         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
4323         /* port-E for HP out (front panel) */
4324         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
4325         /* route front PCM to HP */
4326         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
4327         /* port-F for mic-in (front panel) with vref */
4328         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
4329         /* port-G for CLFE (rear panel) */
4330         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4331         /* port-H for side (rear panel) */
4332         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4333         /* CD-in */
4334         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
4335         /* route front mic to ADC1*/
4336         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4337         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4338         /* Unmute DAC0~3 & spdif out*/
4339         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4340         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4341         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4342         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4343         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4344         
4345         /* Unmute Mixer 14 (mic) 1c (Line in)*/
4346         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4347         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4348         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4349         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4350         
4351         /* Unmute Stereo Mixer 15 */
4352         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4353         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4354         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4355         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
4356
4357         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4358         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4359         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4360         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4361         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4362         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4363         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4364         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4365         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
4366         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4367         { }
4368 };
4369 /*
4370  * generic initialization of ADC, input mixers and output mixers
4371  */
4372 static struct hda_verb alc861_auto_init_verbs[] = {
4373         /*
4374          * Unmute ADC0 and set the default input to mic-in
4375          */
4376 //      {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4377         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4378         
4379         /* Unmute DAC0~3 & spdif out*/
4380         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4381         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4382         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4383         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4384         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4385         
4386         /* Unmute Mixer 14 (mic) 1c (Line in)*/
4387         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4388         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4389         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4390         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4391         
4392         /* Unmute Stereo Mixer 15 */
4393         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4394         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4395         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4396         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
4397
4398         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4399         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4400         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4401         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4402         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4403         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4404         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4405         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4406
4407         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4408         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4409         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},    
4410         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},            
4411         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4412         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4413         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},    
4414         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},    
4415
4416         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  // set Mic 1
4417
4418         { }
4419 };
4420
4421 /* pcm configuration: identiacal with ALC880 */
4422 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
4423 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
4424 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
4425 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
4426
4427
4428 #define ALC861_DIGOUT_NID       0x07
4429
4430 static struct hda_channel_mode alc861_8ch_modes[1] = {
4431         { 8, NULL }
4432 };
4433
4434 static hda_nid_t alc861_dac_nids[4] = {
4435         /* front, surround, clfe, side */
4436         0x03, 0x06, 0x05, 0x04
4437 };
4438
4439 static hda_nid_t alc861_adc_nids[1] = {
4440         /* ADC0-2 */
4441         0x08,
4442 };
4443
4444 static struct hda_input_mux alc861_capture_source = {
4445         .num_items = 5,
4446         .items = {
4447                 { "Mic", 0x0 },
4448                 { "Front Mic", 0x3 },
4449                 { "Line", 0x1 },
4450                 { "CD", 0x4 },
4451                 { "Mixer", 0x5 },
4452         },
4453 };
4454
4455 /* fill in the dac_nids table from the parsed pin configuration */
4456 static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
4457 {
4458         int i;
4459         hda_nid_t nid;
4460
4461         spec->multiout.dac_nids = spec->private_dac_nids;
4462         for (i = 0; i < cfg->line_outs; i++) {
4463                 nid = cfg->line_out_pins[i];
4464                 if (nid) {
4465                         if (i >= ARRAY_SIZE(alc861_dac_nids))
4466                                 continue;
4467                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
4468                 }
4469         }
4470         spec->multiout.num_dacs = cfg->line_outs;
4471         return 0;
4472 }
4473
4474 /* add playback controls from the parsed DAC table */
4475 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
4476                                              const struct auto_pin_cfg *cfg)
4477 {
4478         char name[32];
4479         static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
4480         hda_nid_t nid;
4481         int i, idx, err;
4482
4483         for (i = 0; i < cfg->line_outs; i++) {
4484                 nid = spec->multiout.dac_nids[i];
4485                 if (! nid)
4486                         continue;
4487                 if (nid == 0x05) {
4488                         /* Center/LFE */
4489                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
4490                                                HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
4491                                 return err;
4492                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
4493                                                HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
4494                                 return err;
4495                 } else {
4496                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
4497                                 if (nid == alc861_dac_nids[idx])
4498                                         break;
4499                         sprintf(name, "%s Playback Switch", chname[idx]);
4500                         if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4501                                                HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4502                                 return err;
4503                 }
4504         }
4505         return 0;
4506 }
4507
4508 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
4509 {
4510         int err;
4511         hda_nid_t nid;
4512
4513         if (! pin)
4514                 return 0;
4515
4516         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
4517                 nid = 0x03;
4518                 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
4519                                        HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4520                         return err;
4521                 spec->multiout.hp_nid = nid;
4522         }
4523         return 0;
4524 }
4525
4526 /* create playback/capture controls for input pins */
4527 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
4528 {
4529         struct hda_input_mux *imux = &spec->private_imux;
4530         int i, err, idx, idx1;
4531
4532         for (i = 0; i < AUTO_PIN_LAST; i++) {
4533                 switch(cfg->input_pins[i]) {
4534                 case 0x0c:
4535                         idx1 = 1;
4536                         idx = 2;        // Line In
4537                         break;
4538                 case 0x0f:
4539                         idx1 = 2;
4540                         idx = 2;        // Line In
4541                         break;
4542                 case 0x0d:
4543                         idx1 = 0;
4544                         idx = 1;        // Mic In 
4545                         break;
4546                 case 0x10:      
4547                         idx1 = 3;
4548                         idx = 1;        // Mic In 
4549                         break;
4550                 case 0x11:
4551                         idx1 = 4;
4552                         idx = 0;        // CD
4553                         break;
4554                 default:
4555                         continue;
4556                 }
4557
4558                 err = new_analog_input(spec, cfg->input_pins[i],
4559                                        auto_pin_cfg_labels[i], idx, 0x15);
4560                 if (err < 0)
4561                         return err;
4562
4563                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
4564                 imux->items[imux->num_items].index = idx1;
4565                 imux->num_items++;      
4566         }
4567         return 0;
4568 }
4569
4570 static struct snd_kcontrol_new alc861_capture_mixer[] = {
4571         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4572         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4573
4574         {
4575                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4576                 /* The multiple "Capture Source" controls confuse alsamixer
4577                  * So call somewhat different..
4578                  *FIXME: the controls appear in the "playback" view!
4579                  */
4580                 /* .name = "Capture Source", */
4581                 .name = "Input Source",
4582                 .count = 1,
4583                 .info = alc_mux_enum_info,
4584                 .get = alc_mux_enum_get,
4585                 .put = alc_mux_enum_put,
4586         },
4587         { } /* end */
4588 };
4589
4590 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
4591                                               int pin_type, int dac_idx)
4592 {
4593         /* set as output */
4594
4595         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
4596         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4597
4598 }
4599
4600 static void alc861_auto_init_multi_out(struct hda_codec *codec)
4601 {
4602         struct alc_spec *spec = codec->spec;
4603         int i;
4604
4605         for (i = 0; i < spec->autocfg.line_outs; i++) {
4606                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4607                 if (nid)
4608                         alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
4609         }
4610 }
4611
4612 static void alc861_auto_init_hp_out(struct hda_codec *codec)
4613 {
4614         struct alc_spec *spec = codec->spec;
4615         hda_nid_t pin;
4616
4617         pin = spec->autocfg.hp_pin;
4618         if (pin) /* connect to front */
4619                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
4620 }
4621
4622 static void alc861_auto_init_analog_input(struct hda_codec *codec)
4623 {
4624         struct alc_spec *spec = codec->spec;
4625         int i;
4626
4627         for (i = 0; i < AUTO_PIN_LAST; i++) {
4628                 hda_nid_t nid = spec->autocfg.input_pins[i];
4629                 if ((nid>=0x0c) && (nid <=0x11)) {
4630                         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4631                                             i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4632                 }
4633         }
4634 }
4635
4636 /* parse the BIOS configuration and set up the alc_spec */
4637 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
4638 static int alc861_parse_auto_config(struct hda_codec *codec)
4639 {
4640         struct alc_spec *spec = codec->spec;
4641         int err;
4642         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
4643
4644         if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4645                                                 alc861_ignore)) < 0)
4646                 return err;
4647         if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
4648             ! spec->autocfg.hp_pin)
4649                 return 0; /* can't find valid BIOS pin config */
4650
4651         if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
4652             (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
4653             (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 ||
4654             (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
4655                 return err;
4656
4657         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4658
4659         if (spec->autocfg.dig_out_pin)
4660                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
4661
4662         if (spec->kctl_alloc)
4663                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4664
4665         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
4666
4667         spec->input_mux = &spec->private_imux;
4668
4669         spec->adc_nids = alc861_adc_nids;
4670         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
4671         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
4672         spec->num_mixers++;
4673
4674         return 1;
4675 }
4676
4677 /* init callback for auto-configuration model -- overriding the default init */
4678 static int alc861_auto_init(struct hda_codec *codec)
4679 {
4680         alc_init(codec);
4681         alc861_auto_init_multi_out(codec);
4682         alc861_auto_init_hp_out(codec);
4683         alc861_auto_init_analog_input(codec);
4684
4685         return 0;
4686 }
4687
4688
4689 /*
4690  * configuration and preset
4691  */
4692 static struct hda_board_config alc861_cfg_tbl[] = {
4693         { .modelname = "3stack", .config = ALC861_3ST },
4694         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, .config = ALC861_3ST },
4695         { .modelname = "3stack-dig", .config = ALC861_3ST_DIG },
4696         { .modelname = "6stack-dig", .config = ALC861_6ST_DIG },
4697         { .modelname = "auto", .config = ALC861_AUTO },
4698         {}
4699 };
4700
4701 static struct alc_config_preset alc861_presets[] = {
4702         [ALC861_3ST] = {
4703                 .mixers = { alc861_3ST_mixer },
4704                 .init_verbs = { alc861_threestack_init_verbs },
4705                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
4706                 .dac_nids = alc861_dac_nids,
4707                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
4708                 .channel_mode = alc861_threestack_modes,
4709                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
4710                 .adc_nids = alc861_adc_nids,
4711                 .input_mux = &alc861_capture_source,
4712         },
4713         [ALC861_3ST_DIG] = {
4714                 .mixers = { alc861_base_mixer },
4715                 .init_verbs = { alc861_threestack_init_verbs },
4716                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
4717                 .dac_nids = alc861_dac_nids,
4718                 .dig_out_nid = ALC861_DIGOUT_NID,
4719                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
4720                 .channel_mode = alc861_threestack_modes,
4721                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
4722                 .adc_nids = alc861_adc_nids,
4723                 .input_mux = &alc861_capture_source,
4724         },
4725         [ALC861_6ST_DIG] = {
4726                 .mixers = { alc861_base_mixer },
4727                 .init_verbs = { alc861_base_init_verbs },
4728                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
4729                 .dac_nids = alc861_dac_nids,
4730                 .dig_out_nid = ALC861_DIGOUT_NID,
4731                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
4732                 .channel_mode = alc861_8ch_modes,
4733                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
4734                 .adc_nids = alc861_adc_nids,
4735                 .input_mux = &alc861_capture_source,
4736         },
4737 };      
4738
4739
4740 static int patch_alc861(struct hda_codec *codec)
4741 {
4742         struct alc_spec *spec;
4743         int board_config;
4744         int err;
4745
4746         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
4747         if (spec == NULL)
4748                 return -ENOMEM;
4749
4750         codec->spec = spec;     
4751
4752         board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl);
4753         if (board_config < 0 || board_config >= ALC861_MODEL_LAST) {
4754                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, trying auto-probe from BIOS...\n");
4755                 board_config = ALC861_AUTO;
4756         }
4757
4758         if (board_config == ALC861_AUTO) {
4759                 /* automatic parse from the BIOS config */
4760                 err = alc861_parse_auto_config(codec);
4761                 if (err < 0) {
4762                         alc_free(codec);
4763                         return err;
4764                 } else if (! err) {
4765                         printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
4766                    board_config = ALC861_3ST_DIG;
4767                 }
4768         }
4769
4770         if (board_config != ALC861_AUTO)
4771                 setup_preset(spec, &alc861_presets[board_config]);
4772
4773         spec->stream_name_analog = "ALC861 Analog";
4774         spec->stream_analog_playback = &alc861_pcm_analog_playback;
4775         spec->stream_analog_capture = &alc861_pcm_analog_capture;
4776
4777         spec->stream_name_digital = "ALC861 Digital";
4778         spec->stream_digital_playback = &alc861_pcm_digital_playback;
4779         spec->stream_digital_capture = &alc861_pcm_digital_capture;
4780
4781         codec->patch_ops = alc_patch_ops;
4782         if (board_config == ALC861_AUTO)
4783                 codec->patch_ops.init = alc861_auto_init;
4784                 
4785         return 0;
4786 }
4787
4788 /*
4789  * patch entries
4790  */
4791 struct hda_codec_preset snd_hda_preset_realtek[] = {
4792         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
4793         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
4794         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
4795         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4796         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
4797         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4798         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
4799         {} /* terminator */
4800 };