ce280c006be1f2ec8323747e39595ee7f61ff23d
[linux-2.6.git] / sound / pci / hda / patch_realtek.c
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for ALC 260/880/882 codecs
5  *
6  * Copyright (c) 2004 PeiSen Hou <pshou@realtek.com.tw>
7  *                    Takashi Iwai <tiwai@suse.de>
8  *
9  *  This driver is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This driver is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22  */
23
24 #include <sound/driver.h>
25 #include <linux/init.h>
26 #include <linux/delay.h>
27 #include <linux/slab.h>
28 #include <linux/pci.h>
29 #include <sound/core.h>
30 #include "hda_codec.h"
31 #include "hda_local.h"
32
33
34 /* ALC880 board config type */
35 enum {
36         ALC880_3ST,
37         ALC880_3ST_DIG,
38         ALC880_5ST,
39         ALC880_5ST_DIG,
40         ALC880_W810,
41         ALC880_Z71V,
42         ALC880_TEST,
43         ALC880_6ST_DIG,
44         ALC880_F1734,
45         ALC880_ASUS,
46         ALC880_ASUS_DIG,
47         ALC880_ASUS_W1V,
48         ALC880_UNIWILL_DIG,
49         ALC880_MODEL_LAST /* last tag */
50 };
51
52 /* ALC260 models */
53 enum {
54         ALC260_BASIC,
55         ALC260_HP,
56         ALC260_MODEL_LAST /* last tag */
57 };
58
59 struct alc_spec {
60         /* codec parameterization */
61         unsigned int front_panel: 1;    /* indicates the board has a front panel;
62                                          * not referred currently for any purpose,
63                                          * though...
64                                          */
65         
66         snd_kcontrol_new_t *mixers[2];  /* mixer arrays */
67         unsigned int num_mixers;
68
69         struct hda_verb *init_verbs;    /* initialization verbs
70                                          * don't forget NULL termination!
71                                          */
72
73         char *stream_name_analog;       /* analog PCM stream */
74         struct hda_pcm_stream *stream_analog_playback;
75         struct hda_pcm_stream *stream_analog_capture;
76
77         char *stream_name_digital;      /* digital PCM stream */ 
78         struct hda_pcm_stream *stream_digital_playback;
79         struct hda_pcm_stream *stream_digital_capture;
80
81         /* playback */
82         struct hda_multi_out multiout;  /* playback set-up
83                                          * max_channels, dacs must be set
84                                          * dig_out_nid and hp_nid are optional
85                                          */
86
87         /* capture */
88         unsigned int num_adc_nids;
89         hda_nid_t *adc_nids;
90         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
91
92         /* capture source */
93         const struct hda_input_mux *input_mux;
94         unsigned int cur_mux[3];
95
96         /* channel model */
97         const struct alc_channel_mode *channel_mode;
98         int num_channel_mode;
99
100         /* PCM information */
101         struct hda_pcm pcm_rec[2];      /* used in alc_build_pcms() */
102
103         struct semaphore bind_mutex;    /* for bound controls */
104 };
105
106 /* DAC/ADC assignment */
107
108 static hda_nid_t alc880_dac_nids[4] = {
109         /* front, rear, clfe, rear_surr */
110         0x02, 0x05, 0x04, 0x03
111 };
112
113 static hda_nid_t alc880_6st_dac_nids[4] = {
114         /* front, rear, clfe, rear_surr */
115         0x02, 0x03, 0x04, 0x05
116 };      
117
118 static hda_nid_t alc880_w810_dac_nids[3] = {
119         /* front, rear/surround, clfe */
120         0x02, 0x03, 0x04
121 };
122
123 static hda_nid_t alc880_z71v_dac_nids[1] = {
124         /* front only? */
125         0x02
126 };
127
128 #if 0
129 /* The datasheet says the node 0x07 is connected from inputs,
130  * but it shows zero connection in the real implementation on some devices.
131  */
132 static hda_nid_t alc880_adc_nids[3] = {
133         /* ADC0-2 */
134         0x07, 0x08, 0x09,
135 };
136 #else
137 static hda_nid_t alc880_adc_nids[2] = {
138         /* ADC1-2 */
139         0x08, 0x09,
140 };
141 #endif
142
143 #define ALC880_DIGOUT_NID       0x06
144 #define ALC880_DIGIN_NID        0x0a
145
146 static hda_nid_t alc260_dac_nids[1] = {
147         /* front */
148         0x02,
149 };
150
151 static hda_nid_t alc260_adc_nids[1] = {
152         /* ADC0 */
153         0x04,
154 };
155
156 static hda_nid_t alc260_hp_adc_nids[1] = {
157         /* ADC1 */
158         0x05,
159 };
160
161 #define ALC260_DIGOUT_NID       0x03
162 #define ALC260_DIGIN_NID        0x06
163
164 static struct hda_input_mux alc880_capture_source = {
165         .num_items = 4,
166         .items = {
167                 { "Mic", 0x0 },
168                 { "Front Mic", 0x3 },
169                 { "Line", 0x2 },
170                 { "CD", 0x4 },
171         },
172 };
173
174 //pshou 05/24/05
175 static struct hda_input_mux alc880_6stack_capture_source = {
176         .num_items = 4,
177         .items = {
178                 { "Mic", 0x0 },
179                 { "Front Mic", 0x1 },
180                 { "Line", 0x2 },
181                 { "CD", 0x4 },
182         },
183 };
184
185 static struct hda_input_mux alc260_capture_source = {
186         .num_items = 4,
187         .items = {
188                 { "Mic", 0x0 },
189                 { "Front Mic", 0x1 },
190                 { "Line", 0x2 },
191                 { "CD", 0x4 },
192         },
193 };
194
195 /*
196  * input MUX handling
197  */
198 static int alc_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
199 {
200         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
201         struct alc_spec *spec = codec->spec;
202         return snd_hda_input_mux_info(spec->input_mux, uinfo);
203 }
204
205 static int alc_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
206 {
207         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
208         struct alc_spec *spec = codec->spec;
209         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
210
211         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
212         return 0;
213 }
214
215 static int alc_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
216 {
217         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
218         struct alc_spec *spec = codec->spec;
219         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
220         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
221                                      spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
222 }
223
224 /*
225  * channel mode setting
226  */
227 struct alc_channel_mode {
228         int channels;
229         const struct hda_verb *sequence;
230 };
231
232
233 /*
234  * channel source setting (2/6 channel selection for 3-stack)
235  */
236
237 /*
238  * set the path ways for 2 channel output
239  * need to set the codec line out and mic 1 pin widgets to inputs
240  */
241 static struct hda_verb alc880_threestack_ch2_init[] = {
242         /* set pin widget 1Ah (line in) for input */
243         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
244         /* set pin widget 18h (mic1) for input, for mic also enable the vref */
245         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
246         /* mute the output for Line In PW */
247         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
248         /* mute for Mic1 PW */
249         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
250         { } /* end */
251 };
252
253 /*
254  * 6ch mode
255  * need to set the codec line out and mic 1 pin widgets to outputs
256  */
257 static struct hda_verb alc880_threestack_ch6_init[] = {
258         /* set pin widget 1Ah (line in) for output */
259         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
260         /* set pin widget 18h (mic1) for output */
261         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
262         /* unmute the output for Line In PW */
263         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
264         /* unmute for Mic1 PW */
265         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
266         /* for rear channel output using Line In 1
267          * set select widget connection (nid = 0x12) - to summer node
268          * for rear NID = 0x0f...offset 3 in connection list
269          */
270         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x3 },
271         /* for Mic1 - retask for center/lfe */
272         /* set select widget connection (nid = 0x10) - to summer node for
273          * front CLFE NID = 0x0e...offset 2 in connection list
274          */
275         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x2 },
276         { } /* end */
277 };
278
279 static struct alc_channel_mode alc880_threestack_modes[2] = {
280         { 2, alc880_threestack_ch2_init },
281         { 6, alc880_threestack_ch6_init },
282 };
283
284
285 /*
286  * channel source setting (6/8 channel selection for 5-stack)
287  */
288
289 /* set the path ways for 6 channel output
290  * need to set the codec line out and mic 1 pin widgets to inputs
291  */
292 static struct hda_verb alc880_fivestack_ch6_init[] = {
293         /* set pin widget 1Ah (line in) for input */
294         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
295         /* mute the output for Line In PW */
296         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
297         { } /* end */
298 };
299
300 /* need to set the codec line out and mic 1 pin widgets to outputs */
301 static struct hda_verb alc880_fivestack_ch8_init[] = {
302         /* set pin widget 1Ah (line in) for output */
303         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
304         /* unmute the output for Line In PW */
305         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
306         /* output for surround channel output using Line In 1 */
307         /* set select widget connection (nid = 0x12) - to summer node
308          * for surr_rear NID = 0x0d...offset 1 in connection list
309          */
310         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x1 },
311         { } /* end */
312 };
313
314 static struct alc_channel_mode alc880_fivestack_modes[2] = {
315         { 6, alc880_fivestack_ch6_init },
316         { 8, alc880_fivestack_ch8_init },
317 };
318
319 /*
320  * channel source setting for W810 system
321  *
322  * W810 has rear IO for:
323  * Front (DAC 02)
324  * Surround (DAC 03)
325  * Center/LFE (DAC 04)
326  * Digital out (06)
327  *
328  * The system also has a pair of internal speakers, and a headphone jack.
329  * These are both connected to Line2 on the codec, hence to DAC 02.
330  * 
331  * There is a variable resistor to control the speaker or headphone
332  * volume. This is a hardware-only device without a software API.
333  *
334  * Plugging headphones in will disable the internal speakers. This is
335  * implemented in hardware, not via the driver using jack sense. In
336  * a similar fashion, plugging into the rear socket marked "front" will
337  * disable both the speakers and headphones.
338  *
339  * For input, there's a microphone jack, and an "audio in" jack.
340  * These may not do anything useful with this driver yet, because I
341  * haven't setup any initialization verbs for these yet...
342  */
343
344 static struct alc_channel_mode alc880_w810_modes[1] = {
345         { 6, NULL }
346 };
347
348 static struct alc_channel_mode alc880_z71v_modes[1] = {
349         { 2, NULL }
350 };
351
352 //pshou 05/19/05
353 static struct alc_channel_mode alc880_sixstack_modes[1] = {
354         { 8, NULL },
355 };
356
357 /*
358  */
359 static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
360 {
361         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
362         struct alc_spec *spec = codec->spec;
363         int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
364
365         snd_assert(spec->channel_mode, return -ENXIO);
366         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
367         uinfo->count = 1;
368         uinfo->value.enumerated.items = items;
369         if (uinfo->value.enumerated.item >= items)
370                 uinfo->value.enumerated.item = items - 1;
371         sprintf(uinfo->value.enumerated.name, "%dch",
372                 spec->channel_mode[uinfo->value.enumerated.item].channels);
373         return 0;
374 }
375
376 static int alc880_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
377 {
378         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
379         struct alc_spec *spec = codec->spec;
380         int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
381         int i;
382
383         snd_assert(spec->channel_mode, return -ENXIO);
384         for (i = 0; i < items; i++) {
385                 if (spec->multiout.max_channels == spec->channel_mode[i].channels) {
386                         ucontrol->value.enumerated.item[0] = i;
387                         break;
388                 }
389         }
390         return 0;
391 }
392
393 static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
394 {
395         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
396         struct alc_spec *spec = codec->spec;
397         int mode;
398
399         snd_assert(spec->channel_mode, return -ENXIO);
400         mode = ucontrol->value.enumerated.item[0] ? 1 : 0;
401         if (spec->multiout.max_channels == spec->channel_mode[mode].channels &&
402             ! codec->in_resume)
403                 return 0;
404
405         /* change the current channel setting */
406         spec->multiout.max_channels = spec->channel_mode[mode].channels;
407         if (spec->channel_mode[mode].sequence)
408                 snd_hda_sequence_write(codec, spec->channel_mode[mode].sequence);
409
410         return 1;
411 }
412
413
414 /*
415  * bound volume controls
416  *
417  * bind multiple volumes (# indices, from 0)
418  */
419
420 #define AMP_VAL_IDX_SHIFT       19
421 #define AMP_VAL_IDX_MASK        (0x0f<<19)
422
423 static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
424 {
425         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
426         struct alc_spec *spec = codec->spec;
427         unsigned long pval;
428
429         down(&spec->bind_mutex);
430         pval = kcontrol->private_value;
431         kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
432         snd_hda_mixer_amp_switch_info(kcontrol, uinfo);
433         kcontrol->private_value = pval;
434         up(&spec->bind_mutex);
435         return 0;
436 }
437
438 static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
439 {
440         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
441         struct alc_spec *spec = codec->spec;
442         unsigned long pval;
443
444         down(&spec->bind_mutex);
445         pval = kcontrol->private_value;
446         kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
447         snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
448         kcontrol->private_value = pval;
449         up(&spec->bind_mutex);
450         return 0;
451 }
452
453 static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
454 {
455         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
456         struct alc_spec *spec = codec->spec;
457         unsigned long pval;
458         int i, indices, change = 0;
459
460         down(&spec->bind_mutex);
461         pval = kcontrol->private_value;
462         indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
463         for (i = 0; i < indices; i++) {
464                 kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
465                 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
466         }
467         kcontrol->private_value = pval;
468         up(&spec->bind_mutex);
469         return change;
470 }
471
472 #define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
473         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
474           .info = alc_bind_switch_info, \
475           .get = alc_bind_switch_get, \
476           .put = alc_bind_switch_put, \
477           .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
478
479 #define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir)
480
481 /*
482  */
483
484 /* 3-stack mode
485  * Pin assignment: Front=0x14, Line-In/Rear=0x1a, Mic/CLFE=0x18, F-Mic=0x1b
486  *                 HP=0x19
487  */
488 static snd_kcontrol_new_t alc880_base_mixer[] = {
489         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
490         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
491         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
492         ALC_BIND_MUTE("Surround Playback Switch", 0x1a, 2, HDA_INPUT),
493         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
494         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
495         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
496         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
497         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
498         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
499         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
500         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
501         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
502         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
503         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
504         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
505         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
506         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
507         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
508         ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
509         /* We don't use NID 0x07 - see above */
510         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
511         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
512         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
513         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
514         {
515                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
516                 /* The multiple "Capture Source" controls confuse alsamixer
517                  * So call somewhat different..
518                  * FIXME: the controls appear in the "playback" view!
519                  */
520                 /* .name = "Capture Source", */
521                 .name = "Input Source",
522                 .count = 2,
523                 .info = alc_mux_enum_info,
524                 .get = alc_mux_enum_get,
525                 .put = alc_mux_enum_put,
526         },
527         {
528                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
529                 .name = "Channel Mode",
530                 .info = alc880_ch_mode_info,
531                 .get = alc880_ch_mode_get,
532                 .put = alc880_ch_mode_put,
533         },
534         { } /* end */
535 };
536
537 /* 5-stack mode
538  * Pin assignment: Front=0x14, Rear=0x17, CLFE=0x16
539  *                 Line-In/Side=0x1a, Mic=0x18, F-Mic=0x1b, HP=0x19
540  */
541 static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
542         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
543         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
544         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
545         ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
546         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
547         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
548         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
549         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
550         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
551         ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
552         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
553         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
554         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
555         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
556         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
557         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
558         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
559         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
560         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
561         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
562         /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), */
563         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
564         /* We don't use NID 0x07 - see above */
565         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
566         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
567         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
568         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
569         {
570                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
571                 /* The multiple "Capture Source" controls confuse alsamixer
572                  * So call somewhat different..
573                  * FIXME: the controls appear in the "playback" view!
574                  */
575                 /* .name = "Capture Source", */
576                 .name = "Input Source",
577                 .count = 2,
578                 .info = alc_mux_enum_info,
579                 .get = alc_mux_enum_get,
580                 .put = alc_mux_enum_put,
581         },
582         {
583                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
584                 .name = "Channel Mode",
585                 .info = alc880_ch_mode_info,
586                 .get = alc880_ch_mode_get,
587                 .put = alc880_ch_mode_put,
588         },
589         { } /* end */
590 };
591
592 static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
593         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
594         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
595         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
596         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
597         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
598         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
599         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
600         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
601         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
602         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
603         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
604         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
605         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
606         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
607         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
608         {
609                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
610                 /* The multiple "Capture Source" controls confuse alsamixer
611                  * So call somewhat different..
612                  * FIXME: the controls appear in the "playback" view!
613                  */
614                 /* .name = "Capture Source", */
615                 .name = "Input Source",
616                 .count = 3,
617                 .info = alc_mux_enum_info,
618                 .get = alc_mux_enum_get,
619                 .put = alc_mux_enum_put,
620         },
621         { } /* end */
622 };
623
624 static snd_kcontrol_new_t alc880_z71v_mixer[] = {
625         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
626         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
627         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
628         ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
629         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
630         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
631         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
632         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
633         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
634         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
635         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
636         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
637         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
638         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
639         {
640                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
641                 /* The multiple "Capture Source" controls confuse alsamixer
642                  * So call somewhat different..
643                  * FIXME: the controls appear in the "playback" view!
644                  */
645                 /* .name = "Capture Source", */
646                 .name = "Input Source",
647                 .count = 3,
648                 .info = alc_mux_enum_info,
649                 .get = alc_mux_enum_get,
650                 .put = alc_mux_enum_put,
651         },
652         { } /* end */
653 };
654
655 //pshou 05/24/05
656 static snd_kcontrol_new_t alc880_six_stack_mixer[] = {
657         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
658         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
659         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
660         ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
661         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
662         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
663         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
664         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
665         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
666         ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
667         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
668         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
669         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
670         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
671         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
672         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
673         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
674         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
675         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
676         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
677         /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), */
678         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
679         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
680         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
681         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
682         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
683         {
684                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
685                 /* The multiple "Capture Source" controls confuse alsamixer
686                  * So call somewhat different..
687                  * FIXME: the controls appear in the "playback" view!
688                  */
689                 /* .name = "Capture Source", */
690                 .name = "Input Source",
691                 .count = 2,
692                 .info = alc_mux_enum_info,
693                 .get = alc_mux_enum_get,
694                 .put = alc_mux_enum_put,
695         },
696         {
697                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
698                 .name = "Channel Mode",
699                 .info = alc880_ch_mode_info,
700                 .get = alc880_ch_mode_get,
701                 .put = alc880_ch_mode_put,
702         },
703         { } /* end */
704 };
705
706 // 03/08/05  Fujitsu
707 static snd_kcontrol_new_t alc880_2_jack_mixer[] = {
708         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
709         ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
710         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
711         ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
715         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
716         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
717         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
718         {
719                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
720                 /* The multiple "Capture Source" controls confuse alsamixer
721                  * So call somewhat different..
722                  * FIXME: the controls appear in the "playback" view!
723                  */
724                 /* .name = "Capture Source", */
725                 .name = "Input Source",
726                 .count = 1,
727                 .info = alc_mux_enum_info,
728                 .get = alc_mux_enum_get,
729                 .put = alc_mux_enum_put,
730         },
731         { } /* end */
732 };
733
734 //pshou 04/24/05
735 static snd_kcontrol_new_t alc880_asus_mixer[] = {
736         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
737         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
738         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
739         ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
740         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
741         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
742         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
743         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
744         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
745         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
746         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
747         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
748         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
749         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
750         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
751         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
752         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
753         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
754         {
755                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
756                 /* The multiple "Capture Source" controls confuse alsamixer
757                  * So call somewhat different..
758                  * FIXME: the controls appear in the "playback" view!
759                  */
760                 /* .name = "Capture Source", */
761                 .name = "Input Source",
762                 .count = 2,
763                 .info = alc_mux_enum_info,
764                 .get = alc_mux_enum_get,
765                 .put = alc_mux_enum_put,
766         },
767         {
768                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
769                 .name = "Channel Mode",
770                 .info = alc880_ch_mode_info,
771                 .get = alc880_ch_mode_get,
772                 .put = alc880_ch_mode_put,
773         },
774         { } /* end */
775 };
776
777 // pshou 05/03/05
778 static snd_kcontrol_new_t alc880_asus_w1v_mixer[] = {
779         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
780         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
781         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
782         ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
783         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
784         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
785         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
786         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
787         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
788         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
789         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
790         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
791         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
792         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
793         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
794         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
795         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
796         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
797         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
798         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
799         {
800                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
801                 /* The multiple "Capture Source" controls confuse alsamixer
802                  * So call somewhat different..
803                  * FIXME: the controls appear in the "playback" view!
804                  */
805                 /* .name = "Capture Source", */
806                 .name = "Input Source",
807                 .count = 2,
808                 .info = alc_mux_enum_info,
809                 .get = alc_mux_enum_get,
810                 .put = alc_mux_enum_put,
811         },
812         {
813                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
814                 .name = "Channel Mode",
815                 .info = alc880_ch_mode_info,
816                 .get = alc880_ch_mode_get,
817                 .put = alc880_ch_mode_put,
818         },
819         { } /* end */
820 };
821 /*
822  */
823 static int alc_build_controls(struct hda_codec *codec)
824 {
825         struct alc_spec *spec = codec->spec;
826         int err;
827         int i;
828
829         for (i = 0; i < spec->num_mixers; i++) {
830                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
831                 if (err < 0)
832                         return err;
833         }
834
835         if (spec->multiout.dig_out_nid) {
836                 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
837                 if (err < 0)
838                         return err;
839         }
840         if (spec->dig_in_nid) {
841                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
842                 if (err < 0)
843                         return err;
844         }
845         return 0;
846 }
847
848 /*
849  * initialize the codec volumes, etc
850  */
851
852 #define AMP_IN_MUTE(idx)        (0x7080 | ((idx)<<8))
853 #define AMP_IN_UNMUTE(idx)      (0x7000 | ((idx)<<8))
854 #define AMP_OUT_MUTE    0xb080
855 #define AMP_OUT_UNMUTE  0xb000
856 #define AMP_OUT_ZERO    0xb000
857 #define PIN_IN          0x20
858 #define PIN_VREF80      0x24
859 #define PIN_VREF50      0x21
860 #define PIN_OUT         0x40
861 #define PIN_HP          0xc0
862
863 static struct hda_verb alc880_init_verbs_three_stack[] = {
864         /* Set pin widgets for output */
865         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
866         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
867         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
868         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
869         /* Line In pin widget for input */
870         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
871         /* CD pin widget for input */
872         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
873         /* Mic1 (rear panel) pin widget for input and vref at 80% */
874         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
875         /* Mic2 (front panel) pin widget for input and vref at 80% */
876         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
877         /* unmute capture amp left and right */
878         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
879         /* set connection select to mic in */
880         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
881         /* unmute capture1 amp left and right */
882         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
883         /* set connection select to mic in */
884         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
885         /* unmute capture2 amp left and right */
886         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
887         /* set connection select to mic in */
888         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
889         /* set vol=0 front mixer amp */
890         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
891         /* unmute front-out pin widget amp (no gain on this amp) */
892         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
893         /* set vol=0 rear mixer amp */
894         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
895         /* mute line-in pin widget amp left and right (no gain on this amp) */
896         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
897         /* set vol=0 clfe mixer amp */
898         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
899         /* mute mic pin widget amp left and right (no gain on this amp) */
900         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
901
902         /* using rear surround as the path for headphone output */
903         /* set vol=0 rear surround mixer amp */
904         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
905         /* PASD 3 stack boards use the Mic 2 as the headphone output */
906         /* need to program the selector associated with the Mic 2 pin widget to
907          * surround path (index 0x01) for headphone output */
908         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
909         /* unmute pin widget amp left and right (no gain on this amp) */
910         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
911         /* need to retask the Mic 2 pin widget to output */
912         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
913
914         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer widget(nid=0x0B)
915          * to support the input path of analog loopback
916          * Note: PASD motherboards uses the Line In 2 as the input for front panel
917          * mic (mic 2)
918          */
919         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
920         /* mute CD */
921         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
922         /* unmute Line In */
923         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
924         /* mute Mic 1 */
925         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
926         /* mute Line In 2 (for PASD boards Mic 2) */
927         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
928
929         /* Unmute input amps for the line out paths to support the output path of
930          * analog loopback
931          * the mixers on the output path has 2 inputs, one from the DAC and one
932          * from the mixer
933          */
934         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
935         /* Unmute Front out path */
936         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
937         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
938         /* Unmute Surround (used as HP) out path */
939         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
940         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
941         /* Unmute C/LFE out path */
942         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
943         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
944         /* Unmute rear Surround out path */
945         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
946         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
947
948         { }
949 };
950
951 static struct hda_verb alc880_init_verbs_five_stack[] = {
952         /* Set pin widgets for output */
953         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
954         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
955         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
956         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
957         /* Line In pin widget for input */
958         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
959         /* CD pin widget for input */
960         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
961         /* Mic1 (rear panel) pin widget for input and vref at 80% */
962         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
963         /* Mic2 (front panel) pin widget for input and vref at 80% */
964         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
965         /* mute capture amp left and right */
966         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
967         /* set connection select to mic in */
968         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
969         /* mute amp1 left and right */
970         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
971         /* set connection select to mic in */
972         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
973         /* mute amp left and right */
974         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
975         /* set connection select to mic in */
976         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
977         /* set vol=0 front mixer amp */
978         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
979         /* unmute front-out pin widget amp (no gain on this amp) */
980         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
981         /* set vol=0 rear mixer amp */
982         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
983         /* unmute rear-out pin widget (no gain on this amp) */
984         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
985         /* set vol=0 clfe mixer amp */
986         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
987         /* unmute clfe-pin widget amp (no gain on this amp) */
988         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
989
990         /* using rear surround as the path for headphone output */
991         /* set vol=0 rear surround mixer amp */
992         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
993         /* PASD 3 stack boards use the Mic 2 as the headphone output */
994         /* need to program the selector associated with the Mic 2 pin widget to
995          * surround path (index 0x01) for headphone output
996          */
997         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
998         /* mute pin widget amp left and right (no gain on this amp) */
999         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1000         /* need to retask the Mic 2 pin widget to output */
1001         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1002
1003         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
1004          * widget(nid=0x0B) to support the input path of analog loopback
1005          */
1006         /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
1007         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
1008         /* unmute CD */
1009         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1010         /* unmute Line In */
1011         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1012         /* unmute Mic 1 */
1013         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1014         /* unmute Line In 2 (for PASD boards Mic 2) */
1015         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1016
1017         /* Unmute input amps for the line out paths to support the output path of
1018          * analog loopback
1019          * the mixers on the output path has 2 inputs, one from the DAC and
1020          * one from the mixer
1021          */
1022         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
1023         /* Unmute Front out path */
1024         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1025         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1026         /* Unmute Surround (used as HP) out path */
1027         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1028         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1029         /* Unmute C/LFE out path */
1030         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1031         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1032         /* Unmute rear Surround out path */
1033         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1034         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1035
1036         { }
1037 };
1038
1039 static struct hda_verb alc880_w810_init_verbs[] = {
1040         /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
1041         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1042
1043         /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
1044         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1045
1046         /* front channel selector/amp: output 0: unmuted, max volume */
1047         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1048
1049         /* front out pin: muted, (no volume selection)  */
1050         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1051
1052         /* front out pin: NOT headphone enable, out enable, vref disabled */
1053         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1054
1055
1056         /* surround channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
1057         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1058
1059         /* surround channel selector/amp: input 1: capture mix: muted, (no volume selection) */
1060         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1061
1062         /* surround channel selector/amp: output 0: unmuted, max volume */
1063         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1064
1065         /* surround out pin: muted, (no volume selection)  */
1066         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1067
1068         /* surround out pin: NOT headphone enable, out enable, vref disabled */
1069         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1070
1071
1072         /* c/lfe channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
1073         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1074
1075         /* c/lfe channel selector/amp: input 1: capture mix: muted, (no volume selection) */
1076         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1077
1078         /* c/lfe channel selector/amp: output 0: unmuted, max volume */
1079         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1080
1081         /* c/lfe out pin: muted, (no volume selection)  */
1082         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1083
1084         /* c/lfe out pin: NOT headphone enable, out enable, vref disabled */
1085         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1086
1087
1088         /* hphone/speaker input selector: front DAC */
1089         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1090
1091         /* hphone/speaker out pin: muted, (no volume selection)  */
1092         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1093
1094         /* hphone/speaker out pin: NOT headphone enable, out enable, vref disabled */
1095         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1096
1097
1098         { }
1099 };
1100
1101 static struct hda_verb alc880_z71v_init_verbs[] = {
1102         /* front channel selector/amp: muted, DAC and mix (no vol) */
1103         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1104         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1105         /* front channel selector/amp: output 0: vol=0 */
1106         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1107         /* front out pin: unmuted, (no volume selection)  */
1108         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1109         /* front out pin: NOT headphone enable, out enable, vref disabled */
1110         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1111         /* headphone channel selector/amp: muted, DAC and mix (no vol) */
1112         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1113         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1114         /* headphone channel selector/amp: output 0: vol=0 */
1115         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1116         /* headphone out pin: muted, (no volume selection) */
1117         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1118         /* headpohne out pin: headphone enable, out enable, vref disabled */
1119         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1120
1121         /* Line In pin widget for input */
1122         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1123         /* CD pin widget for input */
1124         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1125         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1126         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1127         /* Mic2 (front panel) pin widget for input and vref at 80% */
1128         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1129         /* unmute amp left and right */
1130         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1131         /* set connection select to mic in */
1132         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1133         /* unmute amp left and right */
1134         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1135         /* set connection select to mic in */
1136         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1137         /* unmute amp left and right */
1138         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1139         /* set connection select to mic in */
1140         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1141         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
1142          * widget(nid=0x0B) to support the input path of analog loopback
1143          */
1144         /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
1145         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
1146         /* unmute CD */
1147         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1148         /* unmute Line In */
1149         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1150         /* unmute Mic 1 */
1151         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1152         /* unmute Line In 2 (for PASD boards Mic 2) */
1153         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1154
1155         { }
1156 };
1157
1158 //pshou 05/24/05
1159 static struct hda_verb alc880_six_stack_init_verbs[] = {
1160         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1161         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1162         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1163         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1164         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1165         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1166         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1167         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1168         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1169         
1170         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1171         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1172         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1173         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1174
1175         /* unmute amp left and right */
1176         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1177         {0x07, AC_VERB_SET_CONNECT_SEL, 0x02},
1178         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1179         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1180         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1181         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1182         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1183         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1184         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1185         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1186         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1187
1188         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
1189          * widget(nid=0x0B) to support the input path of analog loopback
1190          */
1191         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1192         /* unmute Line In */
1193         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1194         /* unmute Mic 1 */
1195         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1196         /* unmute Mic 2  */
1197         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1198
1199         /* Unmute Front out path */
1200         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1201         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1202         /* Unmute Surround (used as HP) out path */
1203         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1204         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1205         /* Unmute C/LFE out path */
1206         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1207         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mute */
1208         /* Unmute rear Surround out path */
1209         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1210         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1211
1212         { }
1213 };
1214
1215 static struct hda_verb alc880_2_jack_init_verbs[] = {
1216         /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
1217         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1218         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1219         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1220         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1221         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1222         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1223         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1224         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1225         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1226         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1227         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1228         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1229         {0x07, AC_VERB_SET_CONNECT_SEL, 0x02},
1230         {0x0C, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1231         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1232         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1233         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1234         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1235         {0x1B, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1236         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1237         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1238         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1239         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1240         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1241         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1242         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1243
1244         { }
1245 };
1246
1247 static struct hda_verb alc880_asus_init_verbs[] = {
1248         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1249         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1250         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1251         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1252
1253         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1254         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1255         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1256         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1257         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
1258         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
1259         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
1260         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1261         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1262         
1263         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
1264         /* unmute CD */
1265         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1266         /* unmute Line In */
1267         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1268         /* unmute Mic 1 */
1269         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1270         /* unmute Line In 2 (for PASD boards Mic 2) */
1271         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1272
1273         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
1274         /* Unmute Front out path */
1275         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1276         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1277         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1278         /* Unmute Surround (used as HP) out path */
1279         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1280         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1281         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1282         /* Unmute C/LFE out path */
1283         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1284         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1285         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1286
1287         { }
1288 };
1289
1290
1291 static int alc_init(struct hda_codec *codec)
1292 {
1293         struct alc_spec *spec = codec->spec;
1294         snd_hda_sequence_write(codec, spec->init_verbs);
1295         return 0;
1296 }
1297
1298 #ifdef CONFIG_PM
1299 /*
1300  * resume
1301  */
1302 static int alc_resume(struct hda_codec *codec)
1303 {
1304         struct alc_spec *spec = codec->spec;
1305         int i;
1306
1307         alc_init(codec);
1308         for (i = 0; i < spec->num_mixers; i++) {
1309                 snd_hda_resume_ctls(codec, spec->mixers[i]);
1310         }
1311         if (spec->multiout.dig_out_nid)
1312                 snd_hda_resume_spdif_out(codec);
1313         if (spec->dig_in_nid)
1314                 snd_hda_resume_spdif_in(codec);
1315
1316         return 0;
1317 }
1318 #endif
1319
1320 /*
1321  * Analog playback callbacks
1322  */
1323 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
1324                                     struct hda_codec *codec,
1325                                     snd_pcm_substream_t *substream)
1326 {
1327         struct alc_spec *spec = codec->spec;
1328         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1329 }
1330
1331 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1332                                        struct hda_codec *codec,
1333                                        unsigned int stream_tag,
1334                                        unsigned int format,
1335                                        snd_pcm_substream_t *substream)
1336 {
1337         struct alc_spec *spec = codec->spec;
1338         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1339                                                 format, substream);
1340 }
1341
1342 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1343                                        struct hda_codec *codec,
1344                                        snd_pcm_substream_t *substream)
1345 {
1346         struct alc_spec *spec = codec->spec;
1347         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1348 }
1349
1350 /*
1351  * Digital out
1352  */
1353 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1354                                         struct hda_codec *codec,
1355                                         snd_pcm_substream_t *substream)
1356 {
1357         struct alc_spec *spec = codec->spec;
1358         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1359 }
1360
1361 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1362                                          struct hda_codec *codec,
1363                                          snd_pcm_substream_t *substream)
1364 {
1365         struct alc_spec *spec = codec->spec;
1366         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1367 }
1368
1369 /*
1370  * Analog capture
1371  */
1372 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1373                                       struct hda_codec *codec,
1374                                       unsigned int stream_tag,
1375                                       unsigned int format,
1376                                       snd_pcm_substream_t *substream)
1377 {
1378         struct alc_spec *spec = codec->spec;
1379
1380         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1381                                    stream_tag, 0, format);
1382         return 0;
1383 }
1384
1385 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1386                                       struct hda_codec *codec,
1387                                       snd_pcm_substream_t *substream)
1388 {
1389         struct alc_spec *spec = codec->spec;
1390
1391         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1392         return 0;
1393 }
1394
1395
1396 /*
1397  */
1398 static struct hda_pcm_stream alc880_pcm_analog_playback = {
1399         .substreams = 1,
1400         .channels_min = 2,
1401         .channels_max = 8,
1402         .nid = 0x02, /* NID to query formats and rates */
1403         .ops = {
1404                 .open = alc880_playback_pcm_open,
1405                 .prepare = alc880_playback_pcm_prepare,
1406                 .cleanup = alc880_playback_pcm_cleanup
1407         },
1408 };
1409
1410 static struct hda_pcm_stream alc880_pcm_analog_capture = {
1411         .substreams = 2,
1412         .channels_min = 2,
1413         .channels_max = 2,
1414         .nid = 0x08, /* NID to query formats and rates
1415                       * (0x07 might be broken on some devices)
1416                       */
1417         .ops = {
1418                 .prepare = alc880_capture_pcm_prepare,
1419                 .cleanup = alc880_capture_pcm_cleanup
1420         },
1421 };
1422
1423 static struct hda_pcm_stream alc880_pcm_digital_playback = {
1424         .substreams = 1,
1425         .channels_min = 2,
1426         .channels_max = 2,
1427         /* NID is set in alc_build_pcms */
1428         .ops = {
1429                 .open = alc880_dig_playback_pcm_open,
1430                 .close = alc880_dig_playback_pcm_close
1431         },
1432 };
1433
1434 static struct hda_pcm_stream alc880_pcm_digital_capture = {
1435         .substreams = 1,
1436         .channels_min = 2,
1437         .channels_max = 2,
1438         /* NID is set in alc_build_pcms */
1439 };
1440
1441 static int alc_build_pcms(struct hda_codec *codec)
1442 {
1443         struct alc_spec *spec = codec->spec;
1444         struct hda_pcm *info = spec->pcm_rec;
1445         int i;
1446
1447         codec->num_pcms = 1;
1448         codec->pcm_info = info;
1449
1450         info->name = spec->stream_name_analog;
1451         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1452         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1453
1454         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1455         for (i = 0; i < spec->num_channel_mode; i++) {
1456                 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1457                     info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1458                 }
1459         }
1460
1461         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1462                 codec->num_pcms++;
1463                 info++;
1464                 info->name = spec->stream_name_digital;
1465                 if (spec->multiout.dig_out_nid) {
1466                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
1467                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1468                 }
1469                 if (spec->dig_in_nid) {
1470                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
1471                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1472                 }
1473         }
1474
1475         return 0;
1476 }
1477
1478 static void alc_free(struct hda_codec *codec)
1479 {
1480         kfree(codec->spec);
1481 }
1482
1483 /*
1484  */
1485 static struct hda_codec_ops alc_patch_ops = {
1486         .build_controls = alc_build_controls,
1487         .build_pcms = alc_build_pcms,
1488         .init = alc_init,
1489         .free = alc_free,
1490 #ifdef CONFIG_PM
1491         .resume = alc_resume,
1492 #endif
1493 };
1494
1495
1496 /*
1497  * Test configuration for debugging
1498  *
1499  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
1500  * enum controls.
1501  */
1502 #ifdef CONFIG_SND_DEBUG
1503 static hda_nid_t alc880_test_dac_nids[4] = {
1504         0x02, 0x03, 0x04, 0x05
1505 };
1506
1507 static struct hda_input_mux alc880_test_capture_source = {
1508         .num_items = 5,
1509         .items = {
1510                 { "In-1", 0x0 },
1511                 { "In-2", 0x1 },
1512                 { "In-3", 0x2 },
1513                 { "In-4", 0x3 },
1514                 { "CD", 0x4 },
1515         },
1516 };
1517
1518 static struct alc_channel_mode alc880_test_modes[4] = {
1519         { 2, NULL },
1520         { 4, NULL },
1521         { 6, NULL },
1522         { 8, NULL },
1523 };
1524
1525 static int alc_test_pin_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1526 {
1527         static char *texts[] = {
1528                 "N/A", "Line Out", "HP Out",
1529                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1530         };
1531         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1532         uinfo->count = 1;
1533         uinfo->value.enumerated.items = 8;
1534         if (uinfo->value.enumerated.item >= 8)
1535                 uinfo->value.enumerated.item = 7;
1536         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1537         return 0;
1538 }
1539
1540 static int alc_test_pin_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1541 {
1542         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1543         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1544         unsigned int pin_ctl, item = 0;
1545
1546         pin_ctl = snd_hda_codec_read(codec, nid, 0,
1547                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1548         if (pin_ctl & AC_PINCTL_OUT_EN) {
1549                 if (pin_ctl & AC_PINCTL_HP_EN)
1550                         item = 2;
1551                 else
1552                         item = 1;
1553         } else if (pin_ctl & AC_PINCTL_IN_EN) {
1554                 switch (pin_ctl & AC_PINCTL_VREFEN) {
1555                 case AC_PINCTL_VREF_HIZ: item = 3; break;
1556                 case AC_PINCTL_VREF_50:  item = 4; break;
1557                 case AC_PINCTL_VREF_GRD: item = 5; break;
1558                 case AC_PINCTL_VREF_80:  item = 6; break;
1559                 case AC_PINCTL_VREF_100: item = 7; break;
1560                 }
1561         }
1562         ucontrol->value.enumerated.item[0] = item;
1563         return 0;
1564 }
1565
1566 static int alc_test_pin_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1567 {
1568         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1569         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1570         static unsigned int ctls[] = {
1571                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1572                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1573                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1574                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1575                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1576                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1577         };
1578         unsigned int old_ctl, new_ctl;
1579
1580         old_ctl = snd_hda_codec_read(codec, nid, 0,
1581                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1582         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1583         if (old_ctl != new_ctl) {
1584                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
1585                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1586                                     ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);
1587                 return 1;
1588         }
1589         return 0;
1590 }
1591
1592 static int alc_test_pin_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1593 {
1594         static char *texts[] = {
1595                 "Front", "Surround", "CLFE", "Side"
1596         };
1597         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1598         uinfo->count = 1;
1599         uinfo->value.enumerated.items = 4;
1600         if (uinfo->value.enumerated.item >= 4)
1601                 uinfo->value.enumerated.item = 3;
1602         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1603         return 0;
1604 }
1605
1606 static int alc_test_pin_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1607 {
1608         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1609         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1610         unsigned int sel;
1611
1612         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1613         ucontrol->value.enumerated.item[0] = sel & 3;
1614         return 0;
1615 }
1616
1617 static int alc_test_pin_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1618 {
1619         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1620         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1621         unsigned int sel;
1622
1623         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1624         if (ucontrol->value.enumerated.item[0] != sel) {
1625                 sel = ucontrol->value.enumerated.item[0] & 3;
1626                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
1627                 return 1;
1628         }
1629         return 0;
1630 }
1631
1632 #define PIN_CTL_TEST(xname,nid) {                       \
1633                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1634                         .name = xname,                 \
1635                         .info = alc_test_pin_ctl_info, \
1636                         .get = alc_test_pin_ctl_get,   \
1637                         .put = alc_test_pin_ctl_put,   \
1638                         .private_value = nid           \
1639                         }
1640
1641 #define PIN_SRC_TEST(xname,nid) {                       \
1642                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1643                         .name = xname,                 \
1644                         .info = alc_test_pin_src_info, \
1645                         .get = alc_test_pin_src_get,   \
1646                         .put = alc_test_pin_src_put,   \
1647                         .private_value = nid           \
1648                         }
1649
1650 static snd_kcontrol_new_t alc880_test_mixer[] = {
1651         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1652         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1653         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1654         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1655         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1656         ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1657         ALC_BIND_MUTE("CLFE Playback Volume", 0x0e, 2, HDA_INPUT),
1658         ALC_BIND_MUTE("Side Playback Volume", 0x0f, 2, HDA_INPUT),
1659         PIN_CTL_TEST("Front Pin Mode", 0x14),
1660         PIN_CTL_TEST("Surround Pin Mode", 0x15),
1661         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1662         PIN_CTL_TEST("Side Pin Mode", 0x17),
1663         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1664         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1665         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1666         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1667         PIN_SRC_TEST("In-1 Pin Source", 0x18),
1668         PIN_SRC_TEST("In-2 Pin Source", 0x19),
1669         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1670         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1671         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1672         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1673         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1674         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1675         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1676         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1677         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1678         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1679         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1680         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1681         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1682         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1683         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1684         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1685         {
1686                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1687                 .name = "Input Source",
1688                 .count = 2,
1689                 .info = alc_mux_enum_info,
1690                 .get = alc_mux_enum_get,
1691                 .put = alc_mux_enum_put,
1692         },
1693         {
1694                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1695                 .name = "Channel Mode",
1696                 .info = alc880_ch_mode_info,
1697                 .get = alc880_ch_mode_get,
1698                 .put = alc880_ch_mode_put,
1699         },
1700         { } /* end */
1701 };
1702
1703 static struct hda_verb alc880_test_init_verbs[] = {
1704         /* Unmute inputs of 0x0c - 0x0f */
1705         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1706         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1707         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1708         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1709         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1710         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1711         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1712         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1713         /* Vol output for 0x0c-0x0f */
1714         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1715         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1716         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1717         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1718         /* Set output pins 0x14-0x17 */
1719         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1720         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1721         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1722         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1723         /* Unmute output pins 0x14-0x17 */
1724         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1725         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1726         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1727         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1728         /* Set input pins 0x18-0x1c */
1729         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1730         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1731         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1732         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1733         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1734         /* Mute input pins 0x18-0x1b */
1735         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1736         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1737         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1738         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1739         /* ADC set up */
1740         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1741         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1742         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1743         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1744         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1745         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1746         /* Analog input/passthru */
1747         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1748         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1749         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1750         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1751         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1752         { }
1753 };
1754 #endif
1755
1756 /*
1757  */
1758
1759 static struct hda_board_config alc880_cfg_tbl[] = {
1760         /* Back 3 jack, front 2 jack */
1761         { .modelname = "3stack", .config = ALC880_3ST },
1762         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
1763         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
1764         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
1765         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
1766         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
1767         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
1768         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
1769         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
1770         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
1771         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
1772         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
1773         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
1774         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
1775         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
1776         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
1777         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
1778         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
1779         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
1780         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
1781         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
1782         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
1783         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
1784         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
1785         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
1786         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
1787         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
1788         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
1789         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
1790         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
1791         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
1792         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
1793         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
1794
1795         /* Back 3 jack, front 2 jack (Internal add Aux-In) */
1796         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
1797         { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, 
1798
1799         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
1800         { .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
1801         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
1802
1803         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
1804         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
1805         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
1806         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
1807
1808         /* Back 5 jack, front 2 jack */
1809         { .modelname = "5stack", .config = ALC880_5ST },
1810         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
1811         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
1812         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
1813         { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
1814         { .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST },
1815
1816         /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
1817         { .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
1818         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
1819         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
1820         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
1821         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
1822         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
1823         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
1824         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
1825         { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
1826         { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
1827         { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG },
1828         { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
1829         { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG },
1830
1831         { .modelname = "w810", .config = ALC880_W810 },
1832         { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
1833
1834         { .modelname = "z71v", .config = ALC880_Z71V },
1835         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
1836
1837         { .modelname = "6statack-digout", .config = ALC880_6ST_DIG },
1838         { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
1839         { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
1840         { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
1841         { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
1842
1843         { .modelname = "asua", .config = ALC880_ASUS },
1844         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
1845         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
1846         { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
1847         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
1848         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
1849         { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
1850         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
1851         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
1852         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
1853         { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
1854
1855         { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
1856         { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },     
1857
1858         { .modelname = "F1734", .config = ALC880_F1734 },
1859         { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
1860
1861 #ifdef CONFIG_SND_DEBUG
1862         { .modelname = "test", .config = ALC880_TEST },
1863 #endif
1864
1865         {}
1866 };
1867
1868 /*
1869  * configuration template - to be copied to the spec instance
1870  */
1871 struct alc_config_preset {
1872         snd_kcontrol_new_t *mixers;
1873         unsigned int front_panel: 1;    /* optional */
1874         unsigned int gpio_payload;      /* optional */
1875         struct hda_verb *init_verbs;
1876         unsigned int num_dacs;
1877         hda_nid_t *dac_nids;
1878         hda_nid_t dig_out_nid;          /* optional */
1879         hda_nid_t hp_nid;               /* optional */
1880         unsigned int num_adc_nids;
1881         hda_nid_t *adc_nids;
1882         unsigned int num_channel_mode;
1883         const struct alc_channel_mode *channel_mode;
1884         const struct hda_input_mux *input_mux;
1885 };
1886
1887 static struct alc_config_preset alc880_presets[] = {
1888         [ALC880_3ST] = {
1889                 .mixers = alc880_base_mixer,
1890                 .init_verbs = alc880_init_verbs_three_stack,
1891                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1892                 .front_panel = 1,
1893                 .dac_nids = alc880_dac_nids,
1894                 .hp_nid = 0x03,
1895                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1896                 .adc_nids = alc880_adc_nids,
1897                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1898                 .channel_mode = alc880_threestack_modes,
1899                 .input_mux = &alc880_capture_source,
1900         },
1901         [ALC880_3ST_DIG] = {
1902                 .mixers = alc880_base_mixer,
1903                 .init_verbs = alc880_init_verbs_three_stack,
1904                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1905                 .front_panel = 1,
1906                 .dac_nids = alc880_dac_nids,
1907                 .dig_out_nid = ALC880_DIGOUT_NID,
1908                 .hp_nid = 0x03,
1909                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1910                 .adc_nids = alc880_adc_nids,
1911                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1912                 .channel_mode = alc880_threestack_modes,
1913                 .input_mux = &alc880_capture_source,
1914         },
1915         [ALC880_5ST] = {
1916                 .mixers = alc880_five_stack_mixer,
1917                 .init_verbs = alc880_init_verbs_five_stack,
1918                 .front_panel = 1,
1919                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1920                 .dac_nids = alc880_dac_nids,
1921                 .hp_nid = 0x03,
1922                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1923                 .adc_nids = alc880_adc_nids,
1924                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1925                 .channel_mode = alc880_fivestack_modes,
1926                 .input_mux = &alc880_capture_source,
1927         },
1928         [ALC880_5ST_DIG] = {
1929                 .mixers = alc880_five_stack_mixer,
1930                 .init_verbs = alc880_init_verbs_five_stack,
1931                 .front_panel = 1,
1932                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1933                 .dac_nids = alc880_dac_nids,
1934                 .dig_out_nid = ALC880_DIGOUT_NID,
1935                 .hp_nid = 0x03,
1936                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1937                 .adc_nids = alc880_adc_nids,
1938                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1939                 .channel_mode = alc880_fivestack_modes,
1940                 .input_mux = &alc880_capture_source,
1941         },
1942         [ALC880_6ST_DIG] = {
1943                 .mixers = alc880_six_stack_mixer,
1944                 .init_verbs = alc880_six_stack_init_verbs,
1945                 .front_panel = 1,
1946                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1947                 .dac_nids = alc880_6st_dac_nids,
1948                 .dig_out_nid = ALC880_DIGOUT_NID,
1949                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1950                 .adc_nids = alc880_adc_nids,
1951                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1952                 .channel_mode = alc880_sixstack_modes,
1953                 .input_mux = &alc880_6stack_capture_source,
1954         },
1955         [ALC880_W810] = {
1956                 .mixers = alc880_w810_base_mixer,
1957                 .init_verbs = alc880_w810_init_verbs,
1958                 .gpio_payload = 0x2,
1959                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1960                 .dac_nids = alc880_w810_dac_nids,
1961                 .dig_out_nid = ALC880_DIGOUT_NID,
1962                 // No dedicated headphone socket - it's shared with built-in speakers.
1963                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1964                 .adc_nids = alc880_adc_nids,
1965                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1966                 .channel_mode = alc880_w810_modes,
1967                 .input_mux = &alc880_capture_source,
1968         },
1969         [ALC880_Z71V] = {
1970                 .mixers = alc880_z71v_mixer,
1971                 .init_verbs = alc880_z71v_init_verbs,
1972                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1973                 .dac_nids = alc880_z71v_dac_nids,
1974                 .dig_out_nid = ALC880_DIGOUT_NID,
1975                 .hp_nid = 0x03,
1976                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1977                 .adc_nids = alc880_adc_nids,
1978                 .num_channel_mode = ARRAY_SIZE(alc880_z71v_modes),
1979                 .channel_mode = alc880_z71v_modes,
1980                 .input_mux = &alc880_capture_source,
1981         },
1982         [ALC880_F1734] = {
1983                 .mixers = alc880_2_jack_mixer,
1984                 .init_verbs = alc880_2_jack_init_verbs,
1985                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1986                 .dac_nids = alc880_dac_nids,
1987                 .hp_nid = 0x03,
1988                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1989                 .adc_nids = alc880_adc_nids,
1990                 .num_channel_mode = ARRAY_SIZE(alc880_z71v_modes),
1991                 .channel_mode = alc880_z71v_modes,
1992                 .input_mux = &alc880_capture_source,
1993         },
1994         [ALC880_ASUS] = {
1995                 .mixers = alc880_asus_mixer,
1996                 .init_verbs = alc880_asus_init_verbs,
1997                 .gpio_payload = 0x1,
1998                 .front_panel = 1,
1999                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2000                 .dac_nids = alc880_w810_dac_nids,
2001                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2002                 .adc_nids = alc880_adc_nids,
2003                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2004                 .channel_mode = alc880_threestack_modes,
2005                 .input_mux = &alc880_capture_source,
2006         },
2007         [ALC880_ASUS_DIG] = {
2008                 .mixers = alc880_asus_mixer,
2009                 .init_verbs = alc880_asus_init_verbs,
2010                 .gpio_payload = 0x1,
2011                 .front_panel = 1,
2012                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2013                 .dac_nids = alc880_w810_dac_nids,
2014                 .dig_out_nid = ALC880_DIGOUT_NID,
2015                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2016                 .adc_nids = alc880_adc_nids,
2017                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2018                 .channel_mode = alc880_threestack_modes,
2019                 .input_mux = &alc880_capture_source,
2020         },
2021         [ALC880_ASUS_W1V] = {
2022                 .mixers = alc880_asus_w1v_mixer,
2023                 .init_verbs = alc880_asus_init_verbs,
2024                 .gpio_payload = 0x1,
2025                 .front_panel = 1,
2026                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2027                 .dac_nids = alc880_w810_dac_nids,
2028                 .dig_out_nid = ALC880_DIGOUT_NID,
2029                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2030                 .adc_nids = alc880_adc_nids,
2031                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2032                 .channel_mode = alc880_threestack_modes,
2033                 .input_mux = &alc880_capture_source,
2034         },
2035         [ALC880_UNIWILL_DIG] = {
2036                 .mixers = alc880_asus_mixer,
2037                 .init_verbs = alc880_asus_init_verbs,
2038                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2039                 .dac_nids = alc880_dac_nids,
2040                 .dig_out_nid = ALC880_DIGOUT_NID,
2041                 .hp_nid = 0x03,
2042                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2043                 .adc_nids = alc880_adc_nids,
2044                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2045                 .channel_mode = alc880_threestack_modes,
2046                 .input_mux = &alc880_capture_source,
2047         },
2048 #ifdef CONFIG_SND_DEBUG
2049         [ALC880_TEST] = {
2050                 .mixers = alc880_test_mixer,
2051                 .init_verbs = alc880_test_init_verbs,
2052                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2053                 .dac_nids = alc880_test_dac_nids,
2054                 .dig_out_nid = ALC880_DIGOUT_NID,
2055                 .num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2056                 .adc_nids = alc880_adc_nids,
2057                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2058                 .channel_mode = alc880_test_modes,
2059                 .input_mux = &alc880_test_capture_source,
2060         },
2061 #endif
2062 };
2063
2064 static int patch_alc880(struct hda_codec *codec)
2065 {
2066         struct alc_spec *spec;
2067         int board_config;
2068         const struct alc_config_preset *preset;
2069
2070         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
2071         if (spec == NULL)
2072                 return -ENOMEM;
2073
2074         init_MUTEX(&spec->bind_mutex);
2075         codec->spec = spec;
2076
2077         board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
2078         if (board_config < 0 || board_config >= ALC880_MODEL_LAST) {
2079                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC880\n");
2080                 board_config = ALC880_3ST;
2081         }
2082         preset = &alc880_presets[board_config];
2083
2084         spec->mixers[spec->num_mixers] = preset->mixers;
2085         snd_assert(spec->mixers[0], kfree(spec);return -EINVAL);
2086         spec->num_mixers++;
2087
2088         /* some MBs need GPIO setup */
2089         if (preset->gpio_payload) {
2090                 /* Enable mask and set output */
2091                 snd_hda_codec_write(codec, codec->afg, 0,
2092                                     AC_VERB_SET_GPIO_MASK, preset->gpio_payload);
2093                 snd_hda_codec_write(codec, codec->afg, 0,
2094                                     AC_VERB_SET_GPIO_DIRECTION, preset->gpio_payload);
2095                 snd_hda_codec_write(codec, codec->afg, 0,
2096                                     AC_VERB_SET_GPIO_DATA, preset->gpio_payload);
2097         }
2098
2099         spec->front_panel = preset->front_panel;
2100         spec->init_verbs = preset->init_verbs;
2101         spec->channel_mode = preset->channel_mode;
2102         spec->num_channel_mode = preset->num_channel_mode;
2103
2104         spec->stream_name_analog = "ALC880 Analog";
2105         spec->stream_analog_playback = &alc880_pcm_analog_playback;
2106         spec->stream_analog_capture = &alc880_pcm_analog_capture;
2107
2108         spec->stream_name_digital = "ALC880 Digital";
2109         spec->stream_digital_playback = &alc880_pcm_digital_playback;
2110         spec->stream_digital_capture = &alc880_pcm_digital_capture;
2111
2112         spec->multiout.max_channels = spec->channel_mode[0].channels;
2113
2114         spec->multiout.num_dacs = preset->num_dacs;
2115         spec->multiout.dac_nids = preset->adc_nids;
2116         spec->multiout.dig_out_nid = preset->dig_out_nid;
2117         spec->multiout.hp_nid = preset->hp_nid;
2118
2119         spec->input_mux = preset->input_mux;
2120         spec->num_adc_nids = preset->num_adc_nids;
2121         spec->adc_nids = preset->adc_nids;
2122
2123         codec->patch_ops = alc_patch_ops;
2124
2125         return 0;
2126 }
2127
2128 /*
2129  * ALC260 support
2130  */
2131
2132 /*
2133  * This is just place-holder, so there's something for alc_build_pcms to look
2134  * at when it calculates the maximum number of channels. ALC260 has no mixer
2135  * element which allows changing the channel mode, so the verb list is
2136  * never used.
2137  */
2138 static struct alc_channel_mode alc260_modes[1] = {
2139         { 2, NULL },
2140 };
2141
2142 snd_kcontrol_new_t alc260_base_mixer[] = {
2143         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2144         ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
2145         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2146         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2147         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
2148         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
2149         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
2150         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
2151         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
2152         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
2153         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
2154         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
2155         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
2156         ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
2157         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2158         ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
2159         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
2160         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
2161         {
2162                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2163                 .name = "Capture Source",
2164                 .info = alc_mux_enum_info,
2165                 .get = alc_mux_enum_get,
2166                 .put = alc_mux_enum_put,
2167         },
2168         { } /* end */
2169 };
2170
2171 snd_kcontrol_new_t alc260_hp_mixer[] = {
2172         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2173         ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
2174         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2175         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2176         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
2177         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
2178         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
2179         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
2180         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
2181         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
2182         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
2183         ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
2184         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2185         ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
2186         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
2187         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
2188         {
2189                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2190                 .name = "Capture Source",
2191                 .info = alc_mux_enum_info,
2192                 .get = alc_mux_enum_get,
2193                 .put = alc_mux_enum_put,
2194         },
2195         { } /* end */
2196 };
2197
2198 static struct hda_verb alc260_init_verbs[] = {
2199         /* Line In pin widget for input */
2200         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2201         /* CD pin widget for input */
2202         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2203         /* Mic1 (rear panel) pin widget for input and vref at 80% */
2204         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2205         /* Mic2 (front panel) pin widget for input and vref at 80% */
2206         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2207         /* LINE-2 is used for line-out in rear */
2208         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2209         /* select line-out */
2210         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2211         /* LINE-OUT pin */
2212         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2213         /* enable HP */
2214         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2215         /* enable Mono */
2216         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2217         /* mute capture amp left and right */
2218         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2219         /* set connection select to line in (default select for this ADC) */
2220         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
2221         /* mute capture amp left and right */
2222         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2223         /* set connection select to line in (default select for this ADC) */
2224         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
2225         /* set vol=0 Line-Out mixer amp left and right */
2226         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2227         /* unmute pin widget amp left and right (no gain on this amp) */
2228         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229         /* set vol=0 HP mixer amp left and right */
2230         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2231         /* unmute pin widget amp left and right (no gain on this amp) */
2232         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2233         /* set vol=0 Mono mixer amp left and right */
2234         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2235         /* unmute pin widget amp left and right (no gain on this amp) */
2236         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2237         /* unmute LINE-2 out pin */
2238         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2239         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
2240         /* mute CD */
2241         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2242         /* mute Line In */
2243         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2244         /* mute Mic */
2245         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2246         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
2247         /* mute Front out path */
2248         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2249         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2250         /* mute Headphone out path */
2251         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2252         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2253         /* mute Mono out path */
2254         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2255         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2256         { }
2257 };
2258
2259 static struct hda_pcm_stream alc260_pcm_analog_playback = {
2260         .substreams = 1,
2261         .channels_min = 2,
2262         .channels_max = 2,
2263         .nid = 0x2,
2264 };
2265
2266 static struct hda_pcm_stream alc260_pcm_analog_capture = {
2267         .substreams = 1,
2268         .channels_min = 2,
2269         .channels_max = 2,
2270         .nid = 0x4,
2271 };
2272
2273 static struct hda_board_config alc260_cfg_tbl[] = {
2274         { .modelname = "hp", .config = ALC260_HP },
2275         { .pci_subvendor = 0x103c, .config = ALC260_HP },
2276         {}
2277 };
2278
2279 static int patch_alc260(struct hda_codec *codec)
2280 {
2281         struct alc_spec *spec;
2282         int board_config;
2283
2284         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
2285         if (spec == NULL)
2286                 return -ENOMEM;
2287
2288         init_MUTEX(&spec->bind_mutex);
2289         codec->spec = spec;
2290
2291         board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
2292         if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
2293                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n");
2294                 board_config = ALC260_BASIC;
2295         }
2296
2297         switch (board_config) {
2298         case ALC260_HP:
2299                 spec->mixers[spec->num_mixers] = alc260_base_mixer;
2300                 spec->num_mixers++;
2301                 break;
2302         default:
2303                 spec->mixers[spec->num_mixers] = alc260_base_mixer;
2304                 spec->num_mixers++;
2305                 break;
2306         }
2307
2308         spec->init_verbs = alc260_init_verbs;
2309         spec->channel_mode = alc260_modes;
2310         spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
2311
2312         spec->stream_name_analog = "ALC260 Analog";
2313         spec->stream_analog_playback = &alc260_pcm_analog_playback;
2314         spec->stream_analog_capture = &alc260_pcm_analog_capture;
2315
2316         spec->multiout.max_channels = spec->channel_mode[0].channels;
2317         spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
2318         spec->multiout.dac_nids = alc260_dac_nids;
2319
2320         spec->input_mux = &alc260_capture_source;
2321         switch (board_config) {
2322         case ALC260_HP:
2323                 spec->stream_analog_capture->nid = 5;
2324                 spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids);
2325                 spec->adc_nids = alc260_hp_adc_nids;
2326                 break;
2327         default:
2328                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
2329                 spec->adc_nids = alc260_adc_nids;
2330                 break;
2331         }
2332
2333         codec->patch_ops = alc_patch_ops;
2334
2335         return 0;
2336 }
2337
2338 /*
2339  * ALC882 support
2340  *
2341  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
2342  * configuration.  Each pin widget can choose any input DACs and a mixer.
2343  * Each ADC is connected from a mixer of all inputs.  This makes possible
2344  * 6-channel independent captures.
2345  *
2346  * In addition, an independent DAC for the multi-playback (not used in this
2347  * driver yet).
2348  */
2349
2350 static struct alc_channel_mode alc882_ch_modes[1] = {
2351         { 8, NULL }
2352 };
2353
2354 static hda_nid_t alc882_dac_nids[4] = {
2355         /* front, rear, clfe, rear_surr */
2356         0x02, 0x03, 0x04, 0x05
2357 };
2358
2359 static hda_nid_t alc882_adc_nids[3] = {
2360         /* ADC0-2 */
2361         0x07, 0x08, 0x09,
2362 };
2363
2364 /* input MUX */
2365 /* FIXME: should be a matrix-type input source selection */
2366
2367 static struct hda_input_mux alc882_capture_source = {
2368         .num_items = 4,
2369         .items = {
2370                 { "Mic", 0x0 },
2371                 { "Front Mic", 0x1 },
2372                 { "Line", 0x2 },
2373                 { "CD", 0x4 },
2374         },
2375 };
2376
2377 #define alc882_mux_enum_info alc_mux_enum_info
2378 #define alc882_mux_enum_get alc_mux_enum_get
2379
2380 static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2381 {
2382         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2383         struct alc_spec *spec = codec->spec;
2384         const struct hda_input_mux *imux = spec->input_mux;
2385         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2386         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
2387         hda_nid_t nid = capture_mixers[adc_idx];
2388         unsigned int *cur_val = &spec->cur_mux[adc_idx];
2389         unsigned int i, idx;
2390
2391         idx = ucontrol->value.enumerated.item[0];
2392         if (idx >= imux->num_items)
2393                 idx = imux->num_items - 1;
2394         if (*cur_val == idx && ! codec->in_resume)
2395                 return 0;
2396         for (i = 0; i < imux->num_items; i++) {
2397                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
2398                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2399                                     v | (imux->items[i].index << 8));
2400         }
2401         *cur_val = idx;
2402         return 1;
2403 }
2404
2405 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
2406  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
2407  */
2408 static snd_kcontrol_new_t alc882_base_mixer[] = {
2409         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2410         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2411         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2412         ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2413         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2414         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2415         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2416         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_OUTPUT),
2417         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2418         ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2419         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2420         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2421         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2422         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2423         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2424         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2425         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2426         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2427         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2428         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
2429         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
2430         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
2431         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
2432         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
2433         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
2434         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
2435         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
2436         {
2437                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2438                 /* .name = "Capture Source", */
2439                 .name = "Input Source",
2440                 .count = 3,
2441                 .info = alc882_mux_enum_info,
2442                 .get = alc882_mux_enum_get,
2443                 .put = alc882_mux_enum_put,
2444         },
2445         { } /* end */
2446 };
2447
2448 static struct hda_verb alc882_init_verbs[] = {
2449         /* Front mixer: unmute input/output amp left and right (volume = 0) */
2450         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2451         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2452         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2453         /* Rear mixer */
2454         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2455         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2456         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2457         /* CLFE mixer */
2458         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2459         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2460         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2461         /* Side mixer */
2462         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2463         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2464         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2465
2466         /* Front Pin: to output mode */
2467         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2468         /* Front Pin: mute amp left and right (no volume) */
2469         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2470         /* select Front mixer (0x0c, index 0) */
2471         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2472         /* Rear Pin */
2473         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2474         /* Rear Pin: mute amp left and right (no volume) */
2475         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2476         /* select Rear mixer (0x0d, index 1) */
2477         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
2478         /* CLFE Pin */
2479         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2480         /* CLFE Pin: mute amp left and right (no volume) */
2481         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2482         /* select CLFE mixer (0x0e, index 2) */
2483         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2484         /* Side Pin */
2485         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2486         /* Side Pin: mute amp left and right (no volume) */
2487         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2488         /* select Side mixer (0x0f, index 3) */
2489         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2490         /* Headphone Pin */
2491         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2492         /* Headphone Pin: mute amp left and right (no volume) */
2493         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2494         /* select Front mixer (0x0c, index 0) */
2495         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2496         /* Mic (rear) pin widget for input and vref at 80% */
2497         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2498         /* Front Mic pin widget for input and vref at 80% */
2499         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2500         /* Line In pin widget for input */
2501         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2502         /* CD pin widget for input */
2503         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2504
2505         /* FIXME: use matrix-type input source selection */
2506         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
2507         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
2508         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2509         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2510         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2511         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2512         /* Input mixer2 */
2513         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2514         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2515         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2516         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2517         /* Input mixer3 */
2518         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2519         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2520         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2521         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2522         /* ADC1: mute amp left and right */
2523         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2524         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2525         /* ADC2: mute amp left and right */
2526         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2527         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2528         /* ADC3: mute amp left and right */
2529         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2530         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2531
2532         { }
2533 };
2534
2535 static int patch_alc882(struct hda_codec *codec)
2536 {
2537         struct alc_spec *spec;
2538
2539         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
2540         if (spec == NULL)
2541                 return -ENOMEM;
2542
2543         init_MUTEX(&spec->bind_mutex);
2544         codec->spec = spec;
2545
2546         spec->mixers[spec->num_mixers] = alc882_base_mixer;
2547         spec->num_mixers++;
2548
2549         spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
2550         spec->dig_in_nid = ALC880_DIGIN_NID;
2551         spec->front_panel = 1;
2552         spec->init_verbs = alc882_init_verbs;
2553         spec->channel_mode = alc882_ch_modes;
2554         spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes);
2555
2556         spec->stream_name_analog = "ALC882 Analog";
2557         spec->stream_analog_playback = &alc880_pcm_analog_playback;
2558         spec->stream_analog_capture = &alc880_pcm_analog_capture;
2559
2560         spec->stream_name_digital = "ALC882 Digital";
2561         spec->stream_digital_playback = &alc880_pcm_digital_playback;
2562         spec->stream_digital_capture = &alc880_pcm_digital_capture;
2563
2564         spec->multiout.max_channels = spec->channel_mode[0].channels;
2565         spec->multiout.num_dacs = ARRAY_SIZE(alc882_dac_nids);
2566         spec->multiout.dac_nids = alc882_dac_nids;
2567
2568         spec->input_mux = &alc882_capture_source;
2569         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
2570         spec->adc_nids = alc882_adc_nids;
2571
2572         codec->patch_ops = alc_patch_ops;
2573
2574         return 0;
2575 }
2576
2577 /*
2578  * patch entries
2579  */
2580 struct hda_codec_preset snd_hda_preset_realtek[] = {
2581         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
2582         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
2583         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
2584         {} /* terminator */
2585 };