]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/pci/hda/patch_realtek.c
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[linux-2.6-omap-h63xx.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_MINIMAL,
37         ALC880_3ST,
38         ALC880_3ST_DIG,
39         ALC880_5ST,
40         ALC880_5ST_DIG,
41         ALC880_W810,
42         ALC880_Z71V,
43         ALC880_TEST,
44 };
45
46 struct alc_spec {
47         /* codec parameterization */
48         unsigned int front_panel: 1;
49
50         snd_kcontrol_new_t* mixers[2];
51         unsigned int num_mixers;
52
53         struct hda_verb *init_verbs;
54
55         char* stream_name_analog;
56         struct hda_pcm_stream *stream_analog_playback;
57         struct hda_pcm_stream *stream_analog_capture;
58
59         char* stream_name_digital;
60         struct hda_pcm_stream *stream_digital_playback;
61         struct hda_pcm_stream *stream_digital_capture;
62
63         /* playback */
64         struct hda_multi_out multiout;
65
66         /* capture */
67         unsigned int num_adc_nids;
68         hda_nid_t *adc_nids;
69         hda_nid_t dig_in_nid;
70
71         /* capture source */
72         const struct hda_input_mux *input_mux;
73         unsigned int cur_mux[3];
74
75         /* channel model */
76         const struct alc_channel_mode *channel_mode;
77         int num_channel_mode;
78
79         /* PCM information */
80         struct hda_pcm pcm_rec[2];
81 };
82
83 /* DAC/ADC assignment */
84
85 static hda_nid_t alc880_dac_nids[4] = {
86         /* front, rear, clfe, rear_surr */
87         0x02, 0x05, 0x04, 0x03
88 };
89
90 static hda_nid_t alc880_w810_dac_nids[3] = {
91         /* front, rear/surround, clfe */
92         0x02, 0x03, 0x04
93 };
94
95 static hda_nid_t alc880_z71v_dac_nids[1] = {
96         /* front only? */
97         0x02
98 };
99
100 #if 0
101 /* The datasheet says the node 0x07 is connected from inputs,
102  * but it shows zero connection in the real implementation.
103  */
104 static hda_nid_t alc880_adc_nids[3] = {
105         /* ADC0-2 */
106         0x07, 0x08, 0x09,
107 };
108 #else
109 static hda_nid_t alc880_adc_nids[2] = {
110         /* ADC1-2 */
111         0x08, 0x09,
112 };
113 #endif
114
115 #define ALC880_DIGOUT_NID       0x06
116 #define ALC880_DIGIN_NID        0x0a
117
118 static hda_nid_t alc260_dac_nids[1] = {
119         /* front */
120         0x02,
121 };
122
123 static hda_nid_t alc260_adc_nids[2] = {
124         /* ADC0-1 */
125         0x04, 0x05,
126 };
127
128 #define ALC260_DIGOUT_NID       0x03
129 #define ALC260_DIGIN_NID        0x06
130
131 static struct hda_input_mux alc880_capture_source = {
132         .num_items = 4,
133         .items = {
134                 { "Mic", 0x0 },
135                 { "Front Mic", 0x3 },
136                 { "Line", 0x2 },
137                 { "CD", 0x4 },
138         },
139 };
140
141 static struct hda_input_mux alc260_capture_source = {
142         .num_items = 4,
143         .items = {
144                 { "Mic", 0x0 },
145                 { "Front Mic", 0x1 },
146                 { "Line", 0x2 },
147                 { "CD", 0x4 },
148         },
149 };
150
151 /*
152  * input MUX handling
153  */
154 static int alc_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
155 {
156         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
157         struct alc_spec *spec = codec->spec;
158         return snd_hda_input_mux_info(spec->input_mux, uinfo);
159 }
160
161 static int alc_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
162 {
163         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
164         struct alc_spec *spec = codec->spec;
165         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
166
167         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
168         return 0;
169 }
170
171 static int alc_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
172 {
173         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
174         struct alc_spec *spec = codec->spec;
175         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
176         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
177                                      spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
178 }
179
180 /*
181  * channel mode setting
182  */
183 struct alc_channel_mode {
184         int channels;
185         const struct hda_verb *sequence;
186 };
187
188
189 /*
190  * channel source setting (2/6 channel selection for 3-stack)
191  */
192
193 /*
194  * set the path ways for 2 channel output
195  * need to set the codec line out and mic 1 pin widgets to inputs
196  */
197 static struct hda_verb alc880_threestack_ch2_init[] = {
198         /* set pin widget 1Ah (line in) for input */
199         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
200         /* set pin widget 18h (mic1) for input, for mic also enable the vref */
201         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
202         /* mute the output for Line In PW */
203         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
204         /* mute for Mic1 PW */
205         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
206         { } /* end */
207 };
208
209 /*
210  * 6ch mode
211  * need to set the codec line out and mic 1 pin widgets to outputs
212  */
213 static struct hda_verb alc880_threestack_ch6_init[] = {
214         /* set pin widget 1Ah (line in) for output */
215         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
216         /* set pin widget 18h (mic1) for output */
217         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
218         /* unmute the output for Line In PW */
219         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
220         /* unmute for Mic1 PW */
221         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
222         /* for rear channel output using Line In 1
223          * set select widget connection (nid = 0x12) - to summer node
224          * for rear NID = 0x0f...offset 3 in connection list
225          */
226         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x3 },
227         /* for Mic1 - retask for center/lfe */
228         /* set select widget connection (nid = 0x10) - to summer node for
229          * front CLFE NID = 0x0e...offset 2 in connection list
230          */
231         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x2 },
232         { } /* end */
233 };
234
235 static struct alc_channel_mode alc880_threestack_modes[2] = {
236         { 2, alc880_threestack_ch2_init },
237         { 6, alc880_threestack_ch6_init },
238 };
239
240
241 /*
242  * channel source setting (6/8 channel selection for 5-stack)
243  */
244
245 /* set the path ways for 6 channel output
246  * need to set the codec line out and mic 1 pin widgets to inputs
247  */
248 static struct hda_verb alc880_fivestack_ch6_init[] = {
249         /* set pin widget 1Ah (line in) for input */
250         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
251         /* mute the output for Line In PW */
252         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
253         { } /* end */
254 };
255
256 /* need to set the codec line out and mic 1 pin widgets to outputs */
257 static struct hda_verb alc880_fivestack_ch8_init[] = {
258         /* set pin widget 1Ah (line in) for output */
259         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
260         /* unmute the output for Line In PW */
261         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
262         /* output for surround channel output using Line In 1 */
263         /* set select widget connection (nid = 0x12) - to summer node
264          * for surr_rear NID = 0x0d...offset 1 in connection list
265          */
266         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x1 },
267         { } /* end */
268 };
269
270 static struct alc_channel_mode alc880_fivestack_modes[2] = {
271         { 6, alc880_fivestack_ch6_init },
272         { 8, alc880_fivestack_ch8_init },
273 };
274
275 /*
276  * channel source setting for W810 system
277  *
278  * W810 has rear IO for:
279  * Front (DAC 02)
280  * Surround (DAC 03)
281  * Center/LFE (DAC 04)
282  * Digital out (06)
283  *
284  * The system also has a pair of internal speakers, and a headphone jack.
285  * These are both connected to Line2 on the codec, hence to DAC 02.
286  * 
287  * There is a variable resistor to control the speaker or headphone
288  * volume. This is a hardware-only device without a software API.
289  *
290  * Plugging headphones in will disable the internal speakers. This is
291  * implemented in hardware, not via the driver using jack sense. In
292  * a similar fashion, plugging into the rear socket marked "front" will
293  * disable both the speakers and headphones.
294  *
295  * For input, there's a microphone jack, and an "audio in" jack.
296  * These may not do anything useful with this driver yet, because I
297  * haven't setup any initialization verbs for these yet...
298  */
299
300 static struct alc_channel_mode alc880_w810_modes[1] = {
301         { 6, NULL }
302 };
303
304 static struct alc_channel_mode alc880_z71v_modes[1] = {
305         { 2, NULL }
306 };
307
308 /*
309  */
310 static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
311 {
312         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
313         struct alc_spec *spec = codec->spec;
314         int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
315
316         snd_assert(spec->channel_mode, return -ENXIO);
317         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
318         uinfo->count = 1;
319         uinfo->value.enumerated.items = items;
320         if (uinfo->value.enumerated.item >= items)
321                 uinfo->value.enumerated.item = items - 1;
322         sprintf(uinfo->value.enumerated.name, "%dch",
323                 spec->channel_mode[uinfo->value.enumerated.item].channels);
324         return 0;
325 }
326
327 static int alc880_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
328 {
329         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
330         struct alc_spec *spec = codec->spec;
331         int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
332         int i;
333
334         snd_assert(spec->channel_mode, return -ENXIO);
335         for (i = 0; i < items; i++) {
336                 if (spec->multiout.max_channels == spec->channel_mode[i].channels) {
337                         ucontrol->value.enumerated.item[0] = i;
338                         break;
339                 }
340         }
341         return 0;
342 }
343
344 static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
345 {
346         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347         struct alc_spec *spec = codec->spec;
348         int mode;
349
350         snd_assert(spec->channel_mode, return -ENXIO);
351         mode = ucontrol->value.enumerated.item[0] ? 1 : 0;
352         if (spec->multiout.max_channels == spec->channel_mode[mode].channels &&
353             ! codec->in_resume)
354                 return 0;
355
356         /* change the current channel setting */
357         spec->multiout.max_channels = spec->channel_mode[mode].channels;
358         if (spec->channel_mode[mode].sequence)
359                 snd_hda_sequence_write(codec, spec->channel_mode[mode].sequence);
360
361         return 1;
362 }
363
364
365 /*
366  */
367
368 /* 3-stack mode
369  * Pin assignment: Front=0x14, Line-In/Rear=0x1a, Mic/CLFE=0x18, F-Mic=0x1b
370  *                 HP=0x19
371  */
372 static snd_kcontrol_new_t alc880_base_mixer[] = {
373         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
374         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
375         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
376         HDA_CODEC_MUTE("Surround Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
377         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
378         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
379         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x18, 1, 0x0, HDA_OUTPUT),
380         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x18, 2, 0x0, HDA_OUTPUT),
381         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
382         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
383         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
384         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
385         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
386         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
387         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
388         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
389         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
390         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
391         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
392         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
393         /* We don't use NID 0x07 - see above */
394         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
395         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
396         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
397         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
398         {
399                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
400                 /* The multiple "Capture Source" controls confuse alsamixer
401                  * So call somewhat different..
402                  * FIXME: the controls appear in the "playback" view!
403                  */
404                 /* .name = "Capture Source", */
405                 .name = "Input Source",
406                 .count = 2,
407                 .info = alc_mux_enum_info,
408                 .get = alc_mux_enum_get,
409                 .put = alc_mux_enum_put,
410         },
411         {
412                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
413                 .name = "Channel Mode",
414                 .info = alc880_ch_mode_info,
415                 .get = alc880_ch_mode_get,
416                 .put = alc880_ch_mode_put,
417         },
418         { } /* end */
419 };
420
421 /* 5-stack mode
422  * Pin assignment: Front=0x14, Rear=0x17, CLFE=0x16
423  *                 Line-In/Side=0x1a, Mic=0x18, F-Mic=0x1b, HP=0x19
424  */
425 static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
426         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
427         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
428         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
429         HDA_CODEC_MUTE("Surround Playback Switch", 0x17, 0x0, HDA_OUTPUT),
430         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
431         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
432         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
433         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
434         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
435         HDA_CODEC_MUTE("Side Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
436         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
437         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
438         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
439         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
440         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
441         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
442         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
443         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
444         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
445         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
446         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
447         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
448         /* We don't use NID 0x07 - see above */
449         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
450         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
451         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
452         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
453         {
454                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
455                 /* The multiple "Capture Source" controls confuse alsamixer
456                  * So call somewhat different..
457                  * FIXME: the controls appear in the "playback" view!
458                  */
459                 /* .name = "Capture Source", */
460                 .name = "Input Source",
461                 .count = 2,
462                 .info = alc_mux_enum_info,
463                 .get = alc_mux_enum_get,
464                 .put = alc_mux_enum_put,
465         },
466         {
467                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
468                 .name = "Channel Mode",
469                 .info = alc880_ch_mode_info,
470                 .get = alc880_ch_mode_get,
471                 .put = alc880_ch_mode_put,
472         },
473         { } /* end */
474 };
475
476 static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
477         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
478         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
479         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
480         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
481         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
482         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
483         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
484         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
485         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
486         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
487         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
488         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
489         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
490         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
491         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
492         {
493                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
494                 /* The multiple "Capture Source" controls confuse alsamixer
495                  * So call somewhat different..
496                  * FIXME: the controls appear in the "playback" view!
497                  */
498                 /* .name = "Capture Source", */
499                 .name = "Input Source",
500                 .count = 3,
501                 .info = alc_mux_enum_info,
502                 .get = alc_mux_enum_get,
503                 .put = alc_mux_enum_put,
504         },
505         { } /* end */
506 };
507
508 static snd_kcontrol_new_t alc880_z71v_mixer[] = {
509         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
510         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
511         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
512         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
513         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
514         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
515         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
516         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
517         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
518         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
519         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
520         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
521         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
522         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
523         {
524                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
525                 /* The multiple "Capture Source" controls confuse alsamixer
526                  * So call somewhat different..
527                  * FIXME: the controls appear in the "playback" view!
528                  */
529                 /* .name = "Capture Source", */
530                 .name = "Input Source",
531                 .count = 3,
532                 .info = alc_mux_enum_info,
533                 .get = alc_mux_enum_get,
534                 .put = alc_mux_enum_put,
535         },
536         { } /* end */
537 };
538
539 /*
540  */
541 static int alc_build_controls(struct hda_codec *codec)
542 {
543         struct alc_spec *spec = codec->spec;
544         int err;
545         int i;
546
547         for (i = 0; i < spec->num_mixers; i++) {
548                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
549                 if (err < 0)
550                         return err;
551         }
552
553         if (spec->multiout.dig_out_nid) {
554                 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
555                 if (err < 0)
556                         return err;
557         }
558         if (spec->dig_in_nid) {
559                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
560                 if (err < 0)
561                         return err;
562         }
563         return 0;
564 }
565
566 /*
567  * initialize the codec volumes, etc
568  */
569
570 static struct hda_verb alc880_init_verbs_three_stack[] = {
571         /* Line In pin widget for input */
572         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
573         /* CD pin widget for input */
574         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
575         /* Mic1 (rear panel) pin widget for input and vref at 80% */
576         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
577         /* Mic2 (front panel) pin widget for input and vref at 80% */
578         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
579         /* unmute amp left and right */
580         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
581         /* set connection select to mic in */
582         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
583         /* unmute amp left and right */
584         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
585         /* set connection select to mic in */
586         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
587         /* unmute amp left and right */
588         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
589         /* set connection select to mic in */
590         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
591         /* unmute front mixer amp left (volume = 0) */
592         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
593         /* mute pin widget amp left and right (no gain on this amp) */
594         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
595         /* unmute rear mixer amp left and right (volume = 0) */
596         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
597         /* mute pin widget amp left and right (no gain on this amp) */
598         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
599         /* unmute rear mixer amp left and right (volume = 0) */
600         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
601         /* mute pin widget amp left and right (no gain on this amp) */
602         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
603
604         /* using rear surround as the path for headphone output */
605         /* unmute rear surround mixer amp left and right (volume = 0) */
606         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
607         /* PASD 3 stack boards use the Mic 2 as the headphone output */
608         /* need to program the selector associated with the Mic 2 pin widget to
609          * surround path (index 0x01) for headphone output */
610         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
611         /* mute pin widget amp left and right (no gain on this amp) */
612         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
613         /* need to retask the Mic 2 pin widget to output */
614         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
615
616         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer widget(nid=0x0B)
617          * to support the input path of analog loopback
618          * Note: PASD motherboards uses the Line In 2 as the input for front panel
619          * mic (mic 2)
620          */
621         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
622         /* unmute CD */
623         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
624         /* unmute Line In */
625         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
626         /* unmute Mic 1 */
627         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
628         /* unmute Line In 2 (for PASD boards Mic 2) */
629         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
630
631         /* Unmute input amps for the line out paths to support the output path of
632          * analog loopback
633          * the mixers on the output path has 2 inputs, one from the DAC and one
634          * from the mixer
635          */
636         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
637         /* Unmute Front out path */
638         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
639         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
640         /* Unmute Surround (used as HP) out path */
641         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
642         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
643         /* Unmute C/LFE out path */
644         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
645         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, /* mute */
646         /* Unmute rear Surround out path */
647         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
648         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
649
650         { }
651 };
652
653 static struct hda_verb alc880_init_verbs_five_stack[] = {
654         /* Line In pin widget for input */
655         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
656         /* CD pin widget for input */
657         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
658         /* Mic1 (rear panel) pin widget for input and vref at 80% */
659         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
660         /* Mic2 (front panel) pin widget for input and vref at 80% */
661         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
662         /* unmute amp left and right */
663         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
664         /* set connection select to mic in */
665         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
666         /* unmute amp left and right */
667         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
668         /* set connection select to mic in */
669         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
670         /* unmute amp left and right */
671         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
672         /* set connection select to mic in */
673         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
674         /* unmute front mixer amp left and right (volume = 0) */
675         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
676         /* mute pin widget amp left and right (no gain on this amp) */
677         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
678         /* five rear and clfe */
679         /* unmute rear mixer amp left and right (volume = 0)  */
680         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
681         /* mute pin widget amp left and right (no gain on this amp) */
682         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
683         /* unmute clfe mixer amp left and right (volume = 0) */
684         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
685         /* mute pin widget amp left and right (no gain on this amp) */
686         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
687
688         /* using rear surround as the path for headphone output */
689         /* unmute rear surround mixer amp left and right (volume = 0) */
690         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
691         /* PASD 3 stack boards use the Mic 2 as the headphone output */
692         /* need to program the selector associated with the Mic 2 pin widget to
693          * surround path (index 0x01) for headphone output
694          */
695         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
696         /* mute pin widget amp left and right (no gain on this amp) */
697         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
698         /* need to retask the Mic 2 pin widget to output */
699         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
700
701         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
702          * widget(nid=0x0B) to support the input path of analog loopback
703          */
704         /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
705         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
706         /* unmute CD */
707         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
708         /* unmute Line In */
709         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
710         /* unmute Mic 1 */
711         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
712         /* unmute Line In 2 (for PASD boards Mic 2) */
713         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
714
715         /* Unmute input amps for the line out paths to support the output path of
716          * analog loopback
717          * the mixers on the output path has 2 inputs, one from the DAC and
718          * one from the mixer
719          */
720         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
721         /* Unmute Front out path */
722         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
723         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
724         /* Unmute Surround (used as HP) out path */
725         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
726         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
727         /* Unmute C/LFE out path */
728         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
729         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, /* mute */
730         /* Unmute rear Surround out path */
731         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
732         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
733
734         { }
735 };
736
737 static struct hda_verb alc880_w810_init_verbs[] = {
738         /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
739         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
740
741         /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
742         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
743
744         /* front channel selector/amp: output 0: unmuted, max volume */
745         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
746
747         /* front out pin: muted, (no volume selection)  */
748         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
749
750         /* front out pin: NOT headphone enable, out enable, vref disabled */
751         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
752
753
754         /* surround channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
755         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
756
757         /* surround channel selector/amp: input 1: capture mix: muted, (no volume selection) */
758         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
759
760         /* surround channel selector/amp: output 0: unmuted, max volume */
761         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
762
763         /* surround out pin: muted, (no volume selection)  */
764         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
765
766         /* surround out pin: NOT headphone enable, out enable, vref disabled */
767         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
768
769
770         /* c/lfe channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
771         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
772
773         /* c/lfe channel selector/amp: input 1: capture mix: muted, (no volume selection) */
774         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
775
776         /* c/lfe channel selector/amp: output 0: unmuted, max volume */
777         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
778
779         /* c/lfe out pin: muted, (no volume selection)  */
780         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
781
782         /* c/lfe out pin: NOT headphone enable, out enable, vref disabled */
783         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
784
785
786         /* hphone/speaker input selector: front DAC */
787         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
788
789         /* hphone/speaker out pin: muted, (no volume selection)  */
790         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
791
792         /* hphone/speaker out pin: NOT headphone enable, out enable, vref disabled */
793         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
794
795
796         { }
797 };
798
799 static struct hda_verb alc880_z71v_init_verbs[] = {
800         /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
801         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
802         /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
803         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
804         /* front channel selector/amp: output 0: unmuted, max volume */
805         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
806         /* front out pin: muted, (no volume selection)  */
807         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
808         /* front out pin: NOT headphone enable, out enable, vref disabled */
809         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
810         /* headphone channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
811         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
812         /* headphone channel selector/amp: input 1: capture mix: muted, (no volume selection) */
813         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
814         /* headphone channel selector/amp: output 0: unmuted, max volume */
815         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
816         /* headphone out pin: muted, (no volume selection)  */
817         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
818         /* headpohne out pin: headphone enable, out enable, vref disabled */
819         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
820
821         /* Line In pin widget for input */
822         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
823         /* CD pin widget for input */
824         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
825         /* Mic1 (rear panel) pin widget for input and vref at 80% */
826         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
827         /* Mic2 (front panel) pin widget for input and vref at 80% */
828         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
829         /* unmute amp left and right */
830         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
831         /* set connection select to mic in */
832         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
833         /* unmute amp left and right */
834         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
835         /* set connection select to mic in */
836         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
837         /* unmute amp left and right */
838         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
839         /* set connection select to mic in */
840         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
841         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
842          * widget(nid=0x0B) to support the input path of analog loopback
843          */
844         /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
845         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
846         /* unmute CD */
847         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
848         /* unmute Line In */
849         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
850         /* unmute Mic 1 */
851         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
852         /* unmute Line In 2 (for PASD boards Mic 2) */
853         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
854
855         { }
856 };
857
858 static int alc_init(struct hda_codec *codec)
859 {
860         struct alc_spec *spec = codec->spec;
861         snd_hda_sequence_write(codec, spec->init_verbs);
862         return 0;
863 }
864
865 #ifdef CONFIG_PM
866 /*
867  * resume
868  */
869 static int alc_resume(struct hda_codec *codec)
870 {
871         struct alc_spec *spec = codec->spec;
872         int i;
873
874         alc_init(codec);
875         for (i = 0; i < spec->num_mixers; i++) {
876                 snd_hda_resume_ctls(codec, spec->mixers[i]);
877         }
878         if (spec->multiout.dig_out_nid)
879                 snd_hda_resume_spdif_out(codec);
880         if (spec->dig_in_nid)
881                 snd_hda_resume_spdif_in(codec);
882
883         return 0;
884 }
885 #endif
886
887 /*
888  * Analog playback callbacks
889  */
890 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
891                                     struct hda_codec *codec,
892                                     snd_pcm_substream_t *substream)
893 {
894         struct alc_spec *spec = codec->spec;
895         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
896 }
897
898 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
899                                        struct hda_codec *codec,
900                                        unsigned int stream_tag,
901                                        unsigned int format,
902                                        snd_pcm_substream_t *substream)
903 {
904         struct alc_spec *spec = codec->spec;
905         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
906                                                 format, substream);
907 }
908
909 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
910                                        struct hda_codec *codec,
911                                        snd_pcm_substream_t *substream)
912 {
913         struct alc_spec *spec = codec->spec;
914         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
915 }
916
917 /*
918  * Digital out
919  */
920 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
921                                         struct hda_codec *codec,
922                                         snd_pcm_substream_t *substream)
923 {
924         struct alc_spec *spec = codec->spec;
925         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
926 }
927
928 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
929                                          struct hda_codec *codec,
930                                          snd_pcm_substream_t *substream)
931 {
932         struct alc_spec *spec = codec->spec;
933         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
934 }
935
936 /*
937  * Analog capture
938  */
939 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
940                                       struct hda_codec *codec,
941                                       unsigned int stream_tag,
942                                       unsigned int format,
943                                       snd_pcm_substream_t *substream)
944 {
945         struct alc_spec *spec = codec->spec;
946
947         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
948                                    stream_tag, 0, format);
949         return 0;
950 }
951
952 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
953                                       struct hda_codec *codec,
954                                       snd_pcm_substream_t *substream)
955 {
956         struct alc_spec *spec = codec->spec;
957
958         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
959         return 0;
960 }
961
962
963 /*
964  */
965 static struct hda_pcm_stream alc880_pcm_analog_playback = {
966         .substreams = 1,
967         .channels_min = 2,
968         .channels_max = 8,
969         .nid = 0x02, /* NID to query formats and rates */
970         .ops = {
971                 .open = alc880_playback_pcm_open,
972                 .prepare = alc880_playback_pcm_prepare,
973                 .cleanup = alc880_playback_pcm_cleanup
974         },
975 };
976
977 static struct hda_pcm_stream alc880_pcm_analog_capture = {
978         .substreams = 2,
979         .channels_min = 2,
980         .channels_max = 2,
981         .nid = 0x08, /* NID to query formats and rates
982                       * (0x07 might be broken on some devices)
983                       */
984         .ops = {
985                 .prepare = alc880_capture_pcm_prepare,
986                 .cleanup = alc880_capture_pcm_cleanup
987         },
988 };
989
990 static struct hda_pcm_stream alc880_pcm_digital_playback = {
991         .substreams = 1,
992         .channels_min = 2,
993         .channels_max = 2,
994         /* NID is set in alc_build_pcms */
995         .ops = {
996                 .open = alc880_dig_playback_pcm_open,
997                 .close = alc880_dig_playback_pcm_close
998         },
999 };
1000
1001 static struct hda_pcm_stream alc880_pcm_digital_capture = {
1002         .substreams = 1,
1003         .channels_min = 2,
1004         .channels_max = 2,
1005         /* NID is set in alc_build_pcms */
1006 };
1007
1008 static int alc_build_pcms(struct hda_codec *codec)
1009 {
1010         struct alc_spec *spec = codec->spec;
1011         struct hda_pcm *info = spec->pcm_rec;
1012         int i;
1013
1014         codec->num_pcms = 1;
1015         codec->pcm_info = info;
1016
1017         info->name = spec->stream_name_analog;
1018         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1019         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1020
1021         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1022         for (i = 0; i < spec->num_channel_mode; i++) {
1023                 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1024                     info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1025                 }
1026         }
1027
1028         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1029                 codec->num_pcms++;
1030                 info++;
1031                 info->name = spec->stream_name_digital;
1032                 if (spec->multiout.dig_out_nid) {
1033                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
1034                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1035                 }
1036                 if (spec->dig_in_nid) {
1037                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
1038                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1039                 }
1040         }
1041
1042         return 0;
1043 }
1044
1045 static void alc_free(struct hda_codec *codec)
1046 {
1047         kfree(codec->spec);
1048 }
1049
1050 /*
1051  */
1052 static struct hda_codec_ops alc_patch_ops = {
1053         .build_controls = alc_build_controls,
1054         .build_pcms = alc_build_pcms,
1055         .init = alc_init,
1056         .free = alc_free,
1057 #ifdef CONFIG_PM
1058         .resume = alc_resume,
1059 #endif
1060 };
1061
1062
1063 /*
1064  * Test configuration for debugging
1065  *
1066  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
1067  * enum controls.
1068  */
1069 #ifdef CONFIG_SND_DEBUG
1070 static hda_nid_t alc880_test_dac_nids[4] = {
1071         0x02, 0x03, 0x04, 0x05
1072 };
1073
1074 static struct hda_input_mux alc880_test_capture_source = {
1075         .num_items = 5,
1076         .items = {
1077                 { "In-1", 0x0 },
1078                 { "In-2", 0x1 },
1079                 { "In-3", 0x2 },
1080                 { "In-4", 0x3 },
1081                 { "CD", 0x4 },
1082         },
1083 };
1084
1085 static struct alc_channel_mode alc880_test_modes[4] = {
1086         { 2, NULL },
1087         { 4, NULL },
1088         { 6, NULL },
1089         { 8, NULL },
1090 };
1091
1092 static int alc_test_pin_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1093 {
1094         static char *texts[] = {
1095                 "N/A", "Line Out", "HP Out",
1096                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1097         };
1098         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1099         uinfo->count = 1;
1100         uinfo->value.enumerated.items = 8;
1101         if (uinfo->value.enumerated.item >= 8)
1102                 uinfo->value.enumerated.item = 7;
1103         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1104         return 0;
1105 }
1106
1107 static int alc_test_pin_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1108 {
1109         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1110         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1111         unsigned int pin_ctl, item = 0;
1112
1113         pin_ctl = snd_hda_codec_read(codec, nid, 0,
1114                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1115         if (pin_ctl & AC_PINCTL_OUT_EN) {
1116                 if (pin_ctl & AC_PINCTL_HP_EN)
1117                         item = 2;
1118                 else
1119                         item = 1;
1120         } else if (pin_ctl & AC_PINCTL_IN_EN) {
1121                 switch (pin_ctl & AC_PINCTL_VREFEN) {
1122                 case AC_PINCTL_VREF_HIZ: item = 3; break;
1123                 case AC_PINCTL_VREF_50:  item = 4; break;
1124                 case AC_PINCTL_VREF_GRD: item = 5; break;
1125                 case AC_PINCTL_VREF_80:  item = 6; break;
1126                 case AC_PINCTL_VREF_100: item = 7; break;
1127                 }
1128         }
1129         ucontrol->value.enumerated.item[0] = item;
1130         return 0;
1131 }
1132
1133 static int alc_test_pin_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1134 {
1135         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1136         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1137         static unsigned int ctls[] = {
1138                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1139                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1140                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1141                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1142                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1143                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1144         };
1145         unsigned int old_ctl, new_ctl;
1146
1147         old_ctl = snd_hda_codec_read(codec, nid, 0,
1148                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1149         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1150         if (old_ctl != new_ctl) {
1151                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
1152                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1153                                     ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);
1154                 return 1;
1155         }
1156         return 0;
1157 }
1158
1159 static int alc_test_pin_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1160 {
1161         static char *texts[] = {
1162                 "Front", "Surround", "CLFE", "Side"
1163         };
1164         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1165         uinfo->count = 1;
1166         uinfo->value.enumerated.items = 4;
1167         if (uinfo->value.enumerated.item >= 4)
1168                 uinfo->value.enumerated.item = 3;
1169         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1170         return 0;
1171 }
1172
1173 static int alc_test_pin_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1174 {
1175         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1176         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1177         unsigned int sel;
1178
1179         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1180         ucontrol->value.enumerated.item[0] = sel & 3;
1181         return 0;
1182 }
1183
1184 static int alc_test_pin_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1185 {
1186         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1187         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1188         unsigned int sel;
1189
1190         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1191         if (ucontrol->value.enumerated.item[0] != sel) {
1192                 sel = ucontrol->value.enumerated.item[0] & 3;
1193                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
1194                 return 1;
1195         }
1196         return 0;
1197 }
1198
1199 #define PIN_CTL_TEST(xname,nid) {                       \
1200                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1201                         .name = xname,                 \
1202                         .info = alc_test_pin_ctl_info, \
1203                         .get = alc_test_pin_ctl_get,   \
1204                         .put = alc_test_pin_ctl_put,   \
1205                         .private_value = nid           \
1206                         }
1207
1208 #define PIN_SRC_TEST(xname,nid) {                       \
1209                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1210                         .name = xname,                 \
1211                         .info = alc_test_pin_src_info, \
1212                         .get = alc_test_pin_src_get,   \
1213                         .put = alc_test_pin_src_put,   \
1214                         .private_value = nid           \
1215                         }
1216
1217 static snd_kcontrol_new_t alc880_test_mixer[] = {
1218         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1219         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1220         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1221         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1222         PIN_CTL_TEST("Front Pin Mode", 0x14),
1223         PIN_CTL_TEST("Surround Pin Mode", 0x15),
1224         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1225         PIN_CTL_TEST("Side Pin Mode", 0x17),
1226         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1227         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1228         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1229         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1230         PIN_SRC_TEST("In-1 Pin Source", 0x18),
1231         PIN_SRC_TEST("In-2 Pin Source", 0x19),
1232         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1233         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1234         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1235         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1236         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1237         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1238         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1239         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1240         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1241         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1242         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1243         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1244         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1245         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1246         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1247         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1248         {
1249                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1250                 .name = "Input Source",
1251                 .count = 2,
1252                 .info = alc_mux_enum_info,
1253                 .get = alc_mux_enum_get,
1254                 .put = alc_mux_enum_put,
1255         },
1256         {
1257                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1258                 .name = "Channel Mode",
1259                 .info = alc880_ch_mode_info,
1260                 .get = alc880_ch_mode_get,
1261                 .put = alc880_ch_mode_put,
1262                 .private_value = ARRAY_SIZE(alc880_test_modes),
1263         },
1264         { } /* end */
1265 };
1266
1267 static struct hda_verb alc880_test_init_verbs[] = {
1268         /* Unmute inputs of 0x0c - 0x0f */
1269         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1270         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100},
1271         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1272         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100},
1273         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1274         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100},
1275         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1276         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100},
1277         /* Vol output for 0x0c-0x0f */
1278         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1279         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1280         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1281         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1282         /* Set output pins 0x14-0x17 */
1283         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1284         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1285         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1286         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1287         /* Unmute output pins 0x14-0x17 */
1288         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1289         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1290         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1291         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1292         /* Set input pins 0x18-0x1c */
1293         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, /* vref 80% */
1294         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1295         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1296         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1297         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1298         /* Mute input pins 0x18-0x1b */
1299         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1300         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1301         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1302         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1303         /* ADC set up */
1304         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1305         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1306         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1307         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1308         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1309         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1310         { }
1311 };
1312 #endif
1313
1314 /*
1315  */
1316
1317 static struct hda_board_config alc880_cfg_tbl[] = {
1318         /* Back 3 jack, front 2 jack */
1319         { .modelname = "3stack", .config = ALC880_3ST },
1320         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
1321         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
1322         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
1323         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
1324         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
1325         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
1326         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
1327         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
1328         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
1329         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
1330         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
1331         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
1332         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
1333         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
1334         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
1335         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
1336         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
1337         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
1338         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
1339         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
1340         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
1341         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
1342         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
1343         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
1344         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
1345         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
1346         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
1347         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
1348         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
1349         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
1350         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
1351         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
1352
1353         /* Back 3 jack, front 2 jack (Internal add Aux-In) */
1354         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
1355
1356         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
1357         { .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
1358         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
1359
1360         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
1361         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
1362         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
1363         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
1364
1365         /* Back 5 jack, front 2 jack */
1366         { .modelname = "5stack", .config = ALC880_5ST },
1367         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
1368         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
1369         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
1370         { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
1371
1372         /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
1373         { .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
1374         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
1375         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
1376         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
1377         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
1378         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
1379         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
1380         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
1381         { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
1382
1383         { .modelname = "w810", .config = ALC880_W810 },
1384         { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
1385
1386         { .modelname = "z71v", .config = ALC880_Z71V },
1387         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
1388
1389 #ifdef CONFIG_SND_DEBUG
1390         { .modelname = "test", .config = ALC880_TEST },
1391 #endif
1392
1393         {}
1394 };
1395
1396 static int patch_alc880(struct hda_codec *codec)
1397 {
1398         struct alc_spec *spec;
1399         int board_config;
1400
1401         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1402         if (spec == NULL)
1403                 return -ENOMEM;
1404
1405         codec->spec = spec;
1406
1407         board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
1408         if (board_config < 0) {
1409                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC880\n");
1410                 board_config = ALC880_MINIMAL;
1411         }
1412
1413         switch (board_config) {
1414         case ALC880_W810:
1415                 spec->mixers[spec->num_mixers] = alc880_w810_base_mixer;
1416                 spec->num_mixers++;
1417                 break;
1418         case ALC880_5ST:
1419         case ALC880_5ST_DIG:
1420                 spec->mixers[spec->num_mixers] = alc880_five_stack_mixer;
1421                 spec->num_mixers++;
1422                 break;
1423         case ALC880_Z71V:
1424                 spec->mixers[spec->num_mixers] = alc880_z71v_mixer;
1425                 spec->num_mixers++;
1426                 break;
1427 #ifdef CONFIG_SND_DEBUG
1428         case ALC880_TEST:
1429                 spec->mixers[spec->num_mixers] = alc880_test_mixer;
1430                 spec->num_mixers++;
1431                 break;
1432 #endif
1433         default:
1434                 spec->mixers[spec->num_mixers] = alc880_base_mixer;
1435                 spec->num_mixers++;
1436                 break;
1437         }
1438
1439         switch (board_config) {
1440         case ALC880_3ST_DIG:
1441         case ALC880_5ST_DIG:
1442         case ALC880_W810:
1443         case ALC880_Z71V:
1444         case ALC880_TEST:
1445                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
1446                 break;
1447         default:
1448                 break;
1449         }
1450
1451         switch (board_config) {
1452         case ALC880_3ST:
1453         case ALC880_3ST_DIG:
1454         case ALC880_5ST:
1455         case ALC880_5ST_DIG:
1456         case ALC880_W810:
1457                 spec->front_panel = 1;
1458                 break;
1459         default:
1460                 break;
1461         }
1462
1463         switch (board_config) {
1464         case ALC880_5ST:
1465         case ALC880_5ST_DIG:
1466                 spec->init_verbs = alc880_init_verbs_five_stack;
1467                 spec->channel_mode = alc880_fivestack_modes;
1468                 spec->num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes);
1469                 break;
1470         case ALC880_W810:
1471                 spec->init_verbs = alc880_w810_init_verbs;
1472                 spec->channel_mode = alc880_w810_modes;
1473                 spec->num_channel_mode = ARRAY_SIZE(alc880_w810_modes);
1474                 break;
1475         case ALC880_Z71V:
1476                 spec->init_verbs = alc880_z71v_init_verbs;
1477                 spec->channel_mode = alc880_z71v_modes;
1478                 spec->num_channel_mode = ARRAY_SIZE(alc880_z71v_modes);
1479                 break;
1480 #ifdef CONFIG_SND_DEBUG
1481         case ALC880_TEST:
1482                 spec->init_verbs = alc880_test_init_verbs;
1483                 spec->channel_mode = alc880_test_modes;
1484                 spec->num_channel_mode = ARRAY_SIZE(alc880_test_modes);
1485                 break;
1486 #endif
1487         default:
1488                 spec->init_verbs = alc880_init_verbs_three_stack;
1489                 spec->channel_mode = alc880_threestack_modes;
1490                 spec->num_channel_mode = ARRAY_SIZE(alc880_threestack_modes);
1491                 break;
1492         }
1493
1494         spec->stream_name_analog = "ALC880 Analog";
1495         spec->stream_analog_playback = &alc880_pcm_analog_playback;
1496         spec->stream_analog_capture = &alc880_pcm_analog_capture;
1497
1498         spec->stream_name_digital = "ALC880 Digital";
1499         spec->stream_digital_playback = &alc880_pcm_digital_playback;
1500         spec->stream_digital_capture = &alc880_pcm_digital_capture;
1501
1502         spec->multiout.max_channels = spec->channel_mode[0].channels;
1503
1504         switch (board_config) {
1505         case ALC880_W810:
1506                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids);
1507                 spec->multiout.dac_nids = alc880_w810_dac_nids;
1508                 // No dedicated headphone socket - it's shared with built-in speakers.
1509                 break;
1510         case ALC880_Z71V:
1511                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids);
1512                 spec->multiout.dac_nids = alc880_z71v_dac_nids;
1513                 spec->multiout.hp_nid = 0x03;
1514                 break;
1515 #ifdef CONFIG_SND_DEBUG
1516         case ALC880_TEST:
1517                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_test_dac_nids);
1518                 spec->multiout.dac_nids = alc880_test_dac_nids;
1519                 spec->input_mux = &alc880_test_capture_source;
1520                 break;
1521 #endif
1522         default:
1523                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_dac_nids);
1524                 spec->multiout.dac_nids = alc880_dac_nids;
1525                 spec->multiout.hp_nid = 0x03; /* rear-surround NID */
1526                 break;
1527         }
1528
1529         if (! spec->input_mux)
1530                 spec->input_mux = &alc880_capture_source;
1531         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
1532         spec->adc_nids = alc880_adc_nids;
1533
1534         codec->patch_ops = alc_patch_ops;
1535
1536         return 0;
1537 }
1538
1539 /*
1540  * ALC260 support
1541  */
1542
1543 /*
1544  * This is just place-holder, so there's something for alc_build_pcms to look
1545  * at when it calculates the maximum number of channels. ALC260 has no mixer
1546  * element which allows changing the channel mode, so the verb list is
1547  * never used.
1548  */
1549 static struct alc_channel_mode alc260_modes[1] = {
1550         { 2, NULL },
1551 };
1552
1553 snd_kcontrol_new_t alc260_base_mixer[] = {
1554         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
1555         /* use LINE2 for the output */
1556         /* HDA_CODEC_MUTE("Front Playback Switch", 0x0f, 0x0, HDA_OUTPUT), */
1557         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1558         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
1559         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
1560         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
1561         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
1562         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
1563         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
1564         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
1565         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
1566         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
1567         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
1568         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
1569         HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1570         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1571         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
1572         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
1573         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
1574         {
1575                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1576                 .name = "Capture Source",
1577                 .info = alc_mux_enum_info,
1578                 .get = alc_mux_enum_get,
1579                 .put = alc_mux_enum_put,
1580         },
1581         { } /* end */
1582 };
1583
1584 static struct hda_verb alc260_init_verbs[] = {
1585         /* Line In pin widget for input */
1586         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1587         /* CD pin widget for input */
1588         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1589         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1590         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1591         /* Mic2 (front panel) pin widget for input and vref at 80% */
1592         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1593         /* LINE-2 is used for line-out in rear */
1594         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1595         /* select line-out */
1596         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1597         /* LINE-OUT pin */
1598         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1599         /* enable HP */
1600         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1601         /* enable Mono */
1602         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1603         /* unmute amp left and right */
1604         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1605         /* set connection select to line in (default select for this ADC) */
1606         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
1607         /* unmute Line-Out mixer amp left and right (volume = 0) */
1608         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1609         /* mute pin widget amp left and right (no gain on this amp) */
1610         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1611         /* unmute HP mixer amp left and right (volume = 0) */
1612         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1613         /* mute pin widget amp left and right (no gain on this amp) */
1614         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1615         /* unmute Mono mixer amp left and right (volume = 0) */
1616         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1617         /* mute pin widget amp left and right (no gain on this amp) */
1618         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1619         /* mute LINE-2 out */
1620         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1621         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
1622         /* unmute CD */
1623         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1624         /* unmute Line In */
1625         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1626         /* unmute Mic */
1627         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1628         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
1629         /* Unmute Front out path */
1630         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1631         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1632         /* Unmute Headphone out path */
1633         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1634         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1635         /* Unmute Mono out path */
1636         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1637         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1638         { }
1639 };
1640
1641 static struct hda_pcm_stream alc260_pcm_analog_playback = {
1642         .substreams = 1,
1643         .channels_min = 2,
1644         .channels_max = 2,
1645         .nid = 0x2,
1646 };
1647
1648 static struct hda_pcm_stream alc260_pcm_analog_capture = {
1649         .substreams = 1,
1650         .channels_min = 2,
1651         .channels_max = 2,
1652         .nid = 0x4,
1653 };
1654
1655 static int patch_alc260(struct hda_codec *codec)
1656 {
1657         struct alc_spec *spec;
1658
1659         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1660         if (spec == NULL)
1661                 return -ENOMEM;
1662
1663         codec->spec = spec;
1664
1665         spec->mixers[spec->num_mixers] = alc260_base_mixer;
1666         spec->num_mixers++;
1667
1668         spec->init_verbs = alc260_init_verbs;
1669         spec->channel_mode = alc260_modes;
1670         spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
1671
1672         spec->stream_name_analog = "ALC260 Analog";
1673         spec->stream_analog_playback = &alc260_pcm_analog_playback;
1674         spec->stream_analog_capture = &alc260_pcm_analog_capture;
1675
1676         spec->multiout.max_channels = spec->channel_mode[0].channels;
1677         spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
1678         spec->multiout.dac_nids = alc260_dac_nids;
1679
1680         spec->input_mux = &alc260_capture_source;
1681         spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
1682         spec->adc_nids = alc260_adc_nids;
1683
1684         codec->patch_ops = alc_patch_ops;
1685
1686         return 0;
1687 }
1688
1689 /*
1690  * ALC882 support
1691  *
1692  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1693  * configuration.  Each pin widget can choose any input DACs and a mixer.
1694  * Each ADC is connected from a mixer of all inputs.  This makes possible
1695  * 6-channel independent captures.
1696  *
1697  * In addition, an independent DAC for the multi-playback (not used in this
1698  * driver yet).
1699  */
1700
1701 static struct alc_channel_mode alc882_ch_modes[1] = {
1702         { 8, NULL }
1703 };
1704
1705 static hda_nid_t alc882_dac_nids[4] = {
1706         /* front, rear, clfe, rear_surr */
1707         0x02, 0x03, 0x04, 0x05
1708 };
1709
1710 static hda_nid_t alc882_adc_nids[3] = {
1711         /* ADC0-2 */
1712         0x07, 0x08, 0x09,
1713 };
1714
1715 /* input MUX */
1716 /* FIXME: should be a matrix-type input source selection */
1717
1718 static struct hda_input_mux alc882_capture_source = {
1719         .num_items = 4,
1720         .items = {
1721                 { "Mic", 0x0 },
1722                 { "Front Mic", 0x1 },
1723                 { "Line", 0x2 },
1724                 { "CD", 0x4 },
1725         },
1726 };
1727
1728 #define alc882_mux_enum_info alc_mux_enum_info
1729 #define alc882_mux_enum_get alc_mux_enum_get
1730
1731 static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1732 {
1733         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1734         struct alc_spec *spec = codec->spec;
1735         const struct hda_input_mux *imux = spec->input_mux;
1736         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1737         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
1738         hda_nid_t nid = capture_mixers[adc_idx];
1739         unsigned int *cur_val = &spec->cur_mux[adc_idx];
1740         unsigned int i, idx;
1741
1742         idx = ucontrol->value.enumerated.item[0];
1743         if (idx >= imux->num_items)
1744                 idx = imux->num_items - 1;
1745         if (*cur_val == idx && ! codec->in_resume)
1746                 return 0;
1747         for (i = 0; i < imux->num_items; i++) {
1748                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
1749                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1750                                     v | (imux->items[i].index << 8));
1751         }
1752         *cur_val = idx;
1753         return 1;
1754 }
1755
1756 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
1757  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
1758  */
1759 static snd_kcontrol_new_t alc882_base_mixer[] = {
1760         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1761         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1762         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1763         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1764         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1765         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1766         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
1767         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
1768         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1769         HDA_CODEC_MUTE("Side Playback Switch", 0x17, 0x0, HDA_OUTPUT),
1770         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1771         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1772         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1773         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1774         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1775         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1776         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1777         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1778         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1779         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1780         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1781         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1782         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1783         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1784         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1785         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1786         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1787         {
1788                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1789                 /* .name = "Capture Source", */
1790                 .name = "Input Source",
1791                 .count = 3,
1792                 .info = alc882_mux_enum_info,
1793                 .get = alc882_mux_enum_get,
1794                 .put = alc882_mux_enum_put,
1795         },
1796         { } /* end */
1797 };
1798
1799 static struct hda_verb alc882_init_verbs[] = {
1800         /* Front mixer: unmute input/output amp left and right (volume = 0) */
1801         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1802         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1803         /* Rear mixer */
1804         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1805         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1806         /* CLFE mixer */
1807         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1808         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1809         /* Side mixer */
1810         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1811         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1812
1813         /* Front Pin: to output mode */
1814         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1815         /* Front Pin: mute amp left and right (no volume) */
1816         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1817         /* select Front mixer (0x0c, index 0) */
1818         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1819         /* Rear Pin */
1820         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1821         /* Rear Pin: mute amp left and right (no volume) */
1822         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1823         /* select Rear mixer (0x0d, index 1) */
1824         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
1825         /* CLFE Pin */
1826         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1827         /* CLFE Pin: mute amp left and right (no volume) */
1828         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1829         /* select CLFE mixer (0x0e, index 2) */
1830         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1831         /* Side Pin */
1832         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1833         /* Side Pin: mute amp left and right (no volume) */
1834         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1835         /* select Side mixer (0x0f, index 3) */
1836         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1837         /* Headphone Pin */
1838         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1839         /* Headphone Pin: mute amp left and right (no volume) */
1840         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1841         /* select Front mixer (0x0c, index 0) */
1842         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1843         /* Mic (rear) pin widget for input and vref at 80% */
1844         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1845         /* Front Mic pin widget for input and vref at 80% */
1846         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1847         /* Line In pin widget for input */
1848         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1849         /* CD pin widget for input */
1850         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1851
1852         /* FIXME: use matrix-type input source selection */
1853         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1854         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1855         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1856         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1857         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1858         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1859         /* Input mixer2 */
1860         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1861         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1862         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1863         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1864         /* Input mixer3 */
1865         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1866         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1867         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1868         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1869         /* ADC1: unmute amp left and right */
1870         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1871         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1872         /* ADC2: unmute amp left and right */
1873         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1874         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1875         /* ADC3: unmute amp left and right */
1876         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1877         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1878         /* Unmute front loopback */
1879         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1880         /* Unmute rear loopback */
1881         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1882         /* Mute CLFE loopback */
1883         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
1884         /* Unmute side loopback */
1885         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1886
1887         { }
1888 };
1889
1890 static int patch_alc882(struct hda_codec *codec)
1891 {
1892         struct alc_spec *spec;
1893
1894         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1895         if (spec == NULL)
1896                 return -ENOMEM;
1897
1898         codec->spec = spec;
1899
1900         spec->mixers[spec->num_mixers] = alc882_base_mixer;
1901         spec->num_mixers++;
1902
1903         spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
1904         spec->dig_in_nid = ALC880_DIGIN_NID;
1905         spec->front_panel = 1;
1906         spec->init_verbs = alc882_init_verbs;
1907         spec->channel_mode = alc882_ch_modes;
1908         spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes);
1909
1910         spec->stream_name_analog = "ALC882 Analog";
1911         spec->stream_analog_playback = &alc880_pcm_analog_playback;
1912         spec->stream_analog_capture = &alc880_pcm_analog_capture;
1913
1914         spec->stream_name_digital = "ALC882 Digital";
1915         spec->stream_digital_playback = &alc880_pcm_digital_playback;
1916         spec->stream_digital_capture = &alc880_pcm_digital_capture;
1917
1918         spec->multiout.max_channels = spec->channel_mode[0].channels;
1919         spec->multiout.num_dacs = ARRAY_SIZE(alc882_dac_nids);
1920         spec->multiout.dac_nids = alc882_dac_nids;
1921
1922         spec->input_mux = &alc882_capture_source;
1923         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
1924         spec->adc_nids = alc882_adc_nids;
1925
1926         codec->patch_ops = alc_patch_ops;
1927
1928         return 0;
1929 }
1930
1931 /*
1932  * patch entries
1933  */
1934 struct hda_codec_preset snd_hda_preset_realtek[] = {
1935         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
1936         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1937         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
1938         {} /* terminator */
1939 };