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