]> git.karo-electronics.de Git - karo-tx-linux.git/blob - sound/pci/hda/alc880_quirks.c
ALSA: hda/realtek - Rewrite ALC880 model=lg with the auto-parser
[karo-tx-linux.git] / sound / pci / hda / alc880_quirks.c
1 /*
2  * ALC880 quirk models
3  * included by patch_realtek.c
4  */
5
6 /* ALC880 board config type */
7 enum {
8         ALC880_AUTO,
9         ALC880_3ST,
10         ALC880_3ST_DIG,
11         ALC880_5ST,
12         ALC880_5ST_DIG,
13         ALC880_W810,
14         ALC880_Z71V,
15         ALC880_6ST,
16         ALC880_6ST_DIG,
17         ALC880_F1734,
18         ALC880_ASUS,
19         ALC880_ASUS_DIG,
20         ALC880_ASUS_W1V,
21         ALC880_ASUS_DIG2,
22         ALC880_FUJITSU,
23         ALC880_UNIWILL_DIG,
24         ALC880_UNIWILL,
25         ALC880_UNIWILL_P53,
26         ALC880_CLEVO,
27         ALC880_TCL_S700,
28 #ifdef CONFIG_SND_DEBUG
29         ALC880_TEST,
30 #endif
31         ALC880_MODEL_LAST /* last tag */
32 };
33
34 /*
35  * ALC880 3-stack model
36  *
37  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
38  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
39  *                 F-Mic = 0x1b, HP = 0x19
40  */
41
42 static const hda_nid_t alc880_dac_nids[4] = {
43         /* front, rear, clfe, rear_surr */
44         0x02, 0x05, 0x04, 0x03
45 };
46
47 static const hda_nid_t alc880_adc_nids[3] = {
48         /* ADC0-2 */
49         0x07, 0x08, 0x09,
50 };
51
52 /* The datasheet says the node 0x07 is connected from inputs,
53  * but it shows zero connection in the real implementation on some devices.
54  * Note: this is a 915GAV bug, fixed on 915GLV
55  */
56 static const hda_nid_t alc880_adc_nids_alt[2] = {
57         /* ADC1-2 */
58         0x08, 0x09,
59 };
60
61 #define ALC880_DIGOUT_NID       0x06
62 #define ALC880_DIGIN_NID        0x0a
63 #define ALC880_PIN_CD_NID       0x1c
64
65 static const struct hda_input_mux alc880_capture_source = {
66         .num_items = 4,
67         .items = {
68                 { "Mic", 0x0 },
69                 { "Front Mic", 0x3 },
70                 { "Line", 0x2 },
71                 { "CD", 0x4 },
72         },
73 };
74
75 /* channel source setting (2/6 channel selection for 3-stack) */
76 /* 2ch mode */
77 static const struct hda_verb alc880_threestack_ch2_init[] = {
78         /* set line-in to input, mute it */
79         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
80         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
81         /* set mic-in to input vref 80%, mute it */
82         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
83         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
84         { } /* end */
85 };
86
87 /* 6ch mode */
88 static const struct hda_verb alc880_threestack_ch6_init[] = {
89         /* set line-in to output, unmute it */
90         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
91         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
92         /* set mic-in to output, unmute it */
93         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
94         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
95         { } /* end */
96 };
97
98 static const struct hda_channel_mode alc880_threestack_modes[2] = {
99         { 2, alc880_threestack_ch2_init },
100         { 6, alc880_threestack_ch6_init },
101 };
102
103 static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
104         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
105         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
106         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
107         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
108         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
109         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
110         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
111         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
112         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
113         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
114         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
115         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
116         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
117         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
118         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
119         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
120         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
121         {
122                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
123                 .name = "Channel Mode",
124                 .info = alc_ch_mode_info,
125                 .get = alc_ch_mode_get,
126                 .put = alc_ch_mode_put,
127         },
128         { } /* end */
129 };
130
131 /*
132  * ALC880 5-stack model
133  *
134  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
135  *      Side = 0x02 (0xd)
136  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
137  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
138  */
139
140 /* additional mixers to alc880_three_stack_mixer */
141 static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
142         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
143         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
144         { } /* end */
145 };
146
147 /* channel source setting (6/8 channel selection for 5-stack) */
148 /* 6ch mode */
149 static const struct hda_verb alc880_fivestack_ch6_init[] = {
150         /* set line-in to input, mute it */
151         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
152         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
153         { } /* end */
154 };
155
156 /* 8ch mode */
157 static const struct hda_verb alc880_fivestack_ch8_init[] = {
158         /* set line-in to output, unmute it */
159         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
160         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
161         { } /* end */
162 };
163
164 static const struct hda_channel_mode alc880_fivestack_modes[2] = {
165         { 6, alc880_fivestack_ch6_init },
166         { 8, alc880_fivestack_ch8_init },
167 };
168
169
170 /*
171  * ALC880 6-stack model
172  *
173  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
174  *      Side = 0x05 (0x0f)
175  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
176  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
177  */
178
179 static const hda_nid_t alc880_6st_dac_nids[4] = {
180         /* front, rear, clfe, rear_surr */
181         0x02, 0x03, 0x04, 0x05
182 };
183
184 static const struct hda_input_mux alc880_6stack_capture_source = {
185         .num_items = 4,
186         .items = {
187                 { "Mic", 0x0 },
188                 { "Front Mic", 0x1 },
189                 { "Line", 0x2 },
190                 { "CD", 0x4 },
191         },
192 };
193
194 /* fixed 8-channels */
195 static const struct hda_channel_mode alc880_sixstack_modes[1] = {
196         { 8, NULL },
197 };
198
199 static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
200         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
201         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
202         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
203         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
204         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
205         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
206         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
207         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
208         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
209         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
210         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
211         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
212         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
213         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
214         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
215         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
216         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
217         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
218         {
219                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
220                 .name = "Channel Mode",
221                 .info = alc_ch_mode_info,
222                 .get = alc_ch_mode_get,
223                 .put = alc_ch_mode_put,
224         },
225         { } /* end */
226 };
227
228
229 /*
230  * ALC880 W810 model
231  *
232  * W810 has rear IO for:
233  * Front (DAC 02)
234  * Surround (DAC 03)
235  * Center/LFE (DAC 04)
236  * Digital out (06)
237  *
238  * The system also has a pair of internal speakers, and a headphone jack.
239  * These are both connected to Line2 on the codec, hence to DAC 02.
240  *
241  * There is a variable resistor to control the speaker or headphone
242  * volume. This is a hardware-only device without a software API.
243  *
244  * Plugging headphones in will disable the internal speakers. This is
245  * implemented in hardware, not via the driver using jack sense. In
246  * a similar fashion, plugging into the rear socket marked "front" will
247  * disable both the speakers and headphones.
248  *
249  * For input, there's a microphone jack, and an "audio in" jack.
250  * These may not do anything useful with this driver yet, because I
251  * haven't setup any initialization verbs for these yet...
252  */
253
254 static const hda_nid_t alc880_w810_dac_nids[3] = {
255         /* front, rear/surround, clfe */
256         0x02, 0x03, 0x04
257 };
258
259 /* fixed 6 channels */
260 static const struct hda_channel_mode alc880_w810_modes[1] = {
261         { 6, NULL }
262 };
263
264 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
265 static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
266         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
267         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
268         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
269         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
270         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
271         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
272         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
273         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
274         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
275         { } /* end */
276 };
277
278
279 /*
280  * Z710V model
281  *
282  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
283  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
284  *                 Line = 0x1a
285  */
286
287 static const hda_nid_t alc880_z71v_dac_nids[1] = {
288         0x02
289 };
290 #define ALC880_Z71V_HP_DAC      0x03
291
292 /* fixed 2 channels */
293 static const struct hda_channel_mode alc880_2_jack_modes[1] = {
294         { 2, NULL }
295 };
296
297 static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
298         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
299         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
300         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
301         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
302         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
303         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
304         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
305         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
306         { } /* end */
307 };
308
309
310 /*
311  * ALC880 F1734 model
312  *
313  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
314  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
315  */
316
317 static const hda_nid_t alc880_f1734_dac_nids[1] = {
318         0x03
319 };
320 #define ALC880_F1734_HP_DAC     0x02
321
322 static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
323         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
324         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
325         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
326         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
327         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
328         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
329         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
330         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
331         { } /* end */
332 };
333
334 static const struct hda_input_mux alc880_f1734_capture_source = {
335         .num_items = 2,
336         .items = {
337                 { "Mic", 0x1 },
338                 { "CD", 0x4 },
339         },
340 };
341
342
343 /*
344  * ALC880 ASUS model
345  *
346  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
347  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
348  *  Mic = 0x18, Line = 0x1a
349  */
350
351 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
352 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
353
354 static const struct snd_kcontrol_new alc880_asus_mixer[] = {
355         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
356         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
357         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
358         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
359         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
360         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
361         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
362         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
363         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
364         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
365         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
366         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
367         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
368         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
369         {
370                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
371                 .name = "Channel Mode",
372                 .info = alc_ch_mode_info,
373                 .get = alc_ch_mode_get,
374                 .put = alc_ch_mode_put,
375         },
376         { } /* end */
377 };
378
379 /*
380  * ALC880 ASUS W1V model
381  *
382  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
383  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
384  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
385  */
386
387 /* additional mixers to alc880_asus_mixer */
388 static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
389         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
390         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
391         { } /* end */
392 };
393
394 /* TCL S700 */
395 static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
396         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
397         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
398         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
399         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
400         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
401         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
402         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
403         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
404         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
405         { } /* end */
406 };
407
408 /* Uniwill */
409 static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
410         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
411         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
412         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
413         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
414         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
415         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
416         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
417         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
418         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
419         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
420         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
421         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
422         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
423         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
424         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
425         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
426         {
427                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
428                 .name = "Channel Mode",
429                 .info = alc_ch_mode_info,
430                 .get = alc_ch_mode_get,
431                 .put = alc_ch_mode_put,
432         },
433         { } /* end */
434 };
435
436 static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
437         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
438         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
439         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
440         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
441         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
442         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
443         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
444         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
445         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
446         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
447         { } /* end */
448 };
449
450 static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
451         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
452         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
453         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
454         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
455         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
456         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
457         { } /* end */
458 };
459
460 /*
461  * initialize the codec volumes, etc
462  */
463
464 /*
465  * generic initialization of ADC, input mixers and output mixers
466  */
467 static const struct hda_verb alc880_volume_init_verbs[] = {
468         /*
469          * Unmute ADC0-2 and set the default input to mic-in
470          */
471         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
472         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
473         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
474         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
475         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
476         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
477
478         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
479          * mixer widget
480          * Note: PASD motherboards uses the Line In 2 as the input for front
481          * panel mic (mic 2)
482          */
483         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
484         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
485         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
486         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
487         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
488         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
489         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
490         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
491
492         /*
493          * Set up output mixers (0x0c - 0x0f)
494          */
495         /* set vol=0 to output mixers */
496         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
497         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
498         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
499         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
500         /* set up input amps for analog loopback */
501         /* Amp Indices: DAC = 0, mixer = 1 */
502         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
503         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
504         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
505         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
506         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
507         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
508         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
509         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
510
511         { }
512 };
513
514 /*
515  * 3-stack pin configuration:
516  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
517  */
518 static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
519         /*
520          * preset connection lists of input pins
521          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
522          */
523         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
524         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
525         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
526
527         /*
528          * Set pin mode and muting
529          */
530         /* set front pin widgets 0x14 for output */
531         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
532         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
533         /* Mic1 (rear panel) pin widget for input and vref at 80% */
534         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
535         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
536         /* Mic2 (as headphone out) for HP output */
537         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
538         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
539         /* Line In pin widget for input */
540         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
541         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
542         /* Line2 (as front mic) pin widget for input and vref at 80% */
543         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
544         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
545         /* CD pin widget for input */
546         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
547
548         { }
549 };
550
551 /*
552  * 5-stack pin configuration:
553  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
554  * line-in/side = 0x1a, f-mic = 0x1b
555  */
556 static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
557         /*
558          * preset connection lists of input pins
559          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
560          */
561         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
562         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
563
564         /*
565          * Set pin mode and muting
566          */
567         /* set pin widgets 0x14-0x17 for output */
568         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
569         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
570         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
571         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
572         /* unmute pins for output (no gain on this amp) */
573         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
574         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
575         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
576         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
577
578         /* Mic1 (rear panel) pin widget for input and vref at 80% */
579         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
580         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
581         /* Mic2 (as headphone out) for HP output */
582         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
583         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
584         /* Line In pin widget for input */
585         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
586         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
587         /* Line2 (as front mic) pin widget for input and vref at 80% */
588         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
589         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
590         /* CD pin widget for input */
591         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
592
593         { }
594 };
595
596 /*
597  * W810 pin configuration:
598  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
599  */
600 static const struct hda_verb alc880_pin_w810_init_verbs[] = {
601         /* hphone/speaker input selector: front DAC */
602         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
603
604         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
605         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
606         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
607         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
608         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
609         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
610
611         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
612         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
613
614         { }
615 };
616
617 /*
618  * Z71V pin configuration:
619  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
620  */
621 static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
622         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
623         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
624         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
625         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
626
627         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
628         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
629         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
630         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
631
632         { }
633 };
634
635 /*
636  * 6-stack pin configuration:
637  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
638  * f-mic = 0x19, line = 0x1a, HP = 0x1b
639  */
640 static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
641         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
642
643         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
644         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
645         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
646         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
647         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
648         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
649         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
650         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
651
652         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
653         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
654         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
655         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
656         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
657         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
658         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
659         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
660         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
661
662         { }
663 };
664
665 /*
666  * Uniwill pin configuration:
667  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
668  * line = 0x1a
669  */
670 static const struct hda_verb alc880_uniwill_init_verbs[] = {
671         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
672
673         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
674         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
675         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
676         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
677         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
678         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
679         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
680         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
681         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
682         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
683         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
684         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
685         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
686         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
687
688         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
689         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
690         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
691         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
692         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
693         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
694         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
695         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
696         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
697
698         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
699         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
700
701         { }
702 };
703
704 /*
705 * Uniwill P53
706 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
707  */
708 static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
709         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
710
711         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
712         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
713         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
714         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
715         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
716         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
717         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
718         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
719         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
720         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
721         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
722         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
723
724         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
725         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
726         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
727         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
728         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
729         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
730
731         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
732         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
733
734         { }
735 };
736
737 static const struct hda_verb alc880_beep_init_verbs[] = {
738         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
739         { }
740 };
741
742 static void alc880_uniwill_setup(struct hda_codec *codec)
743 {
744         struct alc_spec *spec = codec->spec;
745
746         spec->autocfg.hp_pins[0] = 0x14;
747         spec->autocfg.speaker_pins[0] = 0x15;
748         spec->autocfg.speaker_pins[0] = 0x16;
749         alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
750 }
751
752 static void alc880_uniwill_init_hook(struct hda_codec *codec)
753 {
754         alc_hp_automute(codec);
755         alc88x_simple_mic_automute(codec);
756 }
757
758 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
759                                        unsigned int res)
760 {
761         /* Looks like the unsol event is incompatible with the standard
762          * definition.  4bit tag is placed at 28 bit!
763          */
764         res >>= 28;
765         switch (res) {
766         case ALC_MIC_EVENT:
767                 alc88x_simple_mic_automute(codec);
768                 break;
769         default:
770                 alc_exec_unsol_event(codec, res);
771                 break;
772         }
773 }
774
775 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
776 {
777         struct alc_spec *spec = codec->spec;
778
779         spec->autocfg.hp_pins[0] = 0x14;
780         spec->autocfg.speaker_pins[0] = 0x15;
781         alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
782 }
783
784 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
785 {
786         unsigned int present;
787
788         present = snd_hda_codec_read(codec, 0x21, 0,
789                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
790         present &= HDA_AMP_VOLMASK;
791         snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
792                                  HDA_AMP_VOLMASK, present);
793         snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
794                                  HDA_AMP_VOLMASK, present);
795 }
796
797 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
798                                            unsigned int res)
799 {
800         /* Looks like the unsol event is incompatible with the standard
801          * definition.  4bit tag is placed at 28 bit!
802          */
803         res >>= 28;
804         if (res == ALC_DCVOL_EVENT)
805                 alc880_uniwill_p53_dcvol_automute(codec);
806         else
807                 alc_exec_unsol_event(codec, res);
808 }
809
810 /*
811  * F1734 pin configuration:
812  * HP = 0x14, speaker-out = 0x15, mic = 0x18
813  */
814 static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
815         {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
816         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
817         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
818         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
819         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
820
821         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
822         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
823         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
824         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
825
826         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
827         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
828         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
829         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
830         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
831         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
832         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
833         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
834         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
835
836         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
837         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
838
839         { }
840 };
841
842 /*
843  * ASUS pin configuration:
844  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
845  */
846 static const struct hda_verb alc880_pin_asus_init_verbs[] = {
847         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
848         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
849         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
850         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
851
852         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
853         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
854         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
855         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
856         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
857         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
858         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
859         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
860
861         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
862         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
863         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
864         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
865         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
866         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
867         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
868         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
869         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
870
871         { }
872 };
873
874 /* Enable GPIO mask and set output */
875 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
876 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
877 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
878
879 /* Clevo m520g init */
880 static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
881         /* headphone output */
882         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
883         /* line-out */
884         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
885         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
886         /* Line-in */
887         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
888         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
889         /* CD */
890         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
891         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
892         /* Mic1 (rear panel) */
893         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
894         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
895         /* Mic2 (front panel) */
896         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
897         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
898         /* headphone */
899         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
900         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
901         /* change to EAPD mode */
902         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
903         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
904
905         { }
906 };
907
908 static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
909         /* change to EAPD mode */
910         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
911         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
912
913         /* Headphone output */
914         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
915         /* Front output*/
916         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
917         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
918
919         /* Line In pin widget for input */
920         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
921         /* CD pin widget for input */
922         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
923         /* Mic1 (rear panel) pin widget for input and vref at 80% */
924         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
925
926         /* change to EAPD mode */
927         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
928         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
929
930         { }
931 };
932
933 /*
934  * Test configuration for debugging
935  *
936  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
937  * enum controls.
938  */
939 #ifdef CONFIG_SND_DEBUG
940 static const hda_nid_t alc880_test_dac_nids[4] = {
941         0x02, 0x03, 0x04, 0x05
942 };
943
944 static const struct hda_input_mux alc880_test_capture_source = {
945         .num_items = 7,
946         .items = {
947                 { "In-1", 0x0 },
948                 { "In-2", 0x1 },
949                 { "In-3", 0x2 },
950                 { "In-4", 0x3 },
951                 { "CD", 0x4 },
952                 { "Front", 0x5 },
953                 { "Surround", 0x6 },
954         },
955 };
956
957 static const struct hda_channel_mode alc880_test_modes[4] = {
958         { 2, NULL },
959         { 4, NULL },
960         { 6, NULL },
961         { 8, NULL },
962 };
963
964 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
965                                  struct snd_ctl_elem_info *uinfo)
966 {
967         static const char * const texts[] = {
968                 "N/A", "Line Out", "HP Out",
969                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
970         };
971         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
972         uinfo->count = 1;
973         uinfo->value.enumerated.items = 8;
974         if (uinfo->value.enumerated.item >= 8)
975                 uinfo->value.enumerated.item = 7;
976         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
977         return 0;
978 }
979
980 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
981                                 struct snd_ctl_elem_value *ucontrol)
982 {
983         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
984         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
985         unsigned int pin_ctl, item = 0;
986
987         pin_ctl = snd_hda_codec_read(codec, nid, 0,
988                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
989         if (pin_ctl & AC_PINCTL_OUT_EN) {
990                 if (pin_ctl & AC_PINCTL_HP_EN)
991                         item = 2;
992                 else
993                         item = 1;
994         } else if (pin_ctl & AC_PINCTL_IN_EN) {
995                 switch (pin_ctl & AC_PINCTL_VREFEN) {
996                 case AC_PINCTL_VREF_HIZ: item = 3; break;
997                 case AC_PINCTL_VREF_50:  item = 4; break;
998                 case AC_PINCTL_VREF_GRD: item = 5; break;
999                 case AC_PINCTL_VREF_80:  item = 6; break;
1000                 case AC_PINCTL_VREF_100: item = 7; break;
1001                 }
1002         }
1003         ucontrol->value.enumerated.item[0] = item;
1004         return 0;
1005 }
1006
1007 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
1008                                 struct snd_ctl_elem_value *ucontrol)
1009 {
1010         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1011         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1012         static const unsigned int ctls[] = {
1013                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1014                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1015                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1016                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1017                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1018                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1019         };
1020         unsigned int old_ctl, new_ctl;
1021
1022         old_ctl = snd_hda_codec_read(codec, nid, 0,
1023                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1024         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1025         if (old_ctl != new_ctl) {
1026                 int val;
1027                 snd_hda_codec_write_cache(codec, nid, 0,
1028                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
1029                                           new_ctl);
1030                 val = ucontrol->value.enumerated.item[0] >= 3 ?
1031                         HDA_AMP_MUTE : 0;
1032                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1033                                          HDA_AMP_MUTE, val);
1034                 return 1;
1035         }
1036         return 0;
1037 }
1038
1039 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
1040                                  struct snd_ctl_elem_info *uinfo)
1041 {
1042         static const char * const texts[] = {
1043                 "Front", "Surround", "CLFE", "Side"
1044         };
1045         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1046         uinfo->count = 1;
1047         uinfo->value.enumerated.items = 4;
1048         if (uinfo->value.enumerated.item >= 4)
1049                 uinfo->value.enumerated.item = 3;
1050         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1051         return 0;
1052 }
1053
1054 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
1055                                 struct snd_ctl_elem_value *ucontrol)
1056 {
1057         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1058         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1059         unsigned int sel;
1060
1061         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1062         ucontrol->value.enumerated.item[0] = sel & 3;
1063         return 0;
1064 }
1065
1066 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
1067                                 struct snd_ctl_elem_value *ucontrol)
1068 {
1069         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1070         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1071         unsigned int sel;
1072
1073         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1074         if (ucontrol->value.enumerated.item[0] != sel) {
1075                 sel = ucontrol->value.enumerated.item[0] & 3;
1076                 snd_hda_codec_write_cache(codec, nid, 0,
1077                                           AC_VERB_SET_CONNECT_SEL, sel);
1078                 return 1;
1079         }
1080         return 0;
1081 }
1082
1083 #define PIN_CTL_TEST(xname,nid) {                       \
1084                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1085                         .name = xname,                 \
1086                         .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1087                         .info = alc_test_pin_ctl_info, \
1088                         .get = alc_test_pin_ctl_get,   \
1089                         .put = alc_test_pin_ctl_put,   \
1090                         .private_value = nid           \
1091                         }
1092
1093 #define PIN_SRC_TEST(xname,nid) {                       \
1094                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1095                         .name = xname,                 \
1096                         .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1097                         .info = alc_test_pin_src_info, \
1098                         .get = alc_test_pin_src_get,   \
1099                         .put = alc_test_pin_src_put,   \
1100                         .private_value = nid           \
1101                         }
1102
1103 static const struct snd_kcontrol_new alc880_test_mixer[] = {
1104         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1105         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1106         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1107         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1108         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1109         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1110         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1111         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1112         PIN_CTL_TEST("Front Pin Mode", 0x14),
1113         PIN_CTL_TEST("Surround Pin Mode", 0x15),
1114         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1115         PIN_CTL_TEST("Side Pin Mode", 0x17),
1116         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1117         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1118         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1119         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1120         PIN_SRC_TEST("In-1 Pin Source", 0x18),
1121         PIN_SRC_TEST("In-2 Pin Source", 0x19),
1122         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1123         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1124         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1125         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1126         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1127         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1128         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1129         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1130         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1131         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1132         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1133         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1134         {
1135                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1136                 .name = "Channel Mode",
1137                 .info = alc_ch_mode_info,
1138                 .get = alc_ch_mode_get,
1139                 .put = alc_ch_mode_put,
1140         },
1141         { } /* end */
1142 };
1143
1144 static const struct hda_verb alc880_test_init_verbs[] = {
1145         /* Unmute inputs of 0x0c - 0x0f */
1146         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1147         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1148         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1149         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1150         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1151         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1152         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1153         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1154         /* Vol output for 0x0c-0x0f */
1155         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1156         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1157         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1158         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1159         /* Set output pins 0x14-0x17 */
1160         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1161         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1162         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1163         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1164         /* Unmute output pins 0x14-0x17 */
1165         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1166         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1167         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1168         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1169         /* Set input pins 0x18-0x1c */
1170         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1171         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1172         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1173         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1174         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1175         /* Mute input pins 0x18-0x1b */
1176         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1177         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1178         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1179         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1180         /* ADC set up */
1181         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1182         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1183         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1184         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1185         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1186         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1187         /* Analog input/passthru */
1188         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1189         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1190         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1191         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1192         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1193         { }
1194 };
1195 #endif
1196
1197 /*
1198  */
1199
1200 static const char * const alc880_models[ALC880_MODEL_LAST] = {
1201         [ALC880_3ST]            = "3stack",
1202         [ALC880_TCL_S700]       = "tcl",
1203         [ALC880_3ST_DIG]        = "3stack-digout",
1204         [ALC880_CLEVO]          = "clevo",
1205         [ALC880_5ST]            = "5stack",
1206         [ALC880_5ST_DIG]        = "5stack-digout",
1207         [ALC880_W810]           = "w810",
1208         [ALC880_Z71V]           = "z71v",
1209         [ALC880_6ST]            = "6stack",
1210         [ALC880_6ST_DIG]        = "6stack-digout",
1211         [ALC880_ASUS]           = "asus",
1212         [ALC880_ASUS_W1V]       = "asus-w1v",
1213         [ALC880_ASUS_DIG]       = "asus-dig",
1214         [ALC880_ASUS_DIG2]      = "asus-dig2",
1215         [ALC880_UNIWILL_DIG]    = "uniwill",
1216         [ALC880_UNIWILL_P53]    = "uniwill-p53",
1217         [ALC880_FUJITSU]        = "fujitsu",
1218         [ALC880_F1734]          = "F1734",
1219 #ifdef CONFIG_SND_DEBUG
1220         [ALC880_TEST]           = "test",
1221 #endif
1222         [ALC880_AUTO]           = "auto",
1223 };
1224
1225 static const struct snd_pci_quirk alc880_cfg_tbl[] = {
1226         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
1227         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
1228         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
1229         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
1230         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
1231         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
1232         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
1233         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
1234         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
1235         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
1236         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
1237         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
1238         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
1239         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
1240         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
1241         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
1242         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
1243         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
1244         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
1245         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
1246         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
1247         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
1248         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
1249         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
1250         SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
1251         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
1252         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
1253         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
1254         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
1255         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
1256         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
1257         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
1258         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
1259         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
1260         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
1261         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
1262         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
1263         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
1264         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
1265         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
1266         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
1267         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
1268         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
1269         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
1270         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
1271         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1272         SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
1273         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
1274         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
1275         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
1276         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
1277         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
1278         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
1279         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
1280         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
1281         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
1282         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
1283         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
1284         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
1285         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
1286         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
1287         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
1288         /* default Intel */
1289         SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
1290         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
1291         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1292         {}
1293 };
1294
1295 /*
1296  * ALC880 codec presets
1297  */
1298 static const struct alc_config_preset alc880_presets[] = {
1299         [ALC880_3ST] = {
1300                 .mixers = { alc880_three_stack_mixer },
1301                 .init_verbs = { alc880_volume_init_verbs,
1302                                 alc880_pin_3stack_init_verbs },
1303                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1304                 .dac_nids = alc880_dac_nids,
1305                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1306                 .channel_mode = alc880_threestack_modes,
1307                 .need_dac_fix = 1,
1308                 .input_mux = &alc880_capture_source,
1309         },
1310         [ALC880_3ST_DIG] = {
1311                 .mixers = { alc880_three_stack_mixer },
1312                 .init_verbs = { alc880_volume_init_verbs,
1313                                 alc880_pin_3stack_init_verbs },
1314                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1315                 .dac_nids = alc880_dac_nids,
1316                 .dig_out_nid = ALC880_DIGOUT_NID,
1317                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1318                 .channel_mode = alc880_threestack_modes,
1319                 .need_dac_fix = 1,
1320                 .input_mux = &alc880_capture_source,
1321         },
1322         [ALC880_TCL_S700] = {
1323                 .mixers = { alc880_tcl_s700_mixer },
1324                 .init_verbs = { alc880_volume_init_verbs,
1325                                 alc880_pin_tcl_S700_init_verbs,
1326                                 alc880_gpio2_init_verbs },
1327                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1328                 .dac_nids = alc880_dac_nids,
1329                 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
1330                 .num_adc_nids = 1, /* single ADC */
1331                 .hp_nid = 0x03,
1332                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1333                 .channel_mode = alc880_2_jack_modes,
1334                 .input_mux = &alc880_capture_source,
1335         },
1336         [ALC880_5ST] = {
1337                 .mixers = { alc880_three_stack_mixer,
1338                             alc880_five_stack_mixer},
1339                 .init_verbs = { alc880_volume_init_verbs,
1340                                 alc880_pin_5stack_init_verbs },
1341                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1342                 .dac_nids = alc880_dac_nids,
1343                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1344                 .channel_mode = alc880_fivestack_modes,
1345                 .input_mux = &alc880_capture_source,
1346         },
1347         [ALC880_5ST_DIG] = {
1348                 .mixers = { alc880_three_stack_mixer,
1349                             alc880_five_stack_mixer },
1350                 .init_verbs = { alc880_volume_init_verbs,
1351                                 alc880_pin_5stack_init_verbs },
1352                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1353                 .dac_nids = alc880_dac_nids,
1354                 .dig_out_nid = ALC880_DIGOUT_NID,
1355                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1356                 .channel_mode = alc880_fivestack_modes,
1357                 .input_mux = &alc880_capture_source,
1358         },
1359         [ALC880_6ST] = {
1360                 .mixers = { alc880_six_stack_mixer },
1361                 .init_verbs = { alc880_volume_init_verbs,
1362                                 alc880_pin_6stack_init_verbs },
1363                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1364                 .dac_nids = alc880_6st_dac_nids,
1365                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1366                 .channel_mode = alc880_sixstack_modes,
1367                 .input_mux = &alc880_6stack_capture_source,
1368         },
1369         [ALC880_6ST_DIG] = {
1370                 .mixers = { alc880_six_stack_mixer },
1371                 .init_verbs = { alc880_volume_init_verbs,
1372                                 alc880_pin_6stack_init_verbs },
1373                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1374                 .dac_nids = alc880_6st_dac_nids,
1375                 .dig_out_nid = ALC880_DIGOUT_NID,
1376                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1377                 .channel_mode = alc880_sixstack_modes,
1378                 .input_mux = &alc880_6stack_capture_source,
1379         },
1380         [ALC880_W810] = {
1381                 .mixers = { alc880_w810_base_mixer },
1382                 .init_verbs = { alc880_volume_init_verbs,
1383                                 alc880_pin_w810_init_verbs,
1384                                 alc880_gpio2_init_verbs },
1385                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1386                 .dac_nids = alc880_w810_dac_nids,
1387                 .dig_out_nid = ALC880_DIGOUT_NID,
1388                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1389                 .channel_mode = alc880_w810_modes,
1390                 .input_mux = &alc880_capture_source,
1391         },
1392         [ALC880_Z71V] = {
1393                 .mixers = { alc880_z71v_mixer },
1394                 .init_verbs = { alc880_volume_init_verbs,
1395                                 alc880_pin_z71v_init_verbs },
1396                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1397                 .dac_nids = alc880_z71v_dac_nids,
1398                 .dig_out_nid = ALC880_DIGOUT_NID,
1399                 .hp_nid = 0x03,
1400                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1401                 .channel_mode = alc880_2_jack_modes,
1402                 .input_mux = &alc880_capture_source,
1403         },
1404         [ALC880_F1734] = {
1405                 .mixers = { alc880_f1734_mixer },
1406                 .init_verbs = { alc880_volume_init_verbs,
1407                                 alc880_pin_f1734_init_verbs },
1408                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
1409                 .dac_nids = alc880_f1734_dac_nids,
1410                 .hp_nid = 0x02,
1411                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1412                 .channel_mode = alc880_2_jack_modes,
1413                 .input_mux = &alc880_f1734_capture_source,
1414                 .unsol_event = alc880_uniwill_p53_unsol_event,
1415                 .setup = alc880_uniwill_p53_setup,
1416                 .init_hook = alc_hp_automute,
1417         },
1418         [ALC880_ASUS] = {
1419                 .mixers = { alc880_asus_mixer },
1420                 .init_verbs = { alc880_volume_init_verbs,
1421                                 alc880_pin_asus_init_verbs,
1422                                 alc880_gpio1_init_verbs },
1423                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1424                 .dac_nids = alc880_asus_dac_nids,
1425                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1426                 .channel_mode = alc880_asus_modes,
1427                 .need_dac_fix = 1,
1428                 .input_mux = &alc880_capture_source,
1429         },
1430         [ALC880_ASUS_DIG] = {
1431                 .mixers = { alc880_asus_mixer },
1432                 .init_verbs = { alc880_volume_init_verbs,
1433                                 alc880_pin_asus_init_verbs,
1434                                 alc880_gpio1_init_verbs },
1435                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1436                 .dac_nids = alc880_asus_dac_nids,
1437                 .dig_out_nid = ALC880_DIGOUT_NID,
1438                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1439                 .channel_mode = alc880_asus_modes,
1440                 .need_dac_fix = 1,
1441                 .input_mux = &alc880_capture_source,
1442         },
1443         [ALC880_ASUS_DIG2] = {
1444                 .mixers = { alc880_asus_mixer },
1445                 .init_verbs = { alc880_volume_init_verbs,
1446                                 alc880_pin_asus_init_verbs,
1447                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
1448                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1449                 .dac_nids = alc880_asus_dac_nids,
1450                 .dig_out_nid = ALC880_DIGOUT_NID,
1451                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1452                 .channel_mode = alc880_asus_modes,
1453                 .need_dac_fix = 1,
1454                 .input_mux = &alc880_capture_source,
1455         },
1456         [ALC880_ASUS_W1V] = {
1457                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
1458                 .init_verbs = { alc880_volume_init_verbs,
1459                                 alc880_pin_asus_init_verbs,
1460                                 alc880_gpio1_init_verbs },
1461                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1462                 .dac_nids = alc880_asus_dac_nids,
1463                 .dig_out_nid = ALC880_DIGOUT_NID,
1464                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1465                 .channel_mode = alc880_asus_modes,
1466                 .need_dac_fix = 1,
1467                 .input_mux = &alc880_capture_source,
1468         },
1469         [ALC880_UNIWILL_DIG] = {
1470                 .mixers = { alc880_asus_mixer },
1471                 .init_verbs = { alc880_volume_init_verbs,
1472                                 alc880_pin_asus_init_verbs },
1473                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1474                 .dac_nids = alc880_asus_dac_nids,
1475                 .dig_out_nid = ALC880_DIGOUT_NID,
1476                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1477                 .channel_mode = alc880_asus_modes,
1478                 .need_dac_fix = 1,
1479                 .input_mux = &alc880_capture_source,
1480         },
1481         [ALC880_UNIWILL] = {
1482                 .mixers = { alc880_uniwill_mixer },
1483                 .init_verbs = { alc880_volume_init_verbs,
1484                                 alc880_uniwill_init_verbs },
1485                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1486                 .dac_nids = alc880_asus_dac_nids,
1487                 .dig_out_nid = ALC880_DIGOUT_NID,
1488                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1489                 .channel_mode = alc880_threestack_modes,
1490                 .need_dac_fix = 1,
1491                 .input_mux = &alc880_capture_source,
1492                 .unsol_event = alc880_uniwill_unsol_event,
1493                 .setup = alc880_uniwill_setup,
1494                 .init_hook = alc880_uniwill_init_hook,
1495         },
1496         [ALC880_UNIWILL_P53] = {
1497                 .mixers = { alc880_uniwill_p53_mixer },
1498                 .init_verbs = { alc880_volume_init_verbs,
1499                                 alc880_uniwill_p53_init_verbs },
1500                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1501                 .dac_nids = alc880_asus_dac_nids,
1502                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1503                 .channel_mode = alc880_threestack_modes,
1504                 .input_mux = &alc880_capture_source,
1505                 .unsol_event = alc880_uniwill_p53_unsol_event,
1506                 .setup = alc880_uniwill_p53_setup,
1507                 .init_hook = alc_hp_automute,
1508         },
1509         [ALC880_FUJITSU] = {
1510                 .mixers = { alc880_fujitsu_mixer },
1511                 .init_verbs = { alc880_volume_init_verbs,
1512                                 alc880_uniwill_p53_init_verbs,
1513                                 alc880_beep_init_verbs },
1514                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1515                 .dac_nids = alc880_dac_nids,
1516                 .dig_out_nid = ALC880_DIGOUT_NID,
1517                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1518                 .channel_mode = alc880_2_jack_modes,
1519                 .input_mux = &alc880_capture_source,
1520                 .unsol_event = alc880_uniwill_p53_unsol_event,
1521                 .setup = alc880_uniwill_p53_setup,
1522                 .init_hook = alc_hp_automute,
1523         },
1524         [ALC880_CLEVO] = {
1525                 .mixers = { alc880_three_stack_mixer },
1526                 .init_verbs = { alc880_volume_init_verbs,
1527                                 alc880_pin_clevo_init_verbs },
1528                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1529                 .dac_nids = alc880_dac_nids,
1530                 .hp_nid = 0x03,
1531                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1532                 .channel_mode = alc880_threestack_modes,
1533                 .need_dac_fix = 1,
1534                 .input_mux = &alc880_capture_source,
1535         },
1536 #ifdef CONFIG_SND_DEBUG
1537         [ALC880_TEST] = {
1538                 .mixers = { alc880_test_mixer },
1539                 .init_verbs = { alc880_test_init_verbs },
1540                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
1541                 .dac_nids = alc880_test_dac_nids,
1542                 .dig_out_nid = ALC880_DIGOUT_NID,
1543                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
1544                 .channel_mode = alc880_test_modes,
1545                 .input_mux = &alc880_test_capture_source,
1546         },
1547 #endif
1548 };
1549