aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /sound/pci
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/alc260_quirks.c1272
-rw-r--r--sound/pci/hda/alc262_quirks.c1353
-rw-r--r--sound/pci/hda/alc268_quirks.c636
-rw-r--r--sound/pci/hda/alc269_quirks.c688
-rw-r--r--sound/pci/hda/alc662_quirks.c1408
-rw-r--r--sound/pci/hda/alc680_quirks.c222
-rw-r--r--sound/pci/hda/alc861_quirks.c725
-rw-r--r--sound/pci/hda/alc861vd_quirks.c605
-rw-r--r--sound/pci/hda/alc880_quirks.c1898
-rw-r--r--sound/pci/hda/alc882_quirks.c3755
-rw-r--r--sound/pci/hda/alc_quirks.c467
11 files changed, 13029 insertions, 0 deletions
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
new file mode 100644
index 00000000000..21ec2cb100b
--- /dev/null
+++ b/sound/pci/hda/alc260_quirks.c
@@ -0,0 +1,1272 @@
1/*
2 * ALC260 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC260 models */
7enum {
8 ALC260_AUTO,
9 ALC260_BASIC,
10 ALC260_HP,
11 ALC260_HP_DC7600,
12 ALC260_HP_3013,
13 ALC260_FUJITSU_S702X,
14 ALC260_ACER,
15 ALC260_WILL,
16 ALC260_REPLACER_672V,
17 ALC260_FAVORIT100,
18#ifdef CONFIG_SND_DEBUG
19 ALC260_TEST,
20#endif
21 ALC260_MODEL_LAST /* last tag */
22};
23
24static const hda_nid_t alc260_dac_nids[1] = {
25 /* front */
26 0x02,
27};
28
29static const hda_nid_t alc260_adc_nids[1] = {
30 /* ADC0 */
31 0x04,
32};
33
34static const hda_nid_t alc260_adc_nids_alt[1] = {
35 /* ADC1 */
36 0x05,
37};
38
39/* NIDs used when simultaneous access to both ADCs makes sense. Note that
40 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
41 */
42static const hda_nid_t alc260_dual_adc_nids[2] = {
43 /* ADC0, ADC1 */
44 0x04, 0x05
45};
46
47#define ALC260_DIGOUT_NID 0x03
48#define ALC260_DIGIN_NID 0x06
49
50static const struct hda_input_mux alc260_capture_source = {
51 .num_items = 4,
52 .items = {
53 { "Mic", 0x0 },
54 { "Front Mic", 0x1 },
55 { "Line", 0x2 },
56 { "CD", 0x4 },
57 },
58};
59
60/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
61 * headphone jack and the internal CD lines since these are the only pins at
62 * which audio can appear. For flexibility, also allow the option of
63 * recording the mixer output on the second ADC (ADC0 doesn't have a
64 * connection to the mixer output).
65 */
66static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
67 {
68 .num_items = 3,
69 .items = {
70 { "Mic/Line", 0x0 },
71 { "CD", 0x4 },
72 { "Headphone", 0x2 },
73 },
74 },
75 {
76 .num_items = 4,
77 .items = {
78 { "Mic/Line", 0x0 },
79 { "CD", 0x4 },
80 { "Headphone", 0x2 },
81 { "Mixer", 0x5 },
82 },
83 },
84
85};
86
87/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
88 * the Fujitsu S702x, but jacks are marked differently.
89 */
90static const struct hda_input_mux alc260_acer_capture_sources[2] = {
91 {
92 .num_items = 4,
93 .items = {
94 { "Mic", 0x0 },
95 { "Line", 0x2 },
96 { "CD", 0x4 },
97 { "Headphone", 0x5 },
98 },
99 },
100 {
101 .num_items = 5,
102 .items = {
103 { "Mic", 0x0 },
104 { "Line", 0x2 },
105 { "CD", 0x4 },
106 { "Headphone", 0x6 },
107 { "Mixer", 0x5 },
108 },
109 },
110};
111
112/* Maxdata Favorit 100XS */
113static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
114 {
115 .num_items = 2,
116 .items = {
117 { "Line/Mic", 0x0 },
118 { "CD", 0x4 },
119 },
120 },
121 {
122 .num_items = 3,
123 .items = {
124 { "Line/Mic", 0x0 },
125 { "CD", 0x4 },
126 { "Mixer", 0x5 },
127 },
128 },
129};
130
131/*
132 * This is just place-holder, so there's something for alc_build_pcms to look
133 * at when it calculates the maximum number of channels. ALC260 has no mixer
134 * element which allows changing the channel mode, so the verb list is
135 * never used.
136 */
137static const struct hda_channel_mode alc260_modes[1] = {
138 { 2, NULL },
139};
140
141
142/* Mixer combinations
143 *
144 * basic: base_output + input + pc_beep + capture
145 * HP: base_output + input + capture_alt
146 * HP_3013: hp_3013 + input + capture
147 * fujitsu: fujitsu + capture
148 * acer: acer + capture
149 */
150
151static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
152 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
153 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
154 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
155 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
156 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
157 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
158 { } /* end */
159};
160
161static const struct snd_kcontrol_new alc260_input_mixer[] = {
162 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
163 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
164 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
165 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
168 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
169 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
170 { } /* end */
171};
172
173/* update HP, line and mono out pins according to the master switch */
174static void alc260_hp_master_update(struct hda_codec *codec)
175{
176 update_speakers(codec);
177}
178
179static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
181{
182 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
183 struct alc_spec *spec = codec->spec;
184 *ucontrol->value.integer.value = !spec->master_mute;
185 return 0;
186}
187
188static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
189 struct snd_ctl_elem_value *ucontrol)
190{
191 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
192 struct alc_spec *spec = codec->spec;
193 int val = !*ucontrol->value.integer.value;
194
195 if (val == spec->master_mute)
196 return 0;
197 spec->master_mute = val;
198 alc260_hp_master_update(codec);
199 return 1;
200}
201
202static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
203 {
204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
205 .name = "Master Playback Switch",
206 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
207 .info = snd_ctl_boolean_mono_info,
208 .get = alc260_hp_master_sw_get,
209 .put = alc260_hp_master_sw_put,
210 },
211 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
212 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
214 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
215 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
216 HDA_OUTPUT),
217 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
218 { } /* end */
219};
220
221static const struct hda_verb alc260_hp_unsol_verbs[] = {
222 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
223 {},
224};
225
226static void alc260_hp_setup(struct hda_codec *codec)
227{
228 struct alc_spec *spec = codec->spec;
229
230 spec->autocfg.hp_pins[0] = 0x0f;
231 spec->autocfg.speaker_pins[0] = 0x10;
232 spec->autocfg.speaker_pins[1] = 0x11;
233 spec->automute = 1;
234 spec->automute_mode = ALC_AUTOMUTE_PIN;
235}
236
237static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
238 {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Master Playback Switch",
241 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
242 .info = snd_ctl_boolean_mono_info,
243 .get = alc260_hp_master_sw_get,
244 .put = alc260_hp_master_sw_put,
245 },
246 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
247 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
248 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
249 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
250 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
252 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
253 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
254 { } /* end */
255};
256
257static void alc260_hp_3013_setup(struct hda_codec *codec)
258{
259 struct alc_spec *spec = codec->spec;
260
261 spec->autocfg.hp_pins[0] = 0x15;
262 spec->autocfg.speaker_pins[0] = 0x10;
263 spec->autocfg.speaker_pins[1] = 0x11;
264 spec->automute = 1;
265 spec->automute_mode = ALC_AUTOMUTE_PIN;
266}
267
268static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
269 .ops = &snd_hda_bind_vol,
270 .values = {
271 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
272 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
273 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
274 0
275 },
276};
277
278static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
279 .ops = &snd_hda_bind_sw,
280 .values = {
281 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
282 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
283 0
284 },
285};
286
287static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
288 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
289 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
290 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
292 { } /* end */
293};
294
295static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
296 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
297 {},
298};
299
300static void alc260_hp_3012_setup(struct hda_codec *codec)
301{
302 struct alc_spec *spec = codec->spec;
303
304 spec->autocfg.hp_pins[0] = 0x10;
305 spec->autocfg.speaker_pins[0] = 0x0f;
306 spec->autocfg.speaker_pins[1] = 0x11;
307 spec->autocfg.speaker_pins[2] = 0x15;
308 spec->automute = 1;
309 spec->automute_mode = ALC_AUTOMUTE_PIN;
310}
311
312/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
313 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
314 */
315static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
316 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
317 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
318 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
319 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
320 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
321 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
322 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
323 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
324 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
325 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
326 { } /* end */
327};
328
329/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
330 * versions of the ALC260 don't act on requests to enable mic bias from NID
331 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
332 * datasheet doesn't mention this restriction. At this stage it's not clear
333 * whether this behaviour is intentional or is a hardware bug in chip
334 * revisions available in early 2006. Therefore for now allow the
335 * "Headphone Jack Mode" control to span all choices, but if it turns out
336 * that the lack of mic bias for this NID is intentional we could change the
337 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
338 *
339 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
340 * don't appear to make the mic bias available from the "line" jack, even
341 * though the NID used for this jack (0x14) can supply it. The theory is
342 * that perhaps Acer have included blocking capacitors between the ALC260
343 * and the output jack. If this turns out to be the case for all such
344 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
345 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
346 *
347 * The C20x Tablet series have a mono internal speaker which is controlled
348 * via the chip's Mono sum widget and pin complex, so include the necessary
349 * controls for such models. On models without a "mono speaker" the control
350 * won't do anything.
351 */
352static const struct snd_kcontrol_new alc260_acer_mixer[] = {
353 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
354 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
355 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
356 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
357 HDA_OUTPUT),
358 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
359 HDA_INPUT),
360 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
361 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
363 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
364 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
365 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
366 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
367 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
368 { } /* end */
369};
370
371/* Maxdata Favorit 100XS: one output and one input (0x12) jack
372 */
373static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
374 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
375 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
376 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
377 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
378 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
379 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
380 { } /* end */
381};
382
383/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
384 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
385 */
386static const struct snd_kcontrol_new alc260_will_mixer[] = {
387 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
388 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
390 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
391 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
392 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
393 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
394 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
395 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
396 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
397 { } /* end */
398};
399
400/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
401 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
402 */
403static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
404 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
405 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
407 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
408 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
409 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
410 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
411 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
412 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
413 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
414 { } /* end */
415};
416
417/*
418 * initialization verbs
419 */
420static const struct hda_verb alc260_init_verbs[] = {
421 /* Line In pin widget for input */
422 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
423 /* CD pin widget for input */
424 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
425 /* Mic1 (rear panel) pin widget for input and vref at 80% */
426 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
427 /* Mic2 (front panel) pin widget for input and vref at 80% */
428 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
429 /* LINE-2 is used for line-out in rear */
430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
431 /* select line-out */
432 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
433 /* LINE-OUT pin */
434 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
435 /* enable HP */
436 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
437 /* enable Mono */
438 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
439 /* mute capture amp left and right */
440 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
441 /* set connection select to line in (default select for this ADC) */
442 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
443 /* mute capture amp left and right */
444 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
445 /* set connection select to line in (default select for this ADC) */
446 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
447 /* set vol=0 Line-Out mixer amp left and right */
448 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
449 /* unmute pin widget amp left and right (no gain on this amp) */
450 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
451 /* set vol=0 HP mixer amp left and right */
452 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
453 /* unmute pin widget amp left and right (no gain on this amp) */
454 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
455 /* set vol=0 Mono mixer amp left and right */
456 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
457 /* unmute pin widget amp left and right (no gain on this amp) */
458 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
459 /* unmute LINE-2 out pin */
460 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
461 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
462 * Line In 2 = 0x03
463 */
464 /* mute analog inputs */
465 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
466 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
467 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
470 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
471 /* mute Front out path */
472 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
473 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
474 /* mute Headphone out path */
475 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
476 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
477 /* mute Mono out path */
478 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
479 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
480 { }
481};
482
483#if 0 /* should be identical with alc260_init_verbs? */
484static const struct hda_verb alc260_hp_init_verbs[] = {
485 /* Headphone and output */
486 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
487 /* mono output */
488 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
489 /* Mic1 (rear panel) pin widget for input and vref at 80% */
490 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
491 /* Mic2 (front panel) pin widget for input and vref at 80% */
492 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
493 /* Line In pin widget for input */
494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
495 /* Line-2 pin widget for output */
496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
497 /* CD pin widget for input */
498 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
499 /* unmute amp left and right */
500 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
501 /* set connection select to line in (default select for this ADC) */
502 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
503 /* unmute Line-Out mixer amp left and right (volume = 0) */
504 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
505 /* mute pin widget amp left and right (no gain on this amp) */
506 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
507 /* unmute HP mixer amp left and right (volume = 0) */
508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
509 /* mute pin widget amp left and right (no gain on this amp) */
510 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
511 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
512 * Line In 2 = 0x03
513 */
514 /* mute analog inputs */
515 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
518 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
520 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
521 /* Unmute Front out path */
522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
523 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
524 /* Unmute Headphone out path */
525 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
526 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
527 /* Unmute Mono out path */
528 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
529 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
530 { }
531};
532#endif
533
534static const struct hda_verb alc260_hp_3013_init_verbs[] = {
535 /* Line out and output */
536 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
537 /* mono output */
538 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
539 /* Mic1 (rear panel) pin widget for input and vref at 80% */
540 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
541 /* Mic2 (front panel) pin widget for input and vref at 80% */
542 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
543 /* Line In pin widget for input */
544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
545 /* Headphone pin widget for output */
546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
547 /* CD pin widget for input */
548 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
549 /* unmute amp left and right */
550 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
551 /* set connection select to line in (default select for this ADC) */
552 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
553 /* unmute Line-Out mixer amp left and right (volume = 0) */
554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
555 /* mute pin widget amp left and right (no gain on this amp) */
556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
557 /* unmute HP mixer amp left and right (volume = 0) */
558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
559 /* mute pin widget amp left and right (no gain on this amp) */
560 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
561 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
562 * Line In 2 = 0x03
563 */
564 /* mute analog inputs */
565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
570 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
571 /* Unmute Front out path */
572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
573 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
574 /* Unmute Headphone out path */
575 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
576 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
577 /* Unmute Mono out path */
578 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
579 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
580 { }
581};
582
583/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
584 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
585 * audio = 0x16, internal speaker = 0x10.
586 */
587static const struct hda_verb alc260_fujitsu_init_verbs[] = {
588 /* Disable all GPIOs */
589 {0x01, AC_VERB_SET_GPIO_MASK, 0},
590 /* Internal speaker is connected to headphone pin */
591 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
592 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
593 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
594 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
595 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
596 /* Ensure all other unused pins are disabled and muted. */
597 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
598 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
599 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
600 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
601 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
602 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
605
606 /* Disable digital (SPDIF) pins */
607 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
608 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
609
610 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
611 * when acting as an output.
612 */
613 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
614
615 /* Start with output sum widgets muted and their output gains at min */
616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
619 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
622 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
623 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
624 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
625
626 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
627 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
628 /* Unmute Line1 pin widget output buffer since it starts as an output.
629 * If the pin mode is changed by the user the pin mode control will
630 * take care of enabling the pin's input/output buffers as needed.
631 * Therefore there's no need to enable the input buffer at this
632 * stage.
633 */
634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
635 /* Unmute input buffer of pin widget used for Line-in (no equiv
636 * mixer ctrl)
637 */
638 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
639
640 /* Mute capture amp left and right */
641 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
642 /* Set ADC connection select to match default mixer setting - line
643 * in (on mic1 pin)
644 */
645 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
646
647 /* Do the same for the second ADC: mute capture input amp and
648 * set ADC connection to line in (on mic1 pin)
649 */
650 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
651 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
652
653 /* Mute all inputs to mixer widget (even unconnected ones) */
654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
656 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
657 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
658 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
659 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
660 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
662
663 { }
664};
665
666/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
667 * similar laptops (adapted from Fujitsu init verbs).
668 */
669static const struct hda_verb alc260_acer_init_verbs[] = {
670 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
671 * the headphone jack. Turn this on and rely on the standard mute
672 * methods whenever the user wants to turn these outputs off.
673 */
674 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
675 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
676 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
677 /* Internal speaker/Headphone jack is connected to Line-out pin */
678 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 /* Internal microphone/Mic jack is connected to Mic1 pin */
680 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
681 /* Line In jack is connected to Line1 pin */
682 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
683 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
684 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
685 /* Ensure all other unused pins are disabled and muted. */
686 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
687 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
688 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
689 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
690 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
691 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
692 /* Disable digital (SPDIF) pins */
693 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
694 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
695
696 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
697 * bus when acting as outputs.
698 */
699 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
700 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
701
702 /* Start with output sum widgets muted and their output gains at min */
703 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
704 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
705 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
706 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
707 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
708 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
709 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
710 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
711 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
712
713 /* Unmute Line-out pin widget amp left and right
714 * (no equiv mixer ctrl)
715 */
716 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
717 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
718 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
719 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
720 * inputs. If the pin mode is changed by the user the pin mode control
721 * will take care of enabling the pin's input/output buffers as needed.
722 * Therefore there's no need to enable the input buffer at this
723 * stage.
724 */
725 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
727
728 /* Mute capture amp left and right */
729 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
730 /* Set ADC connection select to match default mixer setting - mic
731 * (on mic1 pin)
732 */
733 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
734
735 /* Do similar with the second ADC: mute capture input amp and
736 * set ADC connection to mic to match ALSA's default state.
737 */
738 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
739 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
740
741 /* Mute all inputs to mixer widget (even unconnected ones) */
742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
748 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
750
751 { }
752};
753
754/* Initialisation sequence for Maxdata Favorit 100XS
755 * (adapted from Acer init verbs).
756 */
757static const struct hda_verb alc260_favorit100_init_verbs[] = {
758 /* GPIO 0 enables the output jack.
759 * Turn this on and rely on the standard mute
760 * methods whenever the user wants to turn these outputs off.
761 */
762 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
763 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
764 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
765 /* Line/Mic input jack is connected to Mic1 pin */
766 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
767 /* Ensure all other unused pins are disabled and muted. */
768 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
769 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
770 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
771 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
772 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
773 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
778 /* Disable digital (SPDIF) pins */
779 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
780 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
781
782 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
783 * bus when acting as outputs.
784 */
785 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
786 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
787
788 /* Start with output sum widgets muted and their output gains at min */
789 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
791 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
795 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
796 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
797 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
798
799 /* Unmute Line-out pin widget amp left and right
800 * (no equiv mixer ctrl)
801 */
802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
803 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
804 * inputs. If the pin mode is changed by the user the pin mode control
805 * will take care of enabling the pin's input/output buffers as needed.
806 * Therefore there's no need to enable the input buffer at this
807 * stage.
808 */
809 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
810
811 /* Mute capture amp left and right */
812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
813 /* Set ADC connection select to match default mixer setting - mic
814 * (on mic1 pin)
815 */
816 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
817
818 /* Do similar with the second ADC: mute capture input amp and
819 * set ADC connection to mic to match ALSA's default state.
820 */
821 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
822 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
823
824 /* Mute all inputs to mixer widget (even unconnected ones) */
825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
833
834 { }
835};
836
837static const struct hda_verb alc260_will_verbs[] = {
838 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
839 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
840 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
841 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
842 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
843 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
844 {}
845};
846
847static const struct hda_verb alc260_replacer_672v_verbs[] = {
848 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
849 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
850 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
851
852 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
853 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
854 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
855
856 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
857 {}
858};
859
860/* toggle speaker-output according to the hp-jack state */
861static void alc260_replacer_672v_automute(struct hda_codec *codec)
862{
863 unsigned int present;
864
865 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
866 present = snd_hda_jack_detect(codec, 0x0f);
867 if (present) {
868 snd_hda_codec_write_cache(codec, 0x01, 0,
869 AC_VERB_SET_GPIO_DATA, 1);
870 snd_hda_codec_write_cache(codec, 0x0f, 0,
871 AC_VERB_SET_PIN_WIDGET_CONTROL,
872 PIN_HP);
873 } else {
874 snd_hda_codec_write_cache(codec, 0x01, 0,
875 AC_VERB_SET_GPIO_DATA, 0);
876 snd_hda_codec_write_cache(codec, 0x0f, 0,
877 AC_VERB_SET_PIN_WIDGET_CONTROL,
878 PIN_OUT);
879 }
880}
881
882static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
883 unsigned int res)
884{
885 if ((res >> 26) == ALC_HP_EVENT)
886 alc260_replacer_672v_automute(codec);
887}
888
889static const struct hda_verb alc260_hp_dc7600_verbs[] = {
890 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
891 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
892 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
893 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
894 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
896 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
897 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
898 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
899 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
900 {}
901};
902
903/* Test configuration for debugging, modelled after the ALC880 test
904 * configuration.
905 */
906#ifdef CONFIG_SND_DEBUG
907static const hda_nid_t alc260_test_dac_nids[1] = {
908 0x02,
909};
910static const hda_nid_t alc260_test_adc_nids[2] = {
911 0x04, 0x05,
912};
913/* For testing the ALC260, each input MUX needs its own definition since
914 * the signal assignments are different. This assumes that the first ADC
915 * is NID 0x04.
916 */
917static const struct hda_input_mux alc260_test_capture_sources[2] = {
918 {
919 .num_items = 7,
920 .items = {
921 { "MIC1 pin", 0x0 },
922 { "MIC2 pin", 0x1 },
923 { "LINE1 pin", 0x2 },
924 { "LINE2 pin", 0x3 },
925 { "CD pin", 0x4 },
926 { "LINE-OUT pin", 0x5 },
927 { "HP-OUT pin", 0x6 },
928 },
929 },
930 {
931 .num_items = 8,
932 .items = {
933 { "MIC1 pin", 0x0 },
934 { "MIC2 pin", 0x1 },
935 { "LINE1 pin", 0x2 },
936 { "LINE2 pin", 0x3 },
937 { "CD pin", 0x4 },
938 { "Mixer", 0x5 },
939 { "LINE-OUT pin", 0x6 },
940 { "HP-OUT pin", 0x7 },
941 },
942 },
943};
944static const struct snd_kcontrol_new alc260_test_mixer[] = {
945 /* Output driver widgets */
946 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
947 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
948 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
949 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
950 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
951 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
952
953 /* Modes for retasking pin widgets
954 * Note: the ALC260 doesn't seem to act on requests to enable mic
955 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
956 * mention this restriction. At this stage it's not clear whether
957 * this behaviour is intentional or is a hardware bug in chip
958 * revisions available at least up until early 2006. Therefore for
959 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
960 * choices, but if it turns out that the lack of mic bias for these
961 * NIDs is intentional we could change their modes from
962 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
963 */
964 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
965 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
966 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
967 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
968 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
969 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
970
971 /* Loopback mixer controls */
972 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
973 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
974 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
975 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
976 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
977 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
978 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
979 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
980 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
981 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
982 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
983 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
984 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
985 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
986
987 /* Controls for GPIO pins, assuming they are configured as outputs */
988 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
989 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
990 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
991 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
992
993 /* Switches to allow the digital IO pins to be enabled. The datasheet
994 * is ambigious as to which NID is which; testing on laptops which
995 * make this output available should provide clarification.
996 */
997 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
998 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
999
1000 /* A switch allowing EAPD to be enabled. Some laptops seem to use
1001 * this output to turn on an external amplifier.
1002 */
1003 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
1004 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
1005
1006 { } /* end */
1007};
1008static const struct hda_verb alc260_test_init_verbs[] = {
1009 /* Enable all GPIOs as outputs with an initial value of 0 */
1010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
1011 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
1012 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
1013
1014 /* Enable retasking pins as output, initially without power amp */
1015 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1016 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1018 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1019 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1020 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1021
1022 /* Disable digital (SPDIF) pins initially, but users can enable
1023 * them via a mixer switch. In the case of SPDIF-out, this initverb
1024 * payload also sets the generation to 0, output to be in "consumer"
1025 * PCM format, copyright asserted, no pre-emphasis and no validity
1026 * control.
1027 */
1028 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
1029 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
1030
1031 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
1032 * OUT1 sum bus when acting as an output.
1033 */
1034 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
1035 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
1036 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
1037 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
1038
1039 /* Start with output sum widgets muted and their output gains at min */
1040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1041 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1042 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1043 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1044 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1045 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1046 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1047 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1048 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1049
1050 /* Unmute retasking pin widget output buffers since the default
1051 * state appears to be output. As the pin mode is changed by the
1052 * user the pin mode control will take care of enabling the pin's
1053 * input/output buffers as needed.
1054 */
1055 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1056 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1059 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1060 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1061 /* Also unmute the mono-out pin widget */
1062 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1063
1064 /* Mute capture amp left and right */
1065 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1066 /* Set ADC connection select to match default mixer setting (mic1
1067 * pin)
1068 */
1069 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
1070
1071 /* Do the same for the second ADC: mute capture input amp and
1072 * set ADC connection to mic1 pin
1073 */
1074 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1075 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
1076
1077 /* Mute all inputs to mixer widget (even unconnected ones) */
1078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1079 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1081 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1082 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1084 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1086
1087 { }
1088};
1089#endif
1090
1091/*
1092 * ALC260 configurations
1093 */
1094static const char * const alc260_models[ALC260_MODEL_LAST] = {
1095 [ALC260_BASIC] = "basic",
1096 [ALC260_HP] = "hp",
1097 [ALC260_HP_3013] = "hp-3013",
1098 [ALC260_HP_DC7600] = "hp-dc7600",
1099 [ALC260_FUJITSU_S702X] = "fujitsu",
1100 [ALC260_ACER] = "acer",
1101 [ALC260_WILL] = "will",
1102 [ALC260_REPLACER_672V] = "replacer",
1103 [ALC260_FAVORIT100] = "favorit100",
1104#ifdef CONFIG_SND_DEBUG
1105 [ALC260_TEST] = "test",
1106#endif
1107 [ALC260_AUTO] = "auto",
1108};
1109
1110static const struct snd_pci_quirk alc260_cfg_tbl[] = {
1111 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
1112 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
1113 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
1114 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
1115 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
1116 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
1117 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
1118 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
1119 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
1120 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
1121 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
1122 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
1123 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
1124 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
1125 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
1126 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
1127 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
1128 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
1129 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
1130 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
1131 {}
1132};
1133
1134static const struct alc_config_preset alc260_presets[] = {
1135 [ALC260_BASIC] = {
1136 .mixers = { alc260_base_output_mixer,
1137 alc260_input_mixer },
1138 .init_verbs = { alc260_init_verbs },
1139 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1140 .dac_nids = alc260_dac_nids,
1141 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1142 .adc_nids = alc260_dual_adc_nids,
1143 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1144 .channel_mode = alc260_modes,
1145 .input_mux = &alc260_capture_source,
1146 },
1147 [ALC260_HP] = {
1148 .mixers = { alc260_hp_output_mixer,
1149 alc260_input_mixer },
1150 .init_verbs = { alc260_init_verbs,
1151 alc260_hp_unsol_verbs },
1152 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1153 .dac_nids = alc260_dac_nids,
1154 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1155 .adc_nids = alc260_adc_nids_alt,
1156 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1157 .channel_mode = alc260_modes,
1158 .input_mux = &alc260_capture_source,
1159 .unsol_event = alc_sku_unsol_event,
1160 .setup = alc260_hp_setup,
1161 .init_hook = alc_inithook,
1162 },
1163 [ALC260_HP_DC7600] = {
1164 .mixers = { alc260_hp_dc7600_mixer,
1165 alc260_input_mixer },
1166 .init_verbs = { alc260_init_verbs,
1167 alc260_hp_dc7600_verbs },
1168 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1169 .dac_nids = alc260_dac_nids,
1170 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1171 .adc_nids = alc260_adc_nids_alt,
1172 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1173 .channel_mode = alc260_modes,
1174 .input_mux = &alc260_capture_source,
1175 .unsol_event = alc_sku_unsol_event,
1176 .setup = alc260_hp_3012_setup,
1177 .init_hook = alc_inithook,
1178 },
1179 [ALC260_HP_3013] = {
1180 .mixers = { alc260_hp_3013_mixer,
1181 alc260_input_mixer },
1182 .init_verbs = { alc260_hp_3013_init_verbs,
1183 alc260_hp_3013_unsol_verbs },
1184 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1185 .dac_nids = alc260_dac_nids,
1186 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1187 .adc_nids = alc260_adc_nids_alt,
1188 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1189 .channel_mode = alc260_modes,
1190 .input_mux = &alc260_capture_source,
1191 .unsol_event = alc_sku_unsol_event,
1192 .setup = alc260_hp_3013_setup,
1193 .init_hook = alc_inithook,
1194 },
1195 [ALC260_FUJITSU_S702X] = {
1196 .mixers = { alc260_fujitsu_mixer },
1197 .init_verbs = { alc260_fujitsu_init_verbs },
1198 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1199 .dac_nids = alc260_dac_nids,
1200 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1201 .adc_nids = alc260_dual_adc_nids,
1202 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1203 .channel_mode = alc260_modes,
1204 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
1205 .input_mux = alc260_fujitsu_capture_sources,
1206 },
1207 [ALC260_ACER] = {
1208 .mixers = { alc260_acer_mixer },
1209 .init_verbs = { alc260_acer_init_verbs },
1210 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1211 .dac_nids = alc260_dac_nids,
1212 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1213 .adc_nids = alc260_dual_adc_nids,
1214 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1215 .channel_mode = alc260_modes,
1216 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
1217 .input_mux = alc260_acer_capture_sources,
1218 },
1219 [ALC260_FAVORIT100] = {
1220 .mixers = { alc260_favorit100_mixer },
1221 .init_verbs = { alc260_favorit100_init_verbs },
1222 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1223 .dac_nids = alc260_dac_nids,
1224 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1225 .adc_nids = alc260_dual_adc_nids,
1226 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1227 .channel_mode = alc260_modes,
1228 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
1229 .input_mux = alc260_favorit100_capture_sources,
1230 },
1231 [ALC260_WILL] = {
1232 .mixers = { alc260_will_mixer },
1233 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
1234 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1235 .dac_nids = alc260_dac_nids,
1236 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
1237 .adc_nids = alc260_adc_nids,
1238 .dig_out_nid = ALC260_DIGOUT_NID,
1239 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1240 .channel_mode = alc260_modes,
1241 .input_mux = &alc260_capture_source,
1242 },
1243 [ALC260_REPLACER_672V] = {
1244 .mixers = { alc260_replacer_672v_mixer },
1245 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
1246 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1247 .dac_nids = alc260_dac_nids,
1248 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
1249 .adc_nids = alc260_adc_nids,
1250 .dig_out_nid = ALC260_DIGOUT_NID,
1251 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1252 .channel_mode = alc260_modes,
1253 .input_mux = &alc260_capture_source,
1254 .unsol_event = alc260_replacer_672v_unsol_event,
1255 .init_hook = alc260_replacer_672v_automute,
1256 },
1257#ifdef CONFIG_SND_DEBUG
1258 [ALC260_TEST] = {
1259 .mixers = { alc260_test_mixer },
1260 .init_verbs = { alc260_test_init_verbs },
1261 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
1262 .dac_nids = alc260_test_dac_nids,
1263 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
1264 .adc_nids = alc260_test_adc_nids,
1265 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1266 .channel_mode = alc260_modes,
1267 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
1268 .input_mux = alc260_test_capture_sources,
1269 },
1270#endif
1271};
1272
diff --git a/sound/pci/hda/alc262_quirks.c b/sound/pci/hda/alc262_quirks.c
new file mode 100644
index 00000000000..8d2097d7764
--- /dev/null
+++ b/sound/pci/hda/alc262_quirks.c
@@ -0,0 +1,1353 @@
1/*
2 * ALC262 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC262 models */
7enum {
8 ALC262_AUTO,
9 ALC262_BASIC,
10 ALC262_HIPPO,
11 ALC262_HIPPO_1,
12 ALC262_FUJITSU,
13 ALC262_HP_BPC,
14 ALC262_HP_BPC_D7000_WL,
15 ALC262_HP_BPC_D7000_WF,
16 ALC262_HP_TC_T5735,
17 ALC262_HP_RP5700,
18 ALC262_BENQ_ED8,
19 ALC262_SONY_ASSAMD,
20 ALC262_BENQ_T31,
21 ALC262_ULTRA,
22 ALC262_LENOVO_3000,
23 ALC262_NEC,
24 ALC262_TOSHIBA_S06,
25 ALC262_TOSHIBA_RX1,
26 ALC262_TYAN,
27 ALC262_MODEL_LAST /* last tag */
28};
29
30#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
31#define ALC262_DIGIN_NID ALC880_DIGIN_NID
32
33#define alc262_dac_nids alc260_dac_nids
34#define alc262_adc_nids alc882_adc_nids
35#define alc262_adc_nids_alt alc882_adc_nids_alt
36#define alc262_capsrc_nids alc882_capsrc_nids
37#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
38
39#define alc262_modes alc260_modes
40#define alc262_capture_source alc882_capture_source
41
42static const hda_nid_t alc262_dmic_adc_nids[1] = {
43 /* ADC0 */
44 0x09
45};
46
47static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
48
49static const struct snd_kcontrol_new alc262_base_mixer[] = {
50 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
53 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
54 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
55 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
56 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
57 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
58 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
59 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
60 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
61 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
62 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
63 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
64 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
65 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
66 { } /* end */
67};
68
69/* update HP, line and mono-out pins according to the master switch */
70#define alc262_hp_master_update alc260_hp_master_update
71
72static void alc262_hp_bpc_setup(struct hda_codec *codec)
73{
74 struct alc_spec *spec = codec->spec;
75
76 spec->autocfg.hp_pins[0] = 0x1b;
77 spec->autocfg.speaker_pins[0] = 0x16;
78 spec->automute = 1;
79 spec->automute_mode = ALC_AUTOMUTE_PIN;
80}
81
82static void alc262_hp_wildwest_setup(struct hda_codec *codec)
83{
84 struct alc_spec *spec = codec->spec;
85
86 spec->autocfg.hp_pins[0] = 0x15;
87 spec->autocfg.speaker_pins[0] = 0x16;
88 spec->automute = 1;
89 spec->automute_mode = ALC_AUTOMUTE_PIN;
90}
91
92#define alc262_hp_master_sw_get alc260_hp_master_sw_get
93#define alc262_hp_master_sw_put alc260_hp_master_sw_put
94
95#define ALC262_HP_MASTER_SWITCH \
96 { \
97 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
98 .name = "Master Playback Switch", \
99 .info = snd_ctl_boolean_mono_info, \
100 .get = alc262_hp_master_sw_get, \
101 .put = alc262_hp_master_sw_put, \
102 }, \
103 { \
104 .iface = NID_MAPPING, \
105 .name = "Master Playback Switch", \
106 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
107 }
108
109
110static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
111 ALC262_HP_MASTER_SWITCH,
112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
113 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
115 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
116 HDA_OUTPUT),
117 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
118 HDA_OUTPUT),
119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
121 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
122 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
123 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
124 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
129 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
130 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
131 { } /* end */
132};
133
134static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
135 ALC262_HP_MASTER_SWITCH,
136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
137 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
138 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
139 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
140 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
141 HDA_OUTPUT),
142 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
143 HDA_OUTPUT),
144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
147 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
148 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
149 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
150 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
151 { } /* end */
152};
153
154static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
155 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
156 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
157 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
158 { } /* end */
159};
160
161/* mute/unmute internal speaker according to the hp jack and mute state */
162static void alc262_hp_t5735_setup(struct hda_codec *codec)
163{
164 struct alc_spec *spec = codec->spec;
165
166 spec->autocfg.hp_pins[0] = 0x15;
167 spec->autocfg.speaker_pins[0] = 0x14;
168 spec->automute = 1;
169 spec->automute_mode = ALC_AUTOMUTE_PIN;
170}
171
172static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
173 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
174 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
179 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
180 { } /* end */
181};
182
183static const struct hda_verb alc262_hp_t5735_verbs[] = {
184 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
185 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
186
187 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
188 { }
189};
190
191static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
192 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
194 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
197 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
198 { } /* end */
199};
200
201static const struct hda_verb alc262_hp_rp5700_verbs[] = {
202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
203 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
206 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
207 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
212 {}
213};
214
215static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
216 .num_items = 1,
217 .items = {
218 { "Line", 0x1 },
219 },
220};
221
222/* bind hp and internal speaker mute (with plug check) as master switch */
223#define alc262_hippo_master_update alc262_hp_master_update
224#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
225#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
226
227#define ALC262_HIPPO_MASTER_SWITCH \
228 { \
229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
230 .name = "Master Playback Switch", \
231 .info = snd_ctl_boolean_mono_info, \
232 .get = alc262_hippo_master_sw_get, \
233 .put = alc262_hippo_master_sw_put, \
234 }, \
235 { \
236 .iface = NID_MAPPING, \
237 .name = "Master Playback Switch", \
238 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
239 (SUBDEV_SPEAKER(0) << 16), \
240 }
241
242static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
243 ALC262_HIPPO_MASTER_SWITCH,
244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
245 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
246 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
247 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
248 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
251 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
252 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
254 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
255 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
256 { } /* end */
257};
258
259static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
260 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
261 ALC262_HIPPO_MASTER_SWITCH,
262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
264 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
265 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
268 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
269 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
271 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272 { } /* end */
273};
274
275/* mute/unmute internal speaker according to the hp jack and mute state */
276static void alc262_hippo_setup(struct hda_codec *codec)
277{
278 struct alc_spec *spec = codec->spec;
279
280 spec->autocfg.hp_pins[0] = 0x15;
281 spec->autocfg.speaker_pins[0] = 0x14;
282 spec->automute = 1;
283 spec->automute_mode = ALC_AUTOMUTE_AMP;
284}
285
286static void alc262_hippo1_setup(struct hda_codec *codec)
287{
288 struct alc_spec *spec = codec->spec;
289
290 spec->autocfg.hp_pins[0] = 0x1b;
291 spec->autocfg.speaker_pins[0] = 0x14;
292 spec->automute = 1;
293 spec->automute_mode = ALC_AUTOMUTE_AMP;
294}
295
296
297static const struct snd_kcontrol_new alc262_sony_mixer[] = {
298 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
299 ALC262_HIPPO_MASTER_SWITCH,
300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
302 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
303 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
304 { } /* end */
305};
306
307static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
308 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
309 ALC262_HIPPO_MASTER_SWITCH,
310 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
311 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
312 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
313 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
314 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
315 { } /* end */
316};
317
318static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
319 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
320 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
321 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
322 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
323 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
324 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
327 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
328 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
329 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
330 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
331 { } /* end */
332};
333
334static const struct hda_verb alc262_tyan_verbs[] = {
335 /* Headphone automute */
336 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
337 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
339
340 /* P11 AUX_IN, white 4-pin connector */
341 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
342 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
343 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
344 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
345
346 {}
347};
348
349/* unsolicited event for HP jack sensing */
350static void alc262_tyan_setup(struct hda_codec *codec)
351{
352 struct alc_spec *spec = codec->spec;
353
354 spec->autocfg.hp_pins[0] = 0x1b;
355 spec->autocfg.speaker_pins[0] = 0x15;
356 spec->automute = 1;
357 spec->automute_mode = ALC_AUTOMUTE_AMP;
358}
359
360
361#define alc262_capture_mixer alc882_capture_mixer
362#define alc262_capture_alt_mixer alc882_capture_alt_mixer
363
364/*
365 * generic initialization of ADC, input mixers and output mixers
366 */
367static const struct hda_verb alc262_init_verbs[] = {
368 /*
369 * Unmute ADC0-2 and set the default input to mic-in
370 */
371 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
373 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
375 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
377
378 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
379 * mixer widget
380 * Note: PASD motherboards uses the Line In 2 as the input for
381 * front panel mic (mic 2)
382 */
383 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
388 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
389
390 /*
391 * Set up output mixers (0x0c - 0x0e)
392 */
393 /* set vol=0 to output mixers */
394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
397 /* set up input amps for analog loopback */
398 /* Amp Indices: DAC = 0, mixer = 1 */
399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
400 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
401 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
402 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
404 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
405
406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
407 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
408 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
409 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
410 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
411 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
412
413 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
414 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
415 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
416 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
417 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
418
419 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
420 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
421
422 /* FIXME: use matrix-type input source selection */
423 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
424 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
425 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
428 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
429 /* Input mixer2 */
430 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
431 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
433 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
434 /* Input mixer3 */
435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
439
440 { }
441};
442
443static const struct hda_verb alc262_eapd_verbs[] = {
444 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
445 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
446 { }
447};
448
449static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
450 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
451 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
452 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
453
454 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
455 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
456 {}
457};
458
459static const struct hda_verb alc262_sony_unsol_verbs[] = {
460 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
462 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
463
464 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
466 {}
467};
468
469static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
470 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
471 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
472 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
473 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
474 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
475 { } /* end */
476};
477
478static const struct hda_verb alc262_toshiba_s06_verbs[] = {
479 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
481 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
483 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
484 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
485 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
486 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
487 {}
488};
489
490static void alc262_toshiba_s06_setup(struct hda_codec *codec)
491{
492 struct alc_spec *spec = codec->spec;
493
494 spec->autocfg.hp_pins[0] = 0x15;
495 spec->autocfg.speaker_pins[0] = 0x14;
496 spec->ext_mic_pin = 0x18;
497 spec->int_mic_pin = 0x12;
498 spec->auto_mic = 1;
499 spec->automute = 1;
500 spec->automute_mode = ALC_AUTOMUTE_PIN;
501}
502
503/*
504 * nec model
505 * 0x15 = headphone
506 * 0x16 = internal speaker
507 * 0x18 = external mic
508 */
509
510static const struct snd_kcontrol_new alc262_nec_mixer[] = {
511 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
512 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
513
514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
517
518 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
520 { } /* end */
521};
522
523static const struct hda_verb alc262_nec_verbs[] = {
524 /* Unmute Speaker */
525 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
526
527 /* Headphone */
528 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
530
531 /* External mic to headphone */
532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
533 /* External mic to speaker */
534 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
535 {}
536};
537
538/*
539 * fujitsu model
540 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
541 * 0x1b = port replicator headphone out
542 */
543
544static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
545 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
547 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
549 {}
550};
551
552static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
553 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
555 {}
556};
557
558static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
559 /* Front Mic pin: input vref at 50% */
560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
561 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
562 {}
563};
564
565static const struct hda_input_mux alc262_fujitsu_capture_source = {
566 .num_items = 3,
567 .items = {
568 { "Mic", 0x0 },
569 { "Internal Mic", 0x1 },
570 { "CD", 0x4 },
571 },
572};
573
574static const struct hda_input_mux alc262_HP_capture_source = {
575 .num_items = 5,
576 .items = {
577 { "Mic", 0x0 },
578 { "Front Mic", 0x1 },
579 { "Line", 0x2 },
580 { "CD", 0x4 },
581 { "AUX IN", 0x6 },
582 },
583};
584
585static const struct hda_input_mux alc262_HP_D7000_capture_source = {
586 .num_items = 4,
587 .items = {
588 { "Mic", 0x0 },
589 { "Front Mic", 0x2 },
590 { "Line", 0x1 },
591 { "CD", 0x4 },
592 },
593};
594
595static void alc262_fujitsu_setup(struct hda_codec *codec)
596{
597 struct alc_spec *spec = codec->spec;
598
599 spec->autocfg.hp_pins[0] = 0x14;
600 spec->autocfg.hp_pins[1] = 0x1b;
601 spec->autocfg.speaker_pins[0] = 0x15;
602 spec->automute = 1;
603 spec->automute_mode = ALC_AUTOMUTE_AMP;
604}
605
606/* bind volumes of both NID 0x0c and 0x0d */
607static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
608 .ops = &snd_hda_bind_vol,
609 .values = {
610 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
611 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
612 0
613 },
614};
615
616static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
617 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
618 {
619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
620 .name = "Master Playback Switch",
621 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
622 .info = snd_ctl_boolean_mono_info,
623 .get = alc262_hp_master_sw_get,
624 .put = alc262_hp_master_sw_put,
625 },
626 {
627 .iface = NID_MAPPING,
628 .name = "Master Playback Switch",
629 .private_value = 0x1b,
630 },
631 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
632 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
633 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
636 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
637 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
638 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
639 { } /* end */
640};
641
642static void alc262_lenovo_3000_setup(struct hda_codec *codec)
643{
644 struct alc_spec *spec = codec->spec;
645
646 spec->autocfg.hp_pins[0] = 0x1b;
647 spec->autocfg.speaker_pins[0] = 0x14;
648 spec->autocfg.speaker_pins[1] = 0x16;
649 spec->automute = 1;
650 spec->automute_mode = ALC_AUTOMUTE_AMP;
651}
652
653static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
654 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
655 {
656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
657 .name = "Master Playback Switch",
658 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
659 .info = snd_ctl_boolean_mono_info,
660 .get = alc262_hp_master_sw_get,
661 .put = alc262_hp_master_sw_put,
662 },
663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
665 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
668 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
669 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
670 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
671 { } /* end */
672};
673
674static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
675 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
676 ALC262_HIPPO_MASTER_SWITCH,
677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
679 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
680 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
681 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
682 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
683 { } /* end */
684};
685
686/* additional init verbs for Benq laptops */
687static const struct hda_verb alc262_EAPD_verbs[] = {
688 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
689 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
690 {}
691};
692
693static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
694 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
695 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
696
697 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
698 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
699 {}
700};
701
702/* Samsung Q1 Ultra Vista model setup */
703static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
704 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
705 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
708 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
709 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
710 { } /* end */
711};
712
713static const struct hda_verb alc262_ultra_verbs[] = {
714 /* output mixer */
715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
718 /* speaker */
719 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
720 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
721 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
722 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
723 /* HP */
724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
727 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
728 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
729 /* internal mic */
730 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
731 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
732 /* ADC, choose mic */
733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
737 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
738 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
739 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
743 {}
744};
745
746/* mute/unmute internal speaker according to the hp jack and mute state */
747static void alc262_ultra_automute(struct hda_codec *codec)
748{
749 struct alc_spec *spec = codec->spec;
750 unsigned int mute;
751
752 mute = 0;
753 /* auto-mute only when HP is used as HP */
754 if (!spec->cur_mux[0]) {
755 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
756 if (spec->jack_present)
757 mute = HDA_AMP_MUTE;
758 }
759 /* mute/unmute internal speaker */
760 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
761 HDA_AMP_MUTE, mute);
762 /* mute/unmute HP */
763 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
764 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
765}
766
767/* unsolicited event for HP jack sensing */
768static void alc262_ultra_unsol_event(struct hda_codec *codec,
769 unsigned int res)
770{
771 if ((res >> 26) != ALC_HP_EVENT)
772 return;
773 alc262_ultra_automute(codec);
774}
775
776static const struct hda_input_mux alc262_ultra_capture_source = {
777 .num_items = 2,
778 .items = {
779 { "Mic", 0x1 },
780 { "Headphone", 0x7 },
781 },
782};
783
784static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
785 struct snd_ctl_elem_value *ucontrol)
786{
787 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
788 struct alc_spec *spec = codec->spec;
789 int ret;
790
791 ret = alc_mux_enum_put(kcontrol, ucontrol);
792 if (!ret)
793 return 0;
794 /* reprogram the HP pin as mic or HP according to the input source */
795 snd_hda_codec_write_cache(codec, 0x15, 0,
796 AC_VERB_SET_PIN_WIDGET_CONTROL,
797 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
798 alc262_ultra_automute(codec); /* mute/unmute HP */
799 return ret;
800}
801
802static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
803 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
804 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
805 {
806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
807 .name = "Capture Source",
808 .info = alc_mux_enum_info,
809 .get = alc_mux_enum_get,
810 .put = alc262_ultra_mux_enum_put,
811 },
812 {
813 .iface = NID_MAPPING,
814 .name = "Capture Source",
815 .private_value = 0x15,
816 },
817 { } /* end */
818};
819
820static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
821 /*
822 * Unmute ADC0-2 and set the default input to mic-in
823 */
824 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
826 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
828 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
829 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
830
831 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
832 * mixer widget
833 * Note: PASD motherboards uses the Line In 2 as the input for
834 * front panel mic (mic 2)
835 */
836 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
843 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
844
845 /*
846 * Set up output mixers (0x0c - 0x0e)
847 */
848 /* set vol=0 to output mixers */
849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
850 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
851 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
852
853 /* set up input amps for analog loopback */
854 /* Amp Indices: DAC = 0, mixer = 1 */
855 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
856 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
857 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
858 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
859 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
860 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
861
862 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
864 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
865
866 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
868
869 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
870 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
871
872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
873 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
874 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
877
878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
880 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
881 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
882 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
883 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
884
885
886 /* FIXME: use matrix-type input source selection */
887 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
888 /* Input mixer1: only unmute Mic */
889 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
890 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
891 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
892 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
893 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
895 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
898 /* Input mixer2 */
899 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
900 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
901 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
903 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
906 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
907 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
908 /* Input mixer3 */
909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
918
919 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
920
921 { }
922};
923
924static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
925 /*
926 * Unmute ADC0-2 and set the default input to mic-in
927 */
928 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
929 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
930 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
931 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
932 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
933 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
934
935 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
936 * mixer widget
937 * Note: PASD motherboards uses the Line In 2 as the input for front
938 * panel mic (mic 2)
939 */
940 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
941 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
942 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
943 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
944 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
945 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
946 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
949 /*
950 * Set up output mixers (0x0c - 0x0e)
951 */
952 /* set vol=0 to output mixers */
953 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
954 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
955 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
956
957 /* set up input amps for analog loopback */
958 /* Amp Indices: DAC = 0, mixer = 1 */
959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
962 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
965
966
967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
968 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
970 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
974
975 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
977
978 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
979 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
980
981 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
982 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
983 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
984 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
985 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
986 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
987
988 /* FIXME: use matrix-type input source selection */
989 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
990 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
996 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
998 /* Input mixer2 */
999 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
1003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1004 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
1005 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
1006 /* Input mixer3 */
1007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1010 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
1011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1012 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
1013 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
1014
1015 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1016
1017 { }
1018};
1019
1020static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
1021
1022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
1023 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1024 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
1025
1026 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
1027 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
1028 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
1029 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
1030
1031 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
1032 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1033 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1034 {}
1035};
1036
1037/*
1038 * configuration and preset
1039 */
1040static const char * const alc262_models[ALC262_MODEL_LAST] = {
1041 [ALC262_BASIC] = "basic",
1042 [ALC262_HIPPO] = "hippo",
1043 [ALC262_HIPPO_1] = "hippo_1",
1044 [ALC262_FUJITSU] = "fujitsu",
1045 [ALC262_HP_BPC] = "hp-bpc",
1046 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
1047 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
1048 [ALC262_HP_RP5700] = "hp-rp5700",
1049 [ALC262_BENQ_ED8] = "benq",
1050 [ALC262_BENQ_T31] = "benq-t31",
1051 [ALC262_SONY_ASSAMD] = "sony-assamd",
1052 [ALC262_TOSHIBA_S06] = "toshiba-s06",
1053 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
1054 [ALC262_ULTRA] = "ultra",
1055 [ALC262_LENOVO_3000] = "lenovo-3000",
1056 [ALC262_NEC] = "nec",
1057 [ALC262_TYAN] = "tyan",
1058 [ALC262_AUTO] = "auto",
1059};
1060
1061static const struct snd_pci_quirk alc262_cfg_tbl[] = {
1062 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
1063 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
1064 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
1065 ALC262_HP_BPC),
1066 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
1067 ALC262_HP_BPC),
1068 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
1069 ALC262_HP_BPC),
1070 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
1071 ALC262_AUTO),
1072 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
1073 ALC262_HP_BPC),
1074 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
1075 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
1076 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
1077 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
1078 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
1079 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
1080 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
1081 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
1082 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
1083 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
1084 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
1085 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
1086 ALC262_HP_TC_T5735),
1087 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
1088 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
1089 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
1090 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
1091 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
1092 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
1093 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
1094 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
1095#if 0 /* disable the quirk since model=auto works better in recent versions */
1096 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
1097 ALC262_SONY_ASSAMD),
1098#endif
1099 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
1100 ALC262_TOSHIBA_RX1),
1101 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
1102 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
1103 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
1104 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
1105 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
1106 ALC262_ULTRA),
1107 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
1108 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
1109 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
1110 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
1111 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
1112 {}
1113};
1114
1115static const struct alc_config_preset alc262_presets[] = {
1116 [ALC262_BASIC] = {
1117 .mixers = { alc262_base_mixer },
1118 .init_verbs = { alc262_init_verbs },
1119 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1120 .dac_nids = alc262_dac_nids,
1121 .hp_nid = 0x03,
1122 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1123 .channel_mode = alc262_modes,
1124 .input_mux = &alc262_capture_source,
1125 },
1126 [ALC262_HIPPO] = {
1127 .mixers = { alc262_hippo_mixer },
1128 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
1129 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1130 .dac_nids = alc262_dac_nids,
1131 .hp_nid = 0x03,
1132 .dig_out_nid = ALC262_DIGOUT_NID,
1133 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1134 .channel_mode = alc262_modes,
1135 .input_mux = &alc262_capture_source,
1136 .unsol_event = alc_sku_unsol_event,
1137 .setup = alc262_hippo_setup,
1138 .init_hook = alc_inithook,
1139 },
1140 [ALC262_HIPPO_1] = {
1141 .mixers = { alc262_hippo1_mixer },
1142 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
1143 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1144 .dac_nids = alc262_dac_nids,
1145 .hp_nid = 0x02,
1146 .dig_out_nid = ALC262_DIGOUT_NID,
1147 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1148 .channel_mode = alc262_modes,
1149 .input_mux = &alc262_capture_source,
1150 .unsol_event = alc_sku_unsol_event,
1151 .setup = alc262_hippo1_setup,
1152 .init_hook = alc_inithook,
1153 },
1154 [ALC262_FUJITSU] = {
1155 .mixers = { alc262_fujitsu_mixer },
1156 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
1157 alc262_fujitsu_unsol_verbs },
1158 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1159 .dac_nids = alc262_dac_nids,
1160 .hp_nid = 0x03,
1161 .dig_out_nid = ALC262_DIGOUT_NID,
1162 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1163 .channel_mode = alc262_modes,
1164 .input_mux = &alc262_fujitsu_capture_source,
1165 .unsol_event = alc_sku_unsol_event,
1166 .setup = alc262_fujitsu_setup,
1167 .init_hook = alc_inithook,
1168 },
1169 [ALC262_HP_BPC] = {
1170 .mixers = { alc262_HP_BPC_mixer },
1171 .init_verbs = { alc262_HP_BPC_init_verbs },
1172 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1173 .dac_nids = alc262_dac_nids,
1174 .hp_nid = 0x03,
1175 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1176 .channel_mode = alc262_modes,
1177 .input_mux = &alc262_HP_capture_source,
1178 .unsol_event = alc_sku_unsol_event,
1179 .setup = alc262_hp_bpc_setup,
1180 .init_hook = alc_inithook,
1181 },
1182 [ALC262_HP_BPC_D7000_WF] = {
1183 .mixers = { alc262_HP_BPC_WildWest_mixer },
1184 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
1185 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1186 .dac_nids = alc262_dac_nids,
1187 .hp_nid = 0x03,
1188 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1189 .channel_mode = alc262_modes,
1190 .input_mux = &alc262_HP_D7000_capture_source,
1191 .unsol_event = alc_sku_unsol_event,
1192 .setup = alc262_hp_wildwest_setup,
1193 .init_hook = alc_inithook,
1194 },
1195 [ALC262_HP_BPC_D7000_WL] = {
1196 .mixers = { alc262_HP_BPC_WildWest_mixer,
1197 alc262_HP_BPC_WildWest_option_mixer },
1198 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
1199 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1200 .dac_nids = alc262_dac_nids,
1201 .hp_nid = 0x03,
1202 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1203 .channel_mode = alc262_modes,
1204 .input_mux = &alc262_HP_D7000_capture_source,
1205 .unsol_event = alc_sku_unsol_event,
1206 .setup = alc262_hp_wildwest_setup,
1207 .init_hook = alc_inithook,
1208 },
1209 [ALC262_HP_TC_T5735] = {
1210 .mixers = { alc262_hp_t5735_mixer },
1211 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
1212 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1213 .dac_nids = alc262_dac_nids,
1214 .hp_nid = 0x03,
1215 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1216 .channel_mode = alc262_modes,
1217 .input_mux = &alc262_capture_source,
1218 .unsol_event = alc_sku_unsol_event,
1219 .setup = alc262_hp_t5735_setup,
1220 .init_hook = alc_inithook,
1221 },
1222 [ALC262_HP_RP5700] = {
1223 .mixers = { alc262_hp_rp5700_mixer },
1224 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
1225 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1226 .dac_nids = alc262_dac_nids,
1227 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1228 .channel_mode = alc262_modes,
1229 .input_mux = &alc262_hp_rp5700_capture_source,
1230 },
1231 [ALC262_BENQ_ED8] = {
1232 .mixers = { alc262_base_mixer },
1233 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
1234 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1235 .dac_nids = alc262_dac_nids,
1236 .hp_nid = 0x03,
1237 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1238 .channel_mode = alc262_modes,
1239 .input_mux = &alc262_capture_source,
1240 },
1241 [ALC262_SONY_ASSAMD] = {
1242 .mixers = { alc262_sony_mixer },
1243 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
1244 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1245 .dac_nids = alc262_dac_nids,
1246 .hp_nid = 0x02,
1247 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1248 .channel_mode = alc262_modes,
1249 .input_mux = &alc262_capture_source,
1250 .unsol_event = alc_sku_unsol_event,
1251 .setup = alc262_hippo_setup,
1252 .init_hook = alc_inithook,
1253 },
1254 [ALC262_BENQ_T31] = {
1255 .mixers = { alc262_benq_t31_mixer },
1256 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
1257 alc_hp15_unsol_verbs },
1258 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1259 .dac_nids = alc262_dac_nids,
1260 .hp_nid = 0x03,
1261 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1262 .channel_mode = alc262_modes,
1263 .input_mux = &alc262_capture_source,
1264 .unsol_event = alc_sku_unsol_event,
1265 .setup = alc262_hippo_setup,
1266 .init_hook = alc_inithook,
1267 },
1268 [ALC262_ULTRA] = {
1269 .mixers = { alc262_ultra_mixer },
1270 .cap_mixer = alc262_ultra_capture_mixer,
1271 .init_verbs = { alc262_ultra_verbs },
1272 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1273 .dac_nids = alc262_dac_nids,
1274 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1275 .channel_mode = alc262_modes,
1276 .input_mux = &alc262_ultra_capture_source,
1277 .adc_nids = alc262_adc_nids, /* ADC0 */
1278 .capsrc_nids = alc262_capsrc_nids,
1279 .num_adc_nids = 1, /* single ADC */
1280 .unsol_event = alc262_ultra_unsol_event,
1281 .init_hook = alc262_ultra_automute,
1282 },
1283 [ALC262_LENOVO_3000] = {
1284 .mixers = { alc262_lenovo_3000_mixer },
1285 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
1286 alc262_lenovo_3000_unsol_verbs,
1287 alc262_lenovo_3000_init_verbs },
1288 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1289 .dac_nids = alc262_dac_nids,
1290 .hp_nid = 0x03,
1291 .dig_out_nid = ALC262_DIGOUT_NID,
1292 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1293 .channel_mode = alc262_modes,
1294 .input_mux = &alc262_fujitsu_capture_source,
1295 .unsol_event = alc_sku_unsol_event,
1296 .setup = alc262_lenovo_3000_setup,
1297 .init_hook = alc_inithook,
1298 },
1299 [ALC262_NEC] = {
1300 .mixers = { alc262_nec_mixer },
1301 .init_verbs = { alc262_nec_verbs },
1302 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1303 .dac_nids = alc262_dac_nids,
1304 .hp_nid = 0x03,
1305 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1306 .channel_mode = alc262_modes,
1307 .input_mux = &alc262_capture_source,
1308 },
1309 [ALC262_TOSHIBA_S06] = {
1310 .mixers = { alc262_toshiba_s06_mixer },
1311 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
1312 alc262_eapd_verbs },
1313 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1314 .capsrc_nids = alc262_dmic_capsrc_nids,
1315 .dac_nids = alc262_dac_nids,
1316 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
1317 .num_adc_nids = 1, /* single ADC */
1318 .dig_out_nid = ALC262_DIGOUT_NID,
1319 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1320 .channel_mode = alc262_modes,
1321 .unsol_event = alc_sku_unsol_event,
1322 .setup = alc262_toshiba_s06_setup,
1323 .init_hook = alc_inithook,
1324 },
1325 [ALC262_TOSHIBA_RX1] = {
1326 .mixers = { alc262_toshiba_rx1_mixer },
1327 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
1328 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1329 .dac_nids = alc262_dac_nids,
1330 .hp_nid = 0x03,
1331 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1332 .channel_mode = alc262_modes,
1333 .input_mux = &alc262_capture_source,
1334 .unsol_event = alc_sku_unsol_event,
1335 .setup = alc262_hippo_setup,
1336 .init_hook = alc_inithook,
1337 },
1338 [ALC262_TYAN] = {
1339 .mixers = { alc262_tyan_mixer },
1340 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
1341 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1342 .dac_nids = alc262_dac_nids,
1343 .hp_nid = 0x02,
1344 .dig_out_nid = ALC262_DIGOUT_NID,
1345 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1346 .channel_mode = alc262_modes,
1347 .input_mux = &alc262_capture_source,
1348 .unsol_event = alc_sku_unsol_event,
1349 .setup = alc262_tyan_setup,
1350 .init_hook = alc_hp_automute,
1351 },
1352};
1353
diff --git a/sound/pci/hda/alc268_quirks.c b/sound/pci/hda/alc268_quirks.c
new file mode 100644
index 00000000000..2e5876ce71f
--- /dev/null
+++ b/sound/pci/hda/alc268_quirks.c
@@ -0,0 +1,636 @@
1/*
2 * ALC267/ALC268 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC268 models */
7enum {
8 ALC268_AUTO,
9 ALC267_QUANTA_IL1,
10 ALC268_3ST,
11 ALC268_TOSHIBA,
12 ALC268_ACER,
13 ALC268_ACER_DMIC,
14 ALC268_ACER_ASPIRE_ONE,
15 ALC268_DELL,
16 ALC268_ZEPTO,
17#ifdef CONFIG_SND_DEBUG
18 ALC268_TEST,
19#endif
20 ALC268_MODEL_LAST /* last tag */
21};
22
23/*
24 * ALC268 channel source setting (2 channel)
25 */
26#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
27#define alc268_modes alc260_modes
28
29static const hda_nid_t alc268_dac_nids[2] = {
30 /* front, hp */
31 0x02, 0x03
32};
33
34static const hda_nid_t alc268_adc_nids[2] = {
35 /* ADC0-1 */
36 0x08, 0x07
37};
38
39static const hda_nid_t alc268_adc_nids_alt[1] = {
40 /* ADC0 */
41 0x08
42};
43
44static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
45
46static const struct snd_kcontrol_new alc268_base_mixer[] = {
47 /* output mixer control */
48 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
49 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
50 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
53 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
54 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
55 { }
56};
57
58static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
59 /* output mixer control */
60 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
61 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
62 ALC262_HIPPO_MASTER_SWITCH,
63 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
65 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
66 { }
67};
68
69static const struct hda_verb alc268_eapd_verbs[] = {
70 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
71 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
72 { }
73};
74
75/* Toshiba specific */
76static const struct hda_verb alc268_toshiba_verbs[] = {
77 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
78 { } /* end */
79};
80
81/* Acer specific */
82/* bind volumes of both NID 0x02 and 0x03 */
83static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
84 .ops = &snd_hda_bind_vol,
85 .values = {
86 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
87 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
88 0
89 },
90};
91
92static void alc268_acer_setup(struct hda_codec *codec)
93{
94 struct alc_spec *spec = codec->spec;
95
96 spec->autocfg.hp_pins[0] = 0x14;
97 spec->autocfg.speaker_pins[0] = 0x15;
98 spec->automute = 1;
99 spec->automute_mode = ALC_AUTOMUTE_AMP;
100}
101
102#define alc268_acer_master_sw_get alc262_hp_master_sw_get
103#define alc268_acer_master_sw_put alc262_hp_master_sw_put
104
105static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
106 /* output mixer control */
107 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
108 {
109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
110 .name = "Master Playback Switch",
111 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
112 .info = snd_ctl_boolean_mono_info,
113 .get = alc268_acer_master_sw_get,
114 .put = alc268_acer_master_sw_put,
115 },
116 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
117 { }
118};
119
120static const struct snd_kcontrol_new alc268_acer_mixer[] = {
121 /* output mixer control */
122 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
123 {
124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
125 .name = "Master Playback Switch",
126 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
127 .info = snd_ctl_boolean_mono_info,
128 .get = alc268_acer_master_sw_get,
129 .put = alc268_acer_master_sw_put,
130 },
131 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
132 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
133 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
134 { }
135};
136
137static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
138 /* output mixer control */
139 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
140 {
141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
142 .name = "Master Playback Switch",
143 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
144 .info = snd_ctl_boolean_mono_info,
145 .get = alc268_acer_master_sw_get,
146 .put = alc268_acer_master_sw_put,
147 },
148 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
149 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
150 { }
151};
152
153static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
154 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
155 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
158 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
160 { }
161};
162
163static const struct hda_verb alc268_acer_verbs[] = {
164 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
165 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
166 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
167 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
168 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
169 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
170 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
171 { }
172};
173
174/* unsolicited event for HP jack sensing */
175#define alc268_toshiba_setup alc262_hippo_setup
176
177static void alc268_acer_lc_setup(struct hda_codec *codec)
178{
179 struct alc_spec *spec = codec->spec;
180 spec->autocfg.hp_pins[0] = 0x15;
181 spec->autocfg.speaker_pins[0] = 0x14;
182 spec->automute = 1;
183 spec->automute_mode = ALC_AUTOMUTE_AMP;
184 spec->ext_mic_pin = 0x18;
185 spec->int_mic_pin = 0x12;
186 spec->auto_mic = 1;
187}
188
189static const struct snd_kcontrol_new alc268_dell_mixer[] = {
190 /* output mixer control */
191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
192 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
195 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
196 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
197 { }
198};
199
200static const struct hda_verb alc268_dell_verbs[] = {
201 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
203 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
204 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
205 { }
206};
207
208/* mute/unmute internal speaker according to the hp jack and mute state */
209static void alc268_dell_setup(struct hda_codec *codec)
210{
211 struct alc_spec *spec = codec->spec;
212
213 spec->autocfg.hp_pins[0] = 0x15;
214 spec->autocfg.speaker_pins[0] = 0x14;
215 spec->ext_mic_pin = 0x18;
216 spec->int_mic_pin = 0x19;
217 spec->auto_mic = 1;
218 spec->automute = 1;
219 spec->automute_mode = ALC_AUTOMUTE_PIN;
220}
221
222static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
223 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
224 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
225 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
226 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
227 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
228 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
229 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
230 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
231 { }
232};
233
234static const struct hda_verb alc267_quanta_il1_verbs[] = {
235 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
236 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
237 { }
238};
239
240static void alc267_quanta_il1_setup(struct hda_codec *codec)
241{
242 struct alc_spec *spec = codec->spec;
243 spec->autocfg.hp_pins[0] = 0x15;
244 spec->autocfg.speaker_pins[0] = 0x14;
245 spec->ext_mic_pin = 0x18;
246 spec->int_mic_pin = 0x19;
247 spec->auto_mic = 1;
248 spec->automute = 1;
249 spec->automute_mode = ALC_AUTOMUTE_PIN;
250}
251
252/*
253 * generic initialization of ADC, input mixers and output mixers
254 */
255static const struct hda_verb alc268_base_init_verbs[] = {
256 /* Unmute DAC0-1 and set vol = 0 */
257 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
258 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
259
260 /*
261 * Set up output mixers (0x0c - 0x0e)
262 */
263 /* set vol=0 to output mixers */
264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
265 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
266
267 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
268 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
269
270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
274 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
276 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
277 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
278
279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
281 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
282 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
283 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
284
285 /* set PCBEEP vol = 0, mute connections */
286 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
287 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
288 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
289
290 /* Unmute Selector 23h,24h and set the default input to mic-in */
291
292 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
294 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
296
297 { }
298};
299
300/* only for model=test */
301#ifdef CONFIG_SND_DEBUG
302/*
303 * generic initialization of ADC, input mixers and output mixers
304 */
305static const struct hda_verb alc268_volume_init_verbs[] = {
306 /* set output DAC */
307 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
308 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
309
310 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
311 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
313 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
314 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
315
316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
317 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
318 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
319
320 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
321 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
322 { }
323};
324#endif /* CONFIG_SND_DEBUG */
325
326static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
327 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
328 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
329 { } /* end */
330};
331
332static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
333 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
334 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
335 _DEFINE_CAPSRC(1),
336 { } /* end */
337};
338
339static const struct snd_kcontrol_new alc268_capture_mixer[] = {
340 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
341 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
342 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
343 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
344 _DEFINE_CAPSRC(2),
345 { } /* end */
346};
347
348static const struct hda_input_mux alc268_capture_source = {
349 .num_items = 4,
350 .items = {
351 { "Mic", 0x0 },
352 { "Front Mic", 0x1 },
353 { "Line", 0x2 },
354 { "CD", 0x3 },
355 },
356};
357
358static const struct hda_input_mux alc268_acer_capture_source = {
359 .num_items = 3,
360 .items = {
361 { "Mic", 0x0 },
362 { "Internal Mic", 0x1 },
363 { "Line", 0x2 },
364 },
365};
366
367static const struct hda_input_mux alc268_acer_dmic_capture_source = {
368 .num_items = 3,
369 .items = {
370 { "Mic", 0x0 },
371 { "Internal Mic", 0x6 },
372 { "Line", 0x2 },
373 },
374};
375
376#ifdef CONFIG_SND_DEBUG
377static const struct snd_kcontrol_new alc268_test_mixer[] = {
378 /* Volume widgets */
379 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
380 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
381 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
382 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
383 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
384 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
385 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
386 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
387 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
388 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
389 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
390 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
391 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
392 /* The below appears problematic on some hardwares */
393 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
394 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
395 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
396 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
397 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
398
399 /* Modes for retasking pin widgets */
400 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
401 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
402 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
403 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
404
405 /* Controls for GPIO pins, assuming they are configured as outputs */
406 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
407 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
408 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
409 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
410
411 /* Switches to allow the digital SPDIF output pin to be enabled.
412 * The ALC268 does not have an SPDIF input.
413 */
414 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
415
416 /* A switch allowing EAPD to be enabled. Some laptops seem to use
417 * this output to turn on an external amplifier.
418 */
419 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
420 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
421
422 { } /* end */
423};
424#endif
425
426/*
427 * configuration and preset
428 */
429static const char * const alc268_models[ALC268_MODEL_LAST] = {
430 [ALC267_QUANTA_IL1] = "quanta-il1",
431 [ALC268_3ST] = "3stack",
432 [ALC268_TOSHIBA] = "toshiba",
433 [ALC268_ACER] = "acer",
434 [ALC268_ACER_DMIC] = "acer-dmic",
435 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
436 [ALC268_DELL] = "dell",
437 [ALC268_ZEPTO] = "zepto",
438#ifdef CONFIG_SND_DEBUG
439 [ALC268_TEST] = "test",
440#endif
441 [ALC268_AUTO] = "auto",
442};
443
444static const struct snd_pci_quirk alc268_cfg_tbl[] = {
445 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
446 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
447 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
448 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
449 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
450 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
451 ALC268_ACER_ASPIRE_ONE),
452 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
453 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
454 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
455 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
456 /* almost compatible with toshiba but with optional digital outs;
457 * auto-probing seems working fine
458 */
459 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
460 ALC268_AUTO),
461 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
462 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
463 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
464 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
465 {}
466};
467
468/* Toshiba laptops have no unique PCI SSID but only codec SSID */
469static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
470 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
471 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
472 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
473 ALC268_TOSHIBA),
474 {}
475};
476
477static const struct alc_config_preset alc268_presets[] = {
478 [ALC267_QUANTA_IL1] = {
479 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
480 .cap_mixer = alc268_capture_nosrc_mixer,
481 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
482 alc267_quanta_il1_verbs },
483 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
484 .dac_nids = alc268_dac_nids,
485 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
486 .adc_nids = alc268_adc_nids_alt,
487 .hp_nid = 0x03,
488 .num_channel_mode = ARRAY_SIZE(alc268_modes),
489 .channel_mode = alc268_modes,
490 .unsol_event = alc_sku_unsol_event,
491 .setup = alc267_quanta_il1_setup,
492 .init_hook = alc_inithook,
493 },
494 [ALC268_3ST] = {
495 .mixers = { alc268_base_mixer, alc268_beep_mixer },
496 .cap_mixer = alc268_capture_alt_mixer,
497 .init_verbs = { alc268_base_init_verbs },
498 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
499 .dac_nids = alc268_dac_nids,
500 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
501 .adc_nids = alc268_adc_nids_alt,
502 .capsrc_nids = alc268_capsrc_nids,
503 .hp_nid = 0x03,
504 .dig_out_nid = ALC268_DIGOUT_NID,
505 .num_channel_mode = ARRAY_SIZE(alc268_modes),
506 .channel_mode = alc268_modes,
507 .input_mux = &alc268_capture_source,
508 },
509 [ALC268_TOSHIBA] = {
510 .mixers = { alc268_toshiba_mixer, alc268_beep_mixer },
511 .cap_mixer = alc268_capture_alt_mixer,
512 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
513 alc268_toshiba_verbs },
514 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
515 .dac_nids = alc268_dac_nids,
516 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
517 .adc_nids = alc268_adc_nids_alt,
518 .capsrc_nids = alc268_capsrc_nids,
519 .hp_nid = 0x03,
520 .num_channel_mode = ARRAY_SIZE(alc268_modes),
521 .channel_mode = alc268_modes,
522 .input_mux = &alc268_capture_source,
523 .unsol_event = alc_sku_unsol_event,
524 .setup = alc268_toshiba_setup,
525 .init_hook = alc_inithook,
526 },
527 [ALC268_ACER] = {
528 .mixers = { alc268_acer_mixer, alc268_beep_mixer },
529 .cap_mixer = alc268_capture_alt_mixer,
530 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
531 alc268_acer_verbs },
532 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
533 .dac_nids = alc268_dac_nids,
534 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
535 .adc_nids = alc268_adc_nids_alt,
536 .capsrc_nids = alc268_capsrc_nids,
537 .hp_nid = 0x02,
538 .num_channel_mode = ARRAY_SIZE(alc268_modes),
539 .channel_mode = alc268_modes,
540 .input_mux = &alc268_acer_capture_source,
541 .unsol_event = alc_sku_unsol_event,
542 .setup = alc268_acer_setup,
543 .init_hook = alc_inithook,
544 },
545 [ALC268_ACER_DMIC] = {
546 .mixers = { alc268_acer_dmic_mixer, alc268_beep_mixer },
547 .cap_mixer = alc268_capture_alt_mixer,
548 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
549 alc268_acer_verbs },
550 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
551 .dac_nids = alc268_dac_nids,
552 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
553 .adc_nids = alc268_adc_nids_alt,
554 .capsrc_nids = alc268_capsrc_nids,
555 .hp_nid = 0x02,
556 .num_channel_mode = ARRAY_SIZE(alc268_modes),
557 .channel_mode = alc268_modes,
558 .input_mux = &alc268_acer_dmic_capture_source,
559 .unsol_event = alc_sku_unsol_event,
560 .setup = alc268_acer_setup,
561 .init_hook = alc_inithook,
562 },
563 [ALC268_ACER_ASPIRE_ONE] = {
564 .mixers = { alc268_acer_aspire_one_mixer, alc268_beep_mixer},
565 .cap_mixer = alc268_capture_nosrc_mixer,
566 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
567 alc268_acer_aspire_one_verbs },
568 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
569 .dac_nids = alc268_dac_nids,
570 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
571 .adc_nids = alc268_adc_nids_alt,
572 .capsrc_nids = alc268_capsrc_nids,
573 .hp_nid = 0x03,
574 .num_channel_mode = ARRAY_SIZE(alc268_modes),
575 .channel_mode = alc268_modes,
576 .unsol_event = alc_sku_unsol_event,
577 .setup = alc268_acer_lc_setup,
578 .init_hook = alc_inithook,
579 },
580 [ALC268_DELL] = {
581 .mixers = { alc268_dell_mixer, alc268_beep_mixer},
582 .cap_mixer = alc268_capture_nosrc_mixer,
583 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
584 alc268_dell_verbs },
585 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
586 .dac_nids = alc268_dac_nids,
587 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
588 .adc_nids = alc268_adc_nids_alt,
589 .capsrc_nids = alc268_capsrc_nids,
590 .hp_nid = 0x02,
591 .num_channel_mode = ARRAY_SIZE(alc268_modes),
592 .channel_mode = alc268_modes,
593 .unsol_event = alc_sku_unsol_event,
594 .setup = alc268_dell_setup,
595 .init_hook = alc_inithook,
596 },
597 [ALC268_ZEPTO] = {
598 .mixers = { alc268_base_mixer, alc268_beep_mixer },
599 .cap_mixer = alc268_capture_alt_mixer,
600 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
601 alc268_toshiba_verbs },
602 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
603 .dac_nids = alc268_dac_nids,
604 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
605 .adc_nids = alc268_adc_nids_alt,
606 .capsrc_nids = alc268_capsrc_nids,
607 .hp_nid = 0x03,
608 .dig_out_nid = ALC268_DIGOUT_NID,
609 .num_channel_mode = ARRAY_SIZE(alc268_modes),
610 .channel_mode = alc268_modes,
611 .input_mux = &alc268_capture_source,
612 .unsol_event = alc_sku_unsol_event,
613 .setup = alc268_toshiba_setup,
614 .init_hook = alc_inithook,
615 },
616#ifdef CONFIG_SND_DEBUG
617 [ALC268_TEST] = {
618 .mixers = { alc268_test_mixer },
619 .cap_mixer = alc268_capture_mixer,
620 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
621 alc268_volume_init_verbs,
622 alc268_beep_init_verbs },
623 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
624 .dac_nids = alc268_dac_nids,
625 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
626 .adc_nids = alc268_adc_nids_alt,
627 .capsrc_nids = alc268_capsrc_nids,
628 .hp_nid = 0x03,
629 .dig_out_nid = ALC268_DIGOUT_NID,
630 .num_channel_mode = ARRAY_SIZE(alc268_modes),
631 .channel_mode = alc268_modes,
632 .input_mux = &alc268_capture_source,
633 },
634#endif
635};
636
diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c
new file mode 100644
index 00000000000..9aeeb326460
--- /dev/null
+++ b/sound/pci/hda/alc269_quirks.c
@@ -0,0 +1,688 @@
1/*
2 * ALC269/ALC270/ALC275/ALC276 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC269 models */
7enum {
8 ALC269_AUTO,
9 ALC269_BASIC,
10 ALC269_QUANTA_FL1,
11 ALC269_AMIC,
12 ALC269_DMIC,
13 ALC269VB_AMIC,
14 ALC269VB_DMIC,
15 ALC269_FUJITSU,
16 ALC269_LIFEBOOK,
17 ALC271_ACER,
18 ALC269_MODEL_LAST /* last tag */
19};
20
21/*
22 * ALC269 channel source setting (2 channel)
23 */
24#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
25
26#define alc269_dac_nids alc260_dac_nids
27
28static const hda_nid_t alc269_adc_nids[1] = {
29 /* ADC1 */
30 0x08,
31};
32
33static const hda_nid_t alc269_capsrc_nids[1] = {
34 0x23,
35};
36
37static const hda_nid_t alc269vb_adc_nids[1] = {
38 /* ADC1 */
39 0x09,
40};
41
42static const hda_nid_t alc269vb_capsrc_nids[1] = {
43 0x22,
44};
45
46#define alc269_modes alc260_modes
47#define alc269_capture_source alc880_lg_lw_capture_source
48
49static const struct snd_kcontrol_new alc269_base_mixer[] = {
50 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
53 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
54 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
55 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
56 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
57 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
58 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
59 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
60 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
61 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
62 { } /* end */
63};
64
65static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
66 /* output mixer control */
67 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
68 {
69 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
70 .name = "Master Playback Switch",
71 .subdevice = HDA_SUBDEV_AMP_FLAG,
72 .info = snd_hda_mixer_amp_switch_info,
73 .get = snd_hda_mixer_amp_switch_get,
74 .put = alc268_acer_master_sw_put,
75 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
76 },
77 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
78 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
79 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
80 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
81 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
82 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
83 { }
84};
85
86static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
87 /* output mixer control */
88 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
89 {
90 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
91 .name = "Master Playback Switch",
92 .subdevice = HDA_SUBDEV_AMP_FLAG,
93 .info = snd_hda_mixer_amp_switch_info,
94 .get = snd_hda_mixer_amp_switch_get,
95 .put = alc268_acer_master_sw_put,
96 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
97 },
98 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
99 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
100 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
101 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
102 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
103 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
104 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
105 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
106 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
107 { }
108};
109
110static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
111 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
112 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
113 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
114 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
115 { } /* end */
116};
117
118static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
119 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
122 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
123 { } /* end */
124};
125
126static const struct snd_kcontrol_new alc269_asus_mixer[] = {
127 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
128 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
129 { } /* end */
130};
131
132/* capture mixer elements */
133static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
134 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
135 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
136 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
137 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
138 { } /* end */
139};
140
141static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
142 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
143 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
144 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
145 { } /* end */
146};
147
148static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
149 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
150 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
151 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
152 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
153 { } /* end */
154};
155
156static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
157 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
158 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
159 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
160 { } /* end */
161};
162
163/* FSC amilo */
164#define alc269_fujitsu_mixer alc269_laptop_mixer
165
166static const struct hda_verb alc269_quanta_fl1_verbs[] = {
167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
168 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
170 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
171 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
172 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
173 { }
174};
175
176static const struct hda_verb alc269_lifebook_verbs[] = {
177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
178 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
179 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
181 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
182 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
183 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
184 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
185 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
186 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
187 { }
188};
189
190/* toggle speaker-output according to the hp-jack state */
191static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
192{
193 alc_hp_automute(codec);
194
195 snd_hda_codec_write(codec, 0x20, 0,
196 AC_VERB_SET_COEF_INDEX, 0x0c);
197 snd_hda_codec_write(codec, 0x20, 0,
198 AC_VERB_SET_PROC_COEF, 0x680);
199
200 snd_hda_codec_write(codec, 0x20, 0,
201 AC_VERB_SET_COEF_INDEX, 0x0c);
202 snd_hda_codec_write(codec, 0x20, 0,
203 AC_VERB_SET_PROC_COEF, 0x480);
204}
205
206#define alc269_lifebook_speaker_automute \
207 alc269_quanta_fl1_speaker_automute
208
209static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
210{
211 unsigned int present_laptop;
212 unsigned int present_dock;
213
214 present_laptop = snd_hda_jack_detect(codec, 0x18);
215 present_dock = snd_hda_jack_detect(codec, 0x1b);
216
217 /* Laptop mic port overrides dock mic port, design decision */
218 if (present_dock)
219 snd_hda_codec_write(codec, 0x23, 0,
220 AC_VERB_SET_CONNECT_SEL, 0x3);
221 if (present_laptop)
222 snd_hda_codec_write(codec, 0x23, 0,
223 AC_VERB_SET_CONNECT_SEL, 0x0);
224 if (!present_dock && !present_laptop)
225 snd_hda_codec_write(codec, 0x23, 0,
226 AC_VERB_SET_CONNECT_SEL, 0x1);
227}
228
229static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
230 unsigned int res)
231{
232 switch (res >> 26) {
233 case ALC_HP_EVENT:
234 alc269_quanta_fl1_speaker_automute(codec);
235 break;
236 case ALC_MIC_EVENT:
237 alc_mic_automute(codec);
238 break;
239 }
240}
241
242static void alc269_lifebook_unsol_event(struct hda_codec *codec,
243 unsigned int res)
244{
245 if ((res >> 26) == ALC_HP_EVENT)
246 alc269_lifebook_speaker_automute(codec);
247 if ((res >> 26) == ALC_MIC_EVENT)
248 alc269_lifebook_mic_autoswitch(codec);
249}
250
251static void alc269_quanta_fl1_setup(struct hda_codec *codec)
252{
253 struct alc_spec *spec = codec->spec;
254 spec->autocfg.hp_pins[0] = 0x15;
255 spec->autocfg.speaker_pins[0] = 0x14;
256 spec->automute_mixer_nid[0] = 0x0c;
257 spec->automute = 1;
258 spec->automute_mode = ALC_AUTOMUTE_MIXER;
259 spec->ext_mic_pin = 0x18;
260 spec->int_mic_pin = 0x19;
261 spec->auto_mic = 1;
262}
263
264static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
265{
266 alc269_quanta_fl1_speaker_automute(codec);
267 alc_mic_automute(codec);
268}
269
270static void alc269_lifebook_setup(struct hda_codec *codec)
271{
272 struct alc_spec *spec = codec->spec;
273 spec->autocfg.hp_pins[0] = 0x15;
274 spec->autocfg.hp_pins[1] = 0x1a;
275 spec->autocfg.speaker_pins[0] = 0x14;
276 spec->automute_mixer_nid[0] = 0x0c;
277 spec->automute = 1;
278 spec->automute_mode = ALC_AUTOMUTE_MIXER;
279}
280
281static void alc269_lifebook_init_hook(struct hda_codec *codec)
282{
283 alc269_lifebook_speaker_automute(codec);
284 alc269_lifebook_mic_autoswitch(codec);
285}
286
287static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
288 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
289 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
290 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
292 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
294 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
295 {}
296};
297
298static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
299 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
300 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
301 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
302 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
305 {}
306};
307
308static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
309 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
310 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
311 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
312 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
313 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
314 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
315 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
316 {}
317};
318
319static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
320 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
321 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
322 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
323 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
324 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
325 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
326 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
327 {}
328};
329
330static const struct hda_verb alc271_acer_dmic_verbs[] = {
331 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
332 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
333 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
335 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
336 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
337 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
338 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
339 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
340 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
341 { }
342};
343
344static void alc269_laptop_amic_setup(struct hda_codec *codec)
345{
346 struct alc_spec *spec = codec->spec;
347 spec->autocfg.hp_pins[0] = 0x15;
348 spec->autocfg.speaker_pins[0] = 0x14;
349 spec->automute_mixer_nid[0] = 0x0c;
350 spec->automute = 1;
351 spec->automute_mode = ALC_AUTOMUTE_MIXER;
352 spec->ext_mic_pin = 0x18;
353 spec->int_mic_pin = 0x19;
354 spec->auto_mic = 1;
355}
356
357static void alc269_laptop_dmic_setup(struct hda_codec *codec)
358{
359 struct alc_spec *spec = codec->spec;
360 spec->autocfg.hp_pins[0] = 0x15;
361 spec->autocfg.speaker_pins[0] = 0x14;
362 spec->automute_mixer_nid[0] = 0x0c;
363 spec->automute = 1;
364 spec->automute_mode = ALC_AUTOMUTE_MIXER;
365 spec->ext_mic_pin = 0x18;
366 spec->int_mic_pin = 0x12;
367 spec->auto_mic = 1;
368}
369
370static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
371{
372 struct alc_spec *spec = codec->spec;
373 spec->autocfg.hp_pins[0] = 0x21;
374 spec->autocfg.speaker_pins[0] = 0x14;
375 spec->automute_mixer_nid[0] = 0x0c;
376 spec->automute = 1;
377 spec->automute_mode = ALC_AUTOMUTE_MIXER;
378 spec->ext_mic_pin = 0x18;
379 spec->int_mic_pin = 0x19;
380 spec->auto_mic = 1;
381}
382
383static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
384{
385 struct alc_spec *spec = codec->spec;
386 spec->autocfg.hp_pins[0] = 0x21;
387 spec->autocfg.speaker_pins[0] = 0x14;
388 spec->automute_mixer_nid[0] = 0x0c;
389 spec->automute = 1;
390 spec->automute_mode = ALC_AUTOMUTE_MIXER;
391 spec->ext_mic_pin = 0x18;
392 spec->int_mic_pin = 0x12;
393 spec->auto_mic = 1;
394}
395
396/*
397 * generic initialization of ADC, input mixers and output mixers
398 */
399static const struct hda_verb alc269_init_verbs[] = {
400 /*
401 * Unmute ADC0 and set the default input to mic-in
402 */
403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
404
405 /*
406 * Set up output mixers (0x02 - 0x03)
407 */
408 /* set vol=0 to output mixers */
409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
411
412 /* set up input amps for analog loopback */
413 /* Amp Indices: DAC = 0, mixer = 1 */
414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
420
421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
428
429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
431
432 /* FIXME: use Mux-type input source selection */
433 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
434 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
435 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
436
437 /* set EAPD */
438 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
439 { }
440};
441
442static const struct hda_verb alc269vb_init_verbs[] = {
443 /*
444 * Unmute ADC0 and set the default input to mic-in
445 */
446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
447
448 /*
449 * Set up output mixers (0x02 - 0x03)
450 */
451 /* set vol=0 to output mixers */
452 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
453 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
454
455 /* set up input amps for analog loopback */
456 /* Amp Indices: DAC = 0, mixer = 1 */
457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
463
464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
465 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
471
472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
474
475 /* FIXME: use Mux-type input source selection */
476 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
477 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
478 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
479
480 /* set EAPD */
481 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
482 { }
483};
484
485/*
486 * configuration and preset
487 */
488static const char * const alc269_models[ALC269_MODEL_LAST] = {
489 [ALC269_BASIC] = "basic",
490 [ALC269_QUANTA_FL1] = "quanta",
491 [ALC269_AMIC] = "laptop-amic",
492 [ALC269_DMIC] = "laptop-dmic",
493 [ALC269_FUJITSU] = "fujitsu",
494 [ALC269_LIFEBOOK] = "lifebook",
495 [ALC269_AUTO] = "auto",
496};
497
498static const struct snd_pci_quirk alc269_cfg_tbl[] = {
499 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
500 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
501 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
502 ALC269_AMIC),
503 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
504 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
505 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
506 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
507 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
508 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
509 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
510 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
511 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
512 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
513 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
514 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
515 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
516 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
517 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
518 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
519 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
520 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
521 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
522 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
523 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
524 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
525 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
526 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
527 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
528 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
529 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
530 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
531 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
532 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
533 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
534 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
535 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
536 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
537 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
538 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
539 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
540 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
541 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
542 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
543 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
544 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
545 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
546 {}
547};
548
549static const struct alc_config_preset alc269_presets[] = {
550 [ALC269_BASIC] = {
551 .mixers = { alc269_base_mixer },
552 .init_verbs = { alc269_init_verbs },
553 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
554 .dac_nids = alc269_dac_nids,
555 .hp_nid = 0x03,
556 .num_channel_mode = ARRAY_SIZE(alc269_modes),
557 .channel_mode = alc269_modes,
558 .input_mux = &alc269_capture_source,
559 },
560 [ALC269_QUANTA_FL1] = {
561 .mixers = { alc269_quanta_fl1_mixer },
562 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
563 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
564 .dac_nids = alc269_dac_nids,
565 .hp_nid = 0x03,
566 .num_channel_mode = ARRAY_SIZE(alc269_modes),
567 .channel_mode = alc269_modes,
568 .input_mux = &alc269_capture_source,
569 .unsol_event = alc269_quanta_fl1_unsol_event,
570 .setup = alc269_quanta_fl1_setup,
571 .init_hook = alc269_quanta_fl1_init_hook,
572 },
573 [ALC269_AMIC] = {
574 .mixers = { alc269_laptop_mixer },
575 .cap_mixer = alc269_laptop_analog_capture_mixer,
576 .init_verbs = { alc269_init_verbs,
577 alc269_laptop_amic_init_verbs },
578 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
579 .dac_nids = alc269_dac_nids,
580 .adc_nids = alc269_adc_nids,
581 .capsrc_nids = alc269_capsrc_nids,
582 .num_adc_nids = ARRAY_SIZE(alc269_adc_nids),
583 .hp_nid = 0x03,
584 .num_channel_mode = ARRAY_SIZE(alc269_modes),
585 .channel_mode = alc269_modes,
586 .unsol_event = alc_sku_unsol_event,
587 .setup = alc269_laptop_amic_setup,
588 .init_hook = alc_inithook,
589 },
590 [ALC269_DMIC] = {
591 .mixers = { alc269_laptop_mixer },
592 .cap_mixer = alc269_laptop_digital_capture_mixer,
593 .init_verbs = { alc269_init_verbs,
594 alc269_laptop_dmic_init_verbs },
595 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
596 .dac_nids = alc269_dac_nids,
597 .adc_nids = alc269_adc_nids,
598 .capsrc_nids = alc269_capsrc_nids,
599 .num_adc_nids = ARRAY_SIZE(alc269_adc_nids),
600 .hp_nid = 0x03,
601 .num_channel_mode = ARRAY_SIZE(alc269_modes),
602 .channel_mode = alc269_modes,
603 .unsol_event = alc_sku_unsol_event,
604 .setup = alc269_laptop_dmic_setup,
605 .init_hook = alc_inithook,
606 },
607 [ALC269VB_AMIC] = {
608 .mixers = { alc269vb_laptop_mixer },
609 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
610 .init_verbs = { alc269vb_init_verbs,
611 alc269vb_laptop_amic_init_verbs },
612 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
613 .dac_nids = alc269_dac_nids,
614 .adc_nids = alc269vb_adc_nids,
615 .capsrc_nids = alc269vb_capsrc_nids,
616 .num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids),
617 .hp_nid = 0x03,
618 .num_channel_mode = ARRAY_SIZE(alc269_modes),
619 .channel_mode = alc269_modes,
620 .unsol_event = alc_sku_unsol_event,
621 .setup = alc269vb_laptop_amic_setup,
622 .init_hook = alc_inithook,
623 },
624 [ALC269VB_DMIC] = {
625 .mixers = { alc269vb_laptop_mixer },
626 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
627 .init_verbs = { alc269vb_init_verbs,
628 alc269vb_laptop_dmic_init_verbs },
629 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
630 .dac_nids = alc269_dac_nids,
631 .adc_nids = alc269vb_adc_nids,
632 .capsrc_nids = alc269vb_capsrc_nids,
633 .num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids),
634 .hp_nid = 0x03,
635 .num_channel_mode = ARRAY_SIZE(alc269_modes),
636 .channel_mode = alc269_modes,
637 .unsol_event = alc_sku_unsol_event,
638 .setup = alc269vb_laptop_dmic_setup,
639 .init_hook = alc_inithook,
640 },
641 [ALC269_FUJITSU] = {
642 .mixers = { alc269_fujitsu_mixer },
643 .cap_mixer = alc269_laptop_digital_capture_mixer,
644 .init_verbs = { alc269_init_verbs,
645 alc269_laptop_dmic_init_verbs },
646 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
647 .dac_nids = alc269_dac_nids,
648 .adc_nids = alc269_adc_nids,
649 .capsrc_nids = alc269_capsrc_nids,
650 .hp_nid = 0x03,
651 .num_channel_mode = ARRAY_SIZE(alc269_modes),
652 .channel_mode = alc269_modes,
653 .unsol_event = alc_sku_unsol_event,
654 .setup = alc269_laptop_dmic_setup,
655 .init_hook = alc_inithook,
656 },
657 [ALC269_LIFEBOOK] = {
658 .mixers = { alc269_lifebook_mixer },
659 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
660 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
661 .dac_nids = alc269_dac_nids,
662 .hp_nid = 0x03,
663 .num_channel_mode = ARRAY_SIZE(alc269_modes),
664 .channel_mode = alc269_modes,
665 .input_mux = &alc269_capture_source,
666 .unsol_event = alc269_lifebook_unsol_event,
667 .setup = alc269_lifebook_setup,
668 .init_hook = alc269_lifebook_init_hook,
669 },
670 [ALC271_ACER] = {
671 .mixers = { alc269_asus_mixer },
672 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
673 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
674 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
675 .dac_nids = alc269_dac_nids,
676 .adc_nids = alc262_dmic_adc_nids,
677 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
678 .capsrc_nids = alc262_dmic_capsrc_nids,
679 .num_channel_mode = ARRAY_SIZE(alc269_modes),
680 .channel_mode = alc269_modes,
681 .input_mux = &alc269_capture_source,
682 .dig_out_nid = ALC880_DIGOUT_NID,
683 .unsol_event = alc_sku_unsol_event,
684 .setup = alc269vb_laptop_dmic_setup,
685 .init_hook = alc_inithook,
686 },
687};
688
diff --git a/sound/pci/hda/alc662_quirks.c b/sound/pci/hda/alc662_quirks.c
new file mode 100644
index 00000000000..e69a6ea3083
--- /dev/null
+++ b/sound/pci/hda/alc662_quirks.c
@@ -0,0 +1,1408 @@
1/*
2 * ALC662/ALC663/ALC665/ALC670 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC662 models */
7enum {
8 ALC662_AUTO,
9 ALC662_3ST_2ch_DIG,
10 ALC662_3ST_6ch_DIG,
11 ALC662_3ST_6ch,
12 ALC662_5ST_DIG,
13 ALC662_LENOVO_101E,
14 ALC662_ASUS_EEEPC_P701,
15 ALC662_ASUS_EEEPC_EP20,
16 ALC663_ASUS_M51VA,
17 ALC663_ASUS_G71V,
18 ALC663_ASUS_H13,
19 ALC663_ASUS_G50V,
20 ALC662_ECS,
21 ALC663_ASUS_MODE1,
22 ALC662_ASUS_MODE2,
23 ALC663_ASUS_MODE3,
24 ALC663_ASUS_MODE4,
25 ALC663_ASUS_MODE5,
26 ALC663_ASUS_MODE6,
27 ALC663_ASUS_MODE7,
28 ALC663_ASUS_MODE8,
29 ALC272_DELL,
30 ALC272_DELL_ZM1,
31 ALC272_SAMSUNG_NC10,
32 ALC662_MODEL_LAST,
33};
34
35#define ALC662_DIGOUT_NID 0x06
36#define ALC662_DIGIN_NID 0x0a
37
38static const hda_nid_t alc662_dac_nids[3] = {
39 /* front, rear, clfe */
40 0x02, 0x03, 0x04
41};
42
43static const hda_nid_t alc272_dac_nids[2] = {
44 0x02, 0x03
45};
46
47static const hda_nid_t alc662_adc_nids[2] = {
48 /* ADC1-2 */
49 0x09, 0x08
50};
51
52static const hda_nid_t alc272_adc_nids[1] = {
53 /* ADC1-2 */
54 0x08,
55};
56
57static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
58static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
59
60
61/* input MUX */
62/* FIXME: should be a matrix-type input source selection */
63static const struct hda_input_mux alc662_capture_source = {
64 .num_items = 4,
65 .items = {
66 { "Mic", 0x0 },
67 { "Front Mic", 0x1 },
68 { "Line", 0x2 },
69 { "CD", 0x4 },
70 },
71};
72
73static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
74 .num_items = 2,
75 .items = {
76 { "Mic", 0x1 },
77 { "Line", 0x2 },
78 },
79};
80
81static const struct hda_input_mux alc663_capture_source = {
82 .num_items = 3,
83 .items = {
84 { "Mic", 0x0 },
85 { "Front Mic", 0x1 },
86 { "Line", 0x2 },
87 },
88};
89
90#if 0 /* set to 1 for testing other input sources below */
91static const struct hda_input_mux alc272_nc10_capture_source = {
92 .num_items = 16,
93 .items = {
94 { "Autoselect Mic", 0x0 },
95 { "Internal Mic", 0x1 },
96 { "In-0x02", 0x2 },
97 { "In-0x03", 0x3 },
98 { "In-0x04", 0x4 },
99 { "In-0x05", 0x5 },
100 { "In-0x06", 0x6 },
101 { "In-0x07", 0x7 },
102 { "In-0x08", 0x8 },
103 { "In-0x09", 0x9 },
104 { "In-0x0a", 0x0a },
105 { "In-0x0b", 0x0b },
106 { "In-0x0c", 0x0c },
107 { "In-0x0d", 0x0d },
108 { "In-0x0e", 0x0e },
109 { "In-0x0f", 0x0f },
110 },
111};
112#endif
113
114/*
115 * 2ch mode
116 */
117static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
118 { 2, NULL }
119};
120
121/*
122 * 2ch mode
123 */
124static const struct hda_verb alc662_3ST_ch2_init[] = {
125 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
126 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
127 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
128 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
129 { } /* end */
130};
131
132/*
133 * 6ch mode
134 */
135static const struct hda_verb alc662_3ST_ch6_init[] = {
136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
138 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
141 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
142 { } /* end */
143};
144
145static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
146 { 2, alc662_3ST_ch2_init },
147 { 6, alc662_3ST_ch6_init },
148};
149
150/*
151 * 2ch mode
152 */
153static const struct hda_verb alc662_sixstack_ch6_init[] = {
154 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
155 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
156 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
157 { } /* end */
158};
159
160/*
161 * 6ch mode
162 */
163static const struct hda_verb alc662_sixstack_ch8_init[] = {
164 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
165 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
166 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
167 { } /* end */
168};
169
170static const struct hda_channel_mode alc662_5stack_modes[2] = {
171 { 2, alc662_sixstack_ch6_init },
172 { 6, alc662_sixstack_ch8_init },
173};
174
175/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
176 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
177 */
178
179static const struct snd_kcontrol_new alc662_base_mixer[] = {
180 /* output mixer control */
181 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
182 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
183 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
184 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
185 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
186 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
187 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
188 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
189 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
190
191 /*Input mixer control */
192 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
193 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
194 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
195 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
196 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
197 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
200 { } /* end */
201};
202
203static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
204 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
205 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
207 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
208 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
214 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
215 { } /* end */
216};
217
218static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
219 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
220 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
222 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
224 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
225 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
226 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
227 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
228 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
229 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
230 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
231 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
234 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
235 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
236 { } /* end */
237};
238
239static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
240 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
241 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
242 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
243 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
244 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
249 { } /* end */
250};
251
252static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
253 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
254 ALC262_HIPPO_MASTER_SWITCH,
255
256 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
258 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
259
260 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
261 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
262 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
263 { } /* end */
264};
265
266static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
267 ALC262_HIPPO_MASTER_SWITCH,
268 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
270 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
271 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
272 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
273 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
274 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
277 { } /* end */
278};
279
280static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
281 .ops = &snd_hda_bind_vol,
282 .values = {
283 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
284 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
285 0
286 },
287};
288
289static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
290 .ops = &snd_hda_bind_sw,
291 .values = {
292 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
293 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
294 0
295 },
296};
297
298static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
299 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
300 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
303 { } /* end */
304};
305
306static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
307 .ops = &snd_hda_bind_sw,
308 .values = {
309 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
310 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
311 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
312 0
313 },
314};
315
316static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
317 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
318 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
321 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
322 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
323
324 { } /* end */
325};
326
327static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
328 .ops = &snd_hda_bind_sw,
329 .values = {
330 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
331 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
332 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
333 0
334 },
335};
336
337static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
338 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
339 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
341 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
342 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
343 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
344 { } /* end */
345};
346
347static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
349 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
353 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
354 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
355 { } /* end */
356};
357
358static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
359 .ops = &snd_hda_bind_vol,
360 .values = {
361 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
362 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
363 0
364 },
365};
366
367static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
368 .ops = &snd_hda_bind_sw,
369 .values = {
370 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
371 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
372 0
373 },
374};
375
376static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
377 HDA_BIND_VOL("Master Playback Volume",
378 &alc663_asus_two_bind_master_vol),
379 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
380 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
381 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
384 { } /* end */
385};
386
387static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
388 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
389 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
390 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
391 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
394 { } /* end */
395};
396
397static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
398 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
399 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
400 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
401 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
402 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
403
404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
406 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
407 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
408 { } /* end */
409};
410
411static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
412 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
413 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
414 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
415
416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
418 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
419 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, 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 { } /* end */
423};
424
425static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
426 .ops = &snd_hda_bind_sw,
427 .values = {
428 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
429 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
430 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
431 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
432 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
433 0
434 },
435};
436
437static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
438 .ops = &snd_hda_bind_sw,
439 .values = {
440 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
441 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
442 0
443 },
444};
445
446static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
447 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
448 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
449 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
450 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
451 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
452 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
453 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
456 { } /* end */
457};
458
459static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
460 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
461 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
462 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
463 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
464 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
467 { } /* end */
468};
469
470
471static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
472 {
473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
474 .name = "Channel Mode",
475 .info = alc_ch_mode_info,
476 .get = alc_ch_mode_get,
477 .put = alc_ch_mode_put,
478 },
479 { } /* end */
480};
481
482static const struct hda_verb alc662_init_verbs[] = {
483 /* ADC: mute amp left and right */
484 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
485 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
486
487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
493
494 /* Front Pin: output 0 (0x0c) */
495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
497
498 /* Rear Pin: output 1 (0x0d) */
499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
501
502 /* CLFE Pin: output 2 (0x0e) */
503 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
505
506 /* Mic (rear) pin: input vref at 80% */
507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
509 /* Front Mic pin: input vref at 80% */
510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
512 /* Line In pin: input */
513 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
514 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
515 /* Line-2 In: Headphone output (output 0 - 0x0c) */
516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
518 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
519 /* CD pin widget for input */
520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
521
522 /* FIXME: use matrix-type input source selection */
523 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
524 /* Input mixer */
525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
527
528 { }
529};
530
531static const struct hda_verb alc662_eapd_init_verbs[] = {
532 /* always trun on EAPD */
533 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
534 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
535 { }
536};
537
538static const struct hda_verb alc662_sue_init_verbs[] = {
539 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
540 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
541 {}
542};
543
544static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
545 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
546 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
547 {}
548};
549
550/* Set Unsolicited Event*/
551static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
552 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
554 {}
555};
556
557static const struct hda_verb alc663_m51va_init_verbs[] = {
558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
559 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
560 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
561 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
562 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
565 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
566 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
567 {}
568};
569
570static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
571 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
572 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
573 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
574 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
576 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
577 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
578 {}
579};
580
581static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
582 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
583 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
584 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
585 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
588 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
590 {}
591};
592
593static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
594 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
595 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
596 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
599 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
600 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
601 {}
602};
603
604static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
606 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
607 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
608 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
614 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
615 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
616 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
617 {}
618};
619
620static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
621 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
622 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
623 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
624 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
629 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
630 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
631 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
633 {}
634};
635
636static const struct hda_verb alc663_g71v_init_verbs[] = {
637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
638 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
639 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
640
641 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
642 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
643 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
644
645 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
646 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_MIC_EVENT},
647 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
648 {}
649};
650
651static const struct hda_verb alc663_g50v_init_verbs[] = {
652 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
653 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
654 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
655
656 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
657 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
658 {}
659};
660
661static const struct hda_verb alc662_ecs_init_verbs[] = {
662 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
664 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
665 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
666 {}
667};
668
669static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
670 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
671 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
672 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
674 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
675 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
676 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
679 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
680 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
681 {}
682};
683
684static const struct hda_verb alc272_dell_init_verbs[] = {
685 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
686 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
688 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
689 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
690 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
691 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
692 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
693 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
694 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
695 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
696 {}
697};
698
699static const struct hda_verb alc663_mode7_init_verbs[] = {
700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
701 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
702 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
703 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
707 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
708 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
709 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
712 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
713 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
714 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
715 {}
716};
717
718static const struct hda_verb alc663_mode8_init_verbs[] = {
719 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
720 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
723 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
724 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
725 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
727 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
728 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
729 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
732 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
733 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
734 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
735 {}
736};
737
738static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
739 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
740 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
741 { } /* end */
742};
743
744static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
747 { } /* end */
748};
749
750static void alc662_lenovo_101e_setup(struct hda_codec *codec)
751{
752 struct alc_spec *spec = codec->spec;
753
754 spec->autocfg.hp_pins[0] = 0x1b;
755 spec->autocfg.line_out_pins[0] = 0x14;
756 spec->autocfg.speaker_pins[0] = 0x15;
757 spec->automute = 1;
758 spec->detect_line = 1;
759 spec->automute_lines = 1;
760 spec->automute_mode = ALC_AUTOMUTE_AMP;
761}
762
763static void alc662_eeepc_setup(struct hda_codec *codec)
764{
765 struct alc_spec *spec = codec->spec;
766
767 alc262_hippo1_setup(codec);
768 spec->ext_mic_pin = 0x18;
769 spec->int_mic_pin = 0x19;
770 spec->auto_mic = 1;
771}
772
773static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
774{
775 struct alc_spec *spec = codec->spec;
776
777 spec->autocfg.hp_pins[0] = 0x14;
778 spec->autocfg.speaker_pins[0] = 0x1b;
779 spec->automute = 1;
780 spec->automute_mode = ALC_AUTOMUTE_AMP;
781}
782
783static void alc663_m51va_setup(struct hda_codec *codec)
784{
785 struct alc_spec *spec = codec->spec;
786 spec->autocfg.hp_pins[0] = 0x21;
787 spec->autocfg.speaker_pins[0] = 0x14;
788 spec->automute_mixer_nid[0] = 0x0c;
789 spec->automute = 1;
790 spec->automute_mode = ALC_AUTOMUTE_MIXER;
791 spec->ext_mic_pin = 0x18;
792 spec->int_mic_pin = 0x12;
793 spec->auto_mic = 1;
794}
795
796/* ***************** Mode1 ******************************/
797static void alc663_mode1_setup(struct hda_codec *codec)
798{
799 struct alc_spec *spec = codec->spec;
800 spec->autocfg.hp_pins[0] = 0x21;
801 spec->autocfg.speaker_pins[0] = 0x14;
802 spec->automute_mixer_nid[0] = 0x0c;
803 spec->automute = 1;
804 spec->automute_mode = ALC_AUTOMUTE_MIXER;
805 spec->ext_mic_pin = 0x18;
806 spec->int_mic_pin = 0x19;
807 spec->auto_mic = 1;
808}
809
810/* ***************** Mode2 ******************************/
811static void alc662_mode2_setup(struct hda_codec *codec)
812{
813 struct alc_spec *spec = codec->spec;
814 spec->autocfg.hp_pins[0] = 0x1b;
815 spec->autocfg.speaker_pins[0] = 0x14;
816 spec->automute = 1;
817 spec->automute_mode = ALC_AUTOMUTE_PIN;
818 spec->ext_mic_pin = 0x18;
819 spec->int_mic_pin = 0x19;
820 spec->auto_mic = 1;
821}
822
823/* ***************** Mode3 ******************************/
824static void alc663_mode3_setup(struct hda_codec *codec)
825{
826 struct alc_spec *spec = codec->spec;
827 spec->autocfg.hp_pins[0] = 0x21;
828 spec->autocfg.hp_pins[0] = 0x15;
829 spec->autocfg.speaker_pins[0] = 0x14;
830 spec->automute = 1;
831 spec->automute_mode = ALC_AUTOMUTE_PIN;
832 spec->ext_mic_pin = 0x18;
833 spec->int_mic_pin = 0x19;
834 spec->auto_mic = 1;
835}
836
837/* ***************** Mode4 ******************************/
838static void alc663_mode4_setup(struct hda_codec *codec)
839{
840 struct alc_spec *spec = codec->spec;
841 spec->autocfg.hp_pins[0] = 0x21;
842 spec->autocfg.speaker_pins[0] = 0x14;
843 spec->autocfg.speaker_pins[1] = 0x16;
844 spec->automute_mixer_nid[0] = 0x0c;
845 spec->automute_mixer_nid[1] = 0x0e;
846 spec->automute = 1;
847 spec->automute_mode = ALC_AUTOMUTE_MIXER;
848 spec->ext_mic_pin = 0x18;
849 spec->int_mic_pin = 0x19;
850 spec->auto_mic = 1;
851}
852
853/* ***************** Mode5 ******************************/
854static void alc663_mode5_setup(struct hda_codec *codec)
855{
856 struct alc_spec *spec = codec->spec;
857 spec->autocfg.hp_pins[0] = 0x15;
858 spec->autocfg.speaker_pins[0] = 0x14;
859 spec->autocfg.speaker_pins[1] = 0x16;
860 spec->automute_mixer_nid[0] = 0x0c;
861 spec->automute_mixer_nid[1] = 0x0e;
862 spec->automute = 1;
863 spec->automute_mode = ALC_AUTOMUTE_MIXER;
864 spec->ext_mic_pin = 0x18;
865 spec->int_mic_pin = 0x19;
866 spec->auto_mic = 1;
867}
868
869/* ***************** Mode6 ******************************/
870static void alc663_mode6_setup(struct hda_codec *codec)
871{
872 struct alc_spec *spec = codec->spec;
873 spec->autocfg.hp_pins[0] = 0x1b;
874 spec->autocfg.hp_pins[0] = 0x15;
875 spec->autocfg.speaker_pins[0] = 0x14;
876 spec->automute_mixer_nid[0] = 0x0c;
877 spec->automute = 1;
878 spec->automute_mode = ALC_AUTOMUTE_MIXER;
879 spec->ext_mic_pin = 0x18;
880 spec->int_mic_pin = 0x19;
881 spec->auto_mic = 1;
882}
883
884/* ***************** Mode7 ******************************/
885static void alc663_mode7_setup(struct hda_codec *codec)
886{
887 struct alc_spec *spec = codec->spec;
888 spec->autocfg.hp_pins[0] = 0x1b;
889 spec->autocfg.hp_pins[0] = 0x21;
890 spec->autocfg.speaker_pins[0] = 0x14;
891 spec->autocfg.speaker_pins[0] = 0x17;
892 spec->automute = 1;
893 spec->automute_mode = ALC_AUTOMUTE_PIN;
894 spec->ext_mic_pin = 0x18;
895 spec->int_mic_pin = 0x19;
896 spec->auto_mic = 1;
897}
898
899/* ***************** Mode8 ******************************/
900static void alc663_mode8_setup(struct hda_codec *codec)
901{
902 struct alc_spec *spec = codec->spec;
903 spec->autocfg.hp_pins[0] = 0x21;
904 spec->autocfg.hp_pins[1] = 0x15;
905 spec->autocfg.speaker_pins[0] = 0x14;
906 spec->autocfg.speaker_pins[0] = 0x17;
907 spec->automute = 1;
908 spec->automute_mode = ALC_AUTOMUTE_PIN;
909 spec->ext_mic_pin = 0x18;
910 spec->int_mic_pin = 0x12;
911 spec->auto_mic = 1;
912}
913
914static void alc663_g71v_setup(struct hda_codec *codec)
915{
916 struct alc_spec *spec = codec->spec;
917 spec->autocfg.hp_pins[0] = 0x21;
918 spec->autocfg.line_out_pins[0] = 0x15;
919 spec->autocfg.speaker_pins[0] = 0x14;
920 spec->automute = 1;
921 spec->automute_mode = ALC_AUTOMUTE_AMP;
922 spec->detect_line = 1;
923 spec->automute_lines = 1;
924 spec->ext_mic_pin = 0x18;
925 spec->int_mic_pin = 0x12;
926 spec->auto_mic = 1;
927}
928
929#define alc663_g50v_setup alc663_m51va_setup
930
931static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
932 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
933 ALC262_HIPPO_MASTER_SWITCH,
934
935 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
936 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
937 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
938
939 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
940 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
941 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
942 { } /* end */
943};
944
945static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
946 /* Master Playback automatically created from Speaker and Headphone */
947 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
948 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
949 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
950 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
951
952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
955
956 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
957 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
958 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
959 { } /* end */
960};
961
962
963/*
964 * configuration and preset
965 */
966static const char * const alc662_models[ALC662_MODEL_LAST] = {
967 [ALC662_3ST_2ch_DIG] = "3stack-dig",
968 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
969 [ALC662_3ST_6ch] = "3stack-6ch",
970 [ALC662_5ST_DIG] = "5stack-dig",
971 [ALC662_LENOVO_101E] = "lenovo-101e",
972 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
973 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
974 [ALC662_ECS] = "ecs",
975 [ALC663_ASUS_M51VA] = "m51va",
976 [ALC663_ASUS_G71V] = "g71v",
977 [ALC663_ASUS_H13] = "h13",
978 [ALC663_ASUS_G50V] = "g50v",
979 [ALC663_ASUS_MODE1] = "asus-mode1",
980 [ALC662_ASUS_MODE2] = "asus-mode2",
981 [ALC663_ASUS_MODE3] = "asus-mode3",
982 [ALC663_ASUS_MODE4] = "asus-mode4",
983 [ALC663_ASUS_MODE5] = "asus-mode5",
984 [ALC663_ASUS_MODE6] = "asus-mode6",
985 [ALC663_ASUS_MODE7] = "asus-mode7",
986 [ALC663_ASUS_MODE8] = "asus-mode8",
987 [ALC272_DELL] = "dell",
988 [ALC272_DELL_ZM1] = "dell-zm1",
989 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
990 [ALC662_AUTO] = "auto",
991};
992
993static const struct snd_pci_quirk alc662_cfg_tbl[] = {
994 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
995 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
996 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
997 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
998 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
999 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
1000 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
1001 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
1002 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
1003 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
1004 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
1005 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
1006 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
1007 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
1008 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
1009 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
1010 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
1011 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
1012 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
1013 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
1014 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
1015 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
1016 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
1017 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
1018 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
1019 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
1020 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
1021 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
1022 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
1023 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
1024 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
1025 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
1026 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
1027 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
1028 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
1029 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
1030 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
1031 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
1032 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
1033 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
1034 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
1035 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
1036 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
1037 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
1038 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
1039 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
1040 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
1041 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
1042 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
1043 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
1044 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
1045 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
1046 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
1047 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
1048 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
1049 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
1050 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
1051 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
1052 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
1053 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
1054 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
1055 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
1056 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
1057 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
1058 ALC662_3ST_6ch_DIG),
1059 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
1060 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
1061 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
1062 ALC662_3ST_6ch_DIG),
1063 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
1064 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
1065 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
1066 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
1067 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
1068 ALC662_3ST_6ch_DIG),
1069 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
1070 ALC663_ASUS_H13),
1071 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
1072 {}
1073};
1074
1075static const struct alc_config_preset alc662_presets[] = {
1076 [ALC662_3ST_2ch_DIG] = {
1077 .mixers = { alc662_3ST_2ch_mixer },
1078 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1079 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1080 .dac_nids = alc662_dac_nids,
1081 .dig_out_nid = ALC662_DIGOUT_NID,
1082 .dig_in_nid = ALC662_DIGIN_NID,
1083 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1084 .channel_mode = alc662_3ST_2ch_modes,
1085 .input_mux = &alc662_capture_source,
1086 },
1087 [ALC662_3ST_6ch_DIG] = {
1088 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
1089 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1090 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1091 .dac_nids = alc662_dac_nids,
1092 .dig_out_nid = ALC662_DIGOUT_NID,
1093 .dig_in_nid = ALC662_DIGIN_NID,
1094 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1095 .channel_mode = alc662_3ST_6ch_modes,
1096 .need_dac_fix = 1,
1097 .input_mux = &alc662_capture_source,
1098 },
1099 [ALC662_3ST_6ch] = {
1100 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
1101 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1102 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1103 .dac_nids = alc662_dac_nids,
1104 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1105 .channel_mode = alc662_3ST_6ch_modes,
1106 .need_dac_fix = 1,
1107 .input_mux = &alc662_capture_source,
1108 },
1109 [ALC662_5ST_DIG] = {
1110 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
1111 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1112 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1113 .dac_nids = alc662_dac_nids,
1114 .dig_out_nid = ALC662_DIGOUT_NID,
1115 .dig_in_nid = ALC662_DIGIN_NID,
1116 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
1117 .channel_mode = alc662_5stack_modes,
1118 .input_mux = &alc662_capture_source,
1119 },
1120 [ALC662_LENOVO_101E] = {
1121 .mixers = { alc662_lenovo_101e_mixer },
1122 .init_verbs = { alc662_init_verbs,
1123 alc662_eapd_init_verbs,
1124 alc662_sue_init_verbs },
1125 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1126 .dac_nids = alc662_dac_nids,
1127 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1128 .channel_mode = alc662_3ST_2ch_modes,
1129 .input_mux = &alc662_lenovo_101e_capture_source,
1130 .unsol_event = alc_sku_unsol_event,
1131 .setup = alc662_lenovo_101e_setup,
1132 .init_hook = alc_inithook,
1133 },
1134 [ALC662_ASUS_EEEPC_P701] = {
1135 .mixers = { alc662_eeepc_p701_mixer },
1136 .init_verbs = { alc662_init_verbs,
1137 alc662_eapd_init_verbs,
1138 alc662_eeepc_sue_init_verbs },
1139 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1140 .dac_nids = alc662_dac_nids,
1141 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1142 .channel_mode = alc662_3ST_2ch_modes,
1143 .unsol_event = alc_sku_unsol_event,
1144 .setup = alc662_eeepc_setup,
1145 .init_hook = alc_inithook,
1146 },
1147 [ALC662_ASUS_EEEPC_EP20] = {
1148 .mixers = { alc662_eeepc_ep20_mixer,
1149 alc662_chmode_mixer },
1150 .init_verbs = { alc662_init_verbs,
1151 alc662_eapd_init_verbs,
1152 alc662_eeepc_ep20_sue_init_verbs },
1153 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1154 .dac_nids = alc662_dac_nids,
1155 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1156 .channel_mode = alc662_3ST_6ch_modes,
1157 .input_mux = &alc662_lenovo_101e_capture_source,
1158 .unsol_event = alc_sku_unsol_event,
1159 .setup = alc662_eeepc_ep20_setup,
1160 .init_hook = alc_inithook,
1161 },
1162 [ALC662_ECS] = {
1163 .mixers = { alc662_ecs_mixer },
1164 .init_verbs = { alc662_init_verbs,
1165 alc662_eapd_init_verbs,
1166 alc662_ecs_init_verbs },
1167 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1168 .dac_nids = alc662_dac_nids,
1169 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1170 .channel_mode = alc662_3ST_2ch_modes,
1171 .unsol_event = alc_sku_unsol_event,
1172 .setup = alc662_eeepc_setup,
1173 .init_hook = alc_inithook,
1174 },
1175 [ALC663_ASUS_M51VA] = {
1176 .mixers = { alc663_m51va_mixer },
1177 .init_verbs = { alc662_init_verbs,
1178 alc662_eapd_init_verbs,
1179 alc663_m51va_init_verbs },
1180 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1181 .dac_nids = alc662_dac_nids,
1182 .dig_out_nid = ALC662_DIGOUT_NID,
1183 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1184 .channel_mode = alc662_3ST_2ch_modes,
1185 .unsol_event = alc_sku_unsol_event,
1186 .setup = alc663_m51va_setup,
1187 .init_hook = alc_inithook,
1188 },
1189 [ALC663_ASUS_G71V] = {
1190 .mixers = { alc663_g71v_mixer },
1191 .init_verbs = { alc662_init_verbs,
1192 alc662_eapd_init_verbs,
1193 alc663_g71v_init_verbs },
1194 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1195 .dac_nids = alc662_dac_nids,
1196 .dig_out_nid = ALC662_DIGOUT_NID,
1197 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1198 .channel_mode = alc662_3ST_2ch_modes,
1199 .unsol_event = alc_sku_unsol_event,
1200 .setup = alc663_g71v_setup,
1201 .init_hook = alc_inithook,
1202 },
1203 [ALC663_ASUS_H13] = {
1204 .mixers = { alc663_m51va_mixer },
1205 .init_verbs = { alc662_init_verbs,
1206 alc662_eapd_init_verbs,
1207 alc663_m51va_init_verbs },
1208 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1209 .dac_nids = alc662_dac_nids,
1210 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1211 .channel_mode = alc662_3ST_2ch_modes,
1212 .setup = alc663_m51va_setup,
1213 .unsol_event = alc_sku_unsol_event,
1214 .init_hook = alc_inithook,
1215 },
1216 [ALC663_ASUS_G50V] = {
1217 .mixers = { alc663_g50v_mixer },
1218 .init_verbs = { alc662_init_verbs,
1219 alc662_eapd_init_verbs,
1220 alc663_g50v_init_verbs },
1221 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1222 .dac_nids = alc662_dac_nids,
1223 .dig_out_nid = ALC662_DIGOUT_NID,
1224 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1225 .channel_mode = alc662_3ST_6ch_modes,
1226 .input_mux = &alc663_capture_source,
1227 .unsol_event = alc_sku_unsol_event,
1228 .setup = alc663_g50v_setup,
1229 .init_hook = alc_inithook,
1230 },
1231 [ALC663_ASUS_MODE1] = {
1232 .mixers = { alc663_m51va_mixer },
1233 .cap_mixer = alc662_auto_capture_mixer,
1234 .init_verbs = { alc662_init_verbs,
1235 alc662_eapd_init_verbs,
1236 alc663_21jd_amic_init_verbs },
1237 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1238 .hp_nid = 0x03,
1239 .dac_nids = alc662_dac_nids,
1240 .dig_out_nid = ALC662_DIGOUT_NID,
1241 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1242 .channel_mode = alc662_3ST_2ch_modes,
1243 .unsol_event = alc_sku_unsol_event,
1244 .setup = alc663_mode1_setup,
1245 .init_hook = alc_inithook,
1246 },
1247 [ALC662_ASUS_MODE2] = {
1248 .mixers = { alc662_1bjd_mixer },
1249 .cap_mixer = alc662_auto_capture_mixer,
1250 .init_verbs = { alc662_init_verbs,
1251 alc662_eapd_init_verbs,
1252 alc662_1bjd_amic_init_verbs },
1253 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1254 .dac_nids = alc662_dac_nids,
1255 .dig_out_nid = ALC662_DIGOUT_NID,
1256 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1257 .channel_mode = alc662_3ST_2ch_modes,
1258 .unsol_event = alc_sku_unsol_event,
1259 .setup = alc662_mode2_setup,
1260 .init_hook = alc_inithook,
1261 },
1262 [ALC663_ASUS_MODE3] = {
1263 .mixers = { alc663_two_hp_m1_mixer },
1264 .cap_mixer = alc662_auto_capture_mixer,
1265 .init_verbs = { alc662_init_verbs,
1266 alc662_eapd_init_verbs,
1267 alc663_two_hp_amic_m1_init_verbs },
1268 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1269 .hp_nid = 0x03,
1270 .dac_nids = alc662_dac_nids,
1271 .dig_out_nid = ALC662_DIGOUT_NID,
1272 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1273 .channel_mode = alc662_3ST_2ch_modes,
1274 .unsol_event = alc_sku_unsol_event,
1275 .setup = alc663_mode3_setup,
1276 .init_hook = alc_inithook,
1277 },
1278 [ALC663_ASUS_MODE4] = {
1279 .mixers = { alc663_asus_21jd_clfe_mixer },
1280 .cap_mixer = alc662_auto_capture_mixer,
1281 .init_verbs = { alc662_init_verbs,
1282 alc662_eapd_init_verbs,
1283 alc663_21jd_amic_init_verbs},
1284 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1285 .hp_nid = 0x03,
1286 .dac_nids = alc662_dac_nids,
1287 .dig_out_nid = ALC662_DIGOUT_NID,
1288 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1289 .channel_mode = alc662_3ST_2ch_modes,
1290 .unsol_event = alc_sku_unsol_event,
1291 .setup = alc663_mode4_setup,
1292 .init_hook = alc_inithook,
1293 },
1294 [ALC663_ASUS_MODE5] = {
1295 .mixers = { alc663_asus_15jd_clfe_mixer },
1296 .cap_mixer = alc662_auto_capture_mixer,
1297 .init_verbs = { alc662_init_verbs,
1298 alc662_eapd_init_verbs,
1299 alc663_15jd_amic_init_verbs },
1300 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1301 .hp_nid = 0x03,
1302 .dac_nids = alc662_dac_nids,
1303 .dig_out_nid = ALC662_DIGOUT_NID,
1304 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1305 .channel_mode = alc662_3ST_2ch_modes,
1306 .unsol_event = alc_sku_unsol_event,
1307 .setup = alc663_mode5_setup,
1308 .init_hook = alc_inithook,
1309 },
1310 [ALC663_ASUS_MODE6] = {
1311 .mixers = { alc663_two_hp_m2_mixer },
1312 .cap_mixer = alc662_auto_capture_mixer,
1313 .init_verbs = { alc662_init_verbs,
1314 alc662_eapd_init_verbs,
1315 alc663_two_hp_amic_m2_init_verbs },
1316 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1317 .hp_nid = 0x03,
1318 .dac_nids = alc662_dac_nids,
1319 .dig_out_nid = ALC662_DIGOUT_NID,
1320 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1321 .channel_mode = alc662_3ST_2ch_modes,
1322 .unsol_event = alc_sku_unsol_event,
1323 .setup = alc663_mode6_setup,
1324 .init_hook = alc_inithook,
1325 },
1326 [ALC663_ASUS_MODE7] = {
1327 .mixers = { alc663_mode7_mixer },
1328 .cap_mixer = alc662_auto_capture_mixer,
1329 .init_verbs = { alc662_init_verbs,
1330 alc662_eapd_init_verbs,
1331 alc663_mode7_init_verbs },
1332 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1333 .hp_nid = 0x03,
1334 .dac_nids = alc662_dac_nids,
1335 .dig_out_nid = ALC662_DIGOUT_NID,
1336 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1337 .channel_mode = alc662_3ST_2ch_modes,
1338 .unsol_event = alc_sku_unsol_event,
1339 .setup = alc663_mode7_setup,
1340 .init_hook = alc_inithook,
1341 },
1342 [ALC663_ASUS_MODE8] = {
1343 .mixers = { alc663_mode8_mixer },
1344 .cap_mixer = alc662_auto_capture_mixer,
1345 .init_verbs = { alc662_init_verbs,
1346 alc662_eapd_init_verbs,
1347 alc663_mode8_init_verbs },
1348 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1349 .hp_nid = 0x03,
1350 .dac_nids = alc662_dac_nids,
1351 .dig_out_nid = ALC662_DIGOUT_NID,
1352 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1353 .channel_mode = alc662_3ST_2ch_modes,
1354 .unsol_event = alc_sku_unsol_event,
1355 .setup = alc663_mode8_setup,
1356 .init_hook = alc_inithook,
1357 },
1358 [ALC272_DELL] = {
1359 .mixers = { alc663_m51va_mixer },
1360 .cap_mixer = alc272_auto_capture_mixer,
1361 .init_verbs = { alc662_init_verbs,
1362 alc662_eapd_init_verbs,
1363 alc272_dell_init_verbs },
1364 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1365 .dac_nids = alc272_dac_nids,
1366 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1367 .adc_nids = alc272_adc_nids,
1368 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
1369 .capsrc_nids = alc272_capsrc_nids,
1370 .channel_mode = alc662_3ST_2ch_modes,
1371 .unsol_event = alc_sku_unsol_event,
1372 .setup = alc663_m51va_setup,
1373 .init_hook = alc_inithook,
1374 },
1375 [ALC272_DELL_ZM1] = {
1376 .mixers = { alc663_m51va_mixer },
1377 .cap_mixer = alc662_auto_capture_mixer,
1378 .init_verbs = { alc662_init_verbs,
1379 alc662_eapd_init_verbs,
1380 alc272_dell_zm1_init_verbs },
1381 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1382 .dac_nids = alc272_dac_nids,
1383 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1384 .adc_nids = alc662_adc_nids,
1385 .num_adc_nids = 1,
1386 .capsrc_nids = alc662_capsrc_nids,
1387 .channel_mode = alc662_3ST_2ch_modes,
1388 .unsol_event = alc_sku_unsol_event,
1389 .setup = alc663_m51va_setup,
1390 .init_hook = alc_inithook,
1391 },
1392 [ALC272_SAMSUNG_NC10] = {
1393 .mixers = { alc272_nc10_mixer },
1394 .init_verbs = { alc662_init_verbs,
1395 alc662_eapd_init_verbs,
1396 alc663_21jd_amic_init_verbs },
1397 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1398 .dac_nids = alc272_dac_nids,
1399 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1400 .channel_mode = alc662_3ST_2ch_modes,
1401 /*.input_mux = &alc272_nc10_capture_source,*/
1402 .unsol_event = alc_sku_unsol_event,
1403 .setup = alc663_mode4_setup,
1404 .init_hook = alc_inithook,
1405 },
1406};
1407
1408
diff --git a/sound/pci/hda/alc680_quirks.c b/sound/pci/hda/alc680_quirks.c
new file mode 100644
index 00000000000..0eeb227c7bc
--- /dev/null
+++ b/sound/pci/hda/alc680_quirks.c
@@ -0,0 +1,222 @@
1/*
2 * ALC680 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC680 models */
7enum {
8 ALC680_AUTO,
9 ALC680_BASE,
10 ALC680_MODEL_LAST,
11};
12
13#define ALC680_DIGIN_NID ALC880_DIGIN_NID
14#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
15#define alc680_modes alc260_modes
16
17static const hda_nid_t alc680_dac_nids[3] = {
18 /* Lout1, Lout2, hp */
19 0x02, 0x03, 0x04
20};
21
22static const hda_nid_t alc680_adc_nids[3] = {
23 /* ADC0-2 */
24 /* DMIC, MIC, Line-in*/
25 0x07, 0x08, 0x09
26};
27
28/*
29 * Analog capture ADC cgange
30 */
31static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
32{
33 static hda_nid_t pins[] = {0x18, 0x19};
34 static hda_nid_t adcs[] = {0x08, 0x09};
35 int i;
36
37 for (i = 0; i < ARRAY_SIZE(pins); i++) {
38 if (!is_jack_detectable(codec, pins[i]))
39 continue;
40 if (snd_hda_jack_detect(codec, pins[i]))
41 return adcs[i];
42 }
43 return 0x07;
44}
45
46static void alc680_rec_autoswitch(struct hda_codec *codec)
47{
48 struct alc_spec *spec = codec->spec;
49 hda_nid_t nid = alc680_get_cur_adc(codec);
50 if (spec->cur_adc && nid != spec->cur_adc) {
51 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
52 spec->cur_adc = nid;
53 snd_hda_codec_setup_stream(codec, nid,
54 spec->cur_adc_stream_tag, 0,
55 spec->cur_adc_format);
56 }
57}
58
59static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
60 struct hda_codec *codec,
61 unsigned int stream_tag,
62 unsigned int format,
63 struct snd_pcm_substream *substream)
64{
65 struct alc_spec *spec = codec->spec;
66 hda_nid_t nid = alc680_get_cur_adc(codec);
67
68 spec->cur_adc = nid;
69 spec->cur_adc_stream_tag = stream_tag;
70 spec->cur_adc_format = format;
71 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
72 return 0;
73}
74
75static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
76 struct hda_codec *codec,
77 struct snd_pcm_substream *substream)
78{
79 struct alc_spec *spec = codec->spec;
80 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
81 spec->cur_adc = 0;
82 return 0;
83}
84
85static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
86 .substreams = 1, /* can be overridden */
87 .channels_min = 2,
88 .channels_max = 2,
89 /* NID is set in alc_build_pcms */
90 .ops = {
91 .prepare = alc680_capture_pcm_prepare,
92 .cleanup = alc680_capture_pcm_cleanup
93 },
94};
95
96static const struct snd_kcontrol_new alc680_base_mixer[] = {
97 /* output mixer control */
98 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
99 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
100 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
101 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
102 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
103 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
104 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
105 { }
106};
107
108static const struct hda_bind_ctls alc680_bind_cap_vol = {
109 .ops = &snd_hda_bind_vol,
110 .values = {
111 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
112 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
113 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
114 0
115 },
116};
117
118static const struct hda_bind_ctls alc680_bind_cap_switch = {
119 .ops = &snd_hda_bind_sw,
120 .values = {
121 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
122 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
123 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
124 0
125 },
126};
127
128static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
129 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
130 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
131 { } /* end */
132};
133
134/*
135 * generic initialization of ADC, input mixers and output mixers
136 */
137static const struct hda_verb alc680_init_verbs[] = {
138 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
139 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
140 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
141
142 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
146 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
147 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
148
149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
150 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
151 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
152 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
153 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
154
155 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
156 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
157 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
158
159 { }
160};
161
162/* toggle speaker-output according to the hp-jack state */
163static void alc680_base_setup(struct hda_codec *codec)
164{
165 struct alc_spec *spec = codec->spec;
166
167 spec->autocfg.hp_pins[0] = 0x16;
168 spec->autocfg.speaker_pins[0] = 0x14;
169 spec->autocfg.speaker_pins[1] = 0x15;
170 spec->autocfg.num_inputs = 2;
171 spec->autocfg.inputs[0].pin = 0x18;
172 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
173 spec->autocfg.inputs[1].pin = 0x19;
174 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
175 spec->automute = 1;
176 spec->automute_mode = ALC_AUTOMUTE_AMP;
177}
178
179static void alc680_unsol_event(struct hda_codec *codec,
180 unsigned int res)
181{
182 if ((res >> 26) == ALC_HP_EVENT)
183 alc_hp_automute(codec);
184 if ((res >> 26) == ALC_MIC_EVENT)
185 alc680_rec_autoswitch(codec);
186}
187
188static void alc680_inithook(struct hda_codec *codec)
189{
190 alc_hp_automute(codec);
191 alc680_rec_autoswitch(codec);
192}
193
194/*
195 * configuration and preset
196 */
197static const char * const alc680_models[ALC680_MODEL_LAST] = {
198 [ALC680_BASE] = "base",
199 [ALC680_AUTO] = "auto",
200};
201
202static const struct snd_pci_quirk alc680_cfg_tbl[] = {
203 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
204 {}
205};
206
207static const struct alc_config_preset alc680_presets[] = {
208 [ALC680_BASE] = {
209 .mixers = { alc680_base_mixer },
210 .cap_mixer = alc680_master_capture_mixer,
211 .init_verbs = { alc680_init_verbs },
212 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
213 .dac_nids = alc680_dac_nids,
214 .dig_out_nid = ALC680_DIGOUT_NID,
215 .num_channel_mode = ARRAY_SIZE(alc680_modes),
216 .channel_mode = alc680_modes,
217 .unsol_event = alc680_unsol_event,
218 .setup = alc680_base_setup,
219 .init_hook = alc680_inithook,
220
221 },
222};
diff --git a/sound/pci/hda/alc861_quirks.c b/sound/pci/hda/alc861_quirks.c
new file mode 100644
index 00000000000..d719ec6350e
--- /dev/null
+++ b/sound/pci/hda/alc861_quirks.c
@@ -0,0 +1,725 @@
1/*
2 * ALC660/ALC861 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC861 models */
7enum {
8 ALC861_AUTO,
9 ALC861_3ST,
10 ALC660_3ST,
11 ALC861_3ST_DIG,
12 ALC861_6ST_DIG,
13 ALC861_UNIWILL_M31,
14 ALC861_TOSHIBA,
15 ALC861_ASUS,
16 ALC861_ASUS_LAPTOP,
17 ALC861_MODEL_LAST,
18};
19
20/*
21 * ALC861 channel source setting (2/6 channel selection for 3-stack)
22 */
23
24/*
25 * set the path ways for 2 channel output
26 * need to set the codec line out and mic 1 pin widgets to inputs
27 */
28static const struct hda_verb alc861_threestack_ch2_init[] = {
29 /* set pin widget 1Ah (line in) for input */
30 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
31 /* set pin widget 18h (mic1/2) for input, for mic also enable
32 * the vref
33 */
34 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
35
36 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
37#if 0
38 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
39 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
40#endif
41 { } /* end */
42};
43/*
44 * 6ch mode
45 * need to set the codec line out and mic 1 pin widgets to outputs
46 */
47static const struct hda_verb alc861_threestack_ch6_init[] = {
48 /* set pin widget 1Ah (line in) for output (Back Surround)*/
49 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
50 /* set pin widget 18h (mic1) for output (CLFE)*/
51 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
52
53 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
54 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
55
56 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
57#if 0
58 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
59 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
60#endif
61 { } /* end */
62};
63
64static const struct hda_channel_mode alc861_threestack_modes[2] = {
65 { 2, alc861_threestack_ch2_init },
66 { 6, alc861_threestack_ch6_init },
67};
68/* Set mic1 as input and unmute the mixer */
69static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
70 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
71 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
72 { } /* end */
73};
74/* Set mic1 as output and mute mixer */
75static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
76 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
77 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
78 { } /* end */
79};
80
81static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
82 { 2, alc861_uniwill_m31_ch2_init },
83 { 4, alc861_uniwill_m31_ch4_init },
84};
85
86/* Set mic1 and line-in as input and unmute the mixer */
87static const struct hda_verb alc861_asus_ch2_init[] = {
88 /* set pin widget 1Ah (line in) for input */
89 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
90 /* set pin widget 18h (mic1/2) for input, for mic also enable
91 * the vref
92 */
93 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
94
95 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
96#if 0
97 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
98 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
99#endif
100 { } /* end */
101};
102/* Set mic1 nad line-in as output and mute mixer */
103static const struct hda_verb alc861_asus_ch6_init[] = {
104 /* set pin widget 1Ah (line in) for output (Back Surround)*/
105 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
106 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
107 /* set pin widget 18h (mic1) for output (CLFE)*/
108 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
109 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
110 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
111 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
112
113 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
114#if 0
115 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
116 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
117#endif
118 { } /* end */
119};
120
121static const struct hda_channel_mode alc861_asus_modes[2] = {
122 { 2, alc861_asus_ch2_init },
123 { 6, alc861_asus_ch6_init },
124};
125
126/* patch-ALC861 */
127
128static const struct snd_kcontrol_new alc861_base_mixer[] = {
129 /* output mixer control */
130 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
131 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
132 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
133 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
134 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
135
136 /*Input mixer control */
137 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
138 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
139 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
140 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
141 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
142 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
144 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
147
148 { } /* end */
149};
150
151static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
152 /* output mixer control */
153 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
154 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
155 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
156 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
157 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
158
159 /* Input mixer control */
160 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
161 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
162 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
163 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
164 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
165 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
168 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
170
171 {
172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
173 .name = "Channel Mode",
174 .info = alc_ch_mode_info,
175 .get = alc_ch_mode_get,
176 .put = alc_ch_mode_put,
177 .private_value = ARRAY_SIZE(alc861_threestack_modes),
178 },
179 { } /* end */
180};
181
182static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
183 /* output mixer control */
184 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
186 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
187
188 { } /* end */
189};
190
191static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
192 /* output mixer control */
193 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
194 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
196 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
197 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
198
199 /* Input mixer control */
200 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
201 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
202 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
203 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
204 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
205 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
207 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
208 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
210
211 {
212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
213 .name = "Channel Mode",
214 .info = alc_ch_mode_info,
215 .get = alc_ch_mode_get,
216 .put = alc_ch_mode_put,
217 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
218 },
219 { } /* end */
220};
221
222static const struct snd_kcontrol_new alc861_asus_mixer[] = {
223 /* output mixer control */
224 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
225 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
226 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
227 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
228 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
229
230 /* Input mixer control */
231 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
232 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
233 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
234 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
235 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
236 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
238 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
239 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
240 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
241
242 {
243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
244 .name = "Channel Mode",
245 .info = alc_ch_mode_info,
246 .get = alc_ch_mode_get,
247 .put = alc_ch_mode_put,
248 .private_value = ARRAY_SIZE(alc861_asus_modes),
249 },
250 { }
251};
252
253/* additional mixer */
254static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
255 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
256 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
257 { }
258};
259
260/*
261 * generic initialization of ADC, input mixers and output mixers
262 */
263static const struct hda_verb alc861_base_init_verbs[] = {
264 /*
265 * Unmute ADC0 and set the default input to mic-in
266 */
267 /* port-A for surround (rear panel) */
268 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
269 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
270 /* port-B for mic-in (rear panel) with vref */
271 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
272 /* port-C for line-in (rear panel) */
273 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
274 /* port-D for Front */
275 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
276 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
277 /* port-E for HP out (front panel) */
278 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
279 /* route front PCM to HP */
280 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
281 /* port-F for mic-in (front panel) with vref */
282 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
283 /* port-G for CLFE (rear panel) */
284 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
285 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
286 /* port-H for side (rear panel) */
287 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
288 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
289 /* CD-in */
290 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
291 /* route front mic to ADC1*/
292 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
293 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
294
295 /* Unmute DAC0~3 & spdif out*/
296 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
297 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
298 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
299 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
300 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
301
302 /* Unmute Mixer 14 (mic) 1c (Line in)*/
303 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
304 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
305 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
306 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
307
308 /* Unmute Stereo Mixer 15 */
309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
310 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
311 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
312 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
313
314 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
315 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
316 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
317 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
318 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
320 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
321 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
322 /* hp used DAC 3 (Front) */
323 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
324 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
325
326 { }
327};
328
329static const struct hda_verb alc861_threestack_init_verbs[] = {
330 /*
331 * Unmute ADC0 and set the default input to mic-in
332 */
333 /* port-A for surround (rear panel) */
334 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
335 /* port-B for mic-in (rear panel) with vref */
336 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
337 /* port-C for line-in (rear panel) */
338 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
339 /* port-D for Front */
340 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
341 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
342 /* port-E for HP out (front panel) */
343 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
344 /* route front PCM to HP */
345 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
346 /* port-F for mic-in (front panel) with vref */
347 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
348 /* port-G for CLFE (rear panel) */
349 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
350 /* port-H for side (rear panel) */
351 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
352 /* CD-in */
353 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
354 /* route front mic to ADC1*/
355 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
357 /* Unmute DAC0~3 & spdif out*/
358 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
359 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
360 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
361 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
363
364 /* Unmute Mixer 14 (mic) 1c (Line in)*/
365 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
366 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
367 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
368 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
369
370 /* Unmute Stereo Mixer 15 */
371 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
374 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
375
376 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
377 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
378 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
379 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
381 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
382 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
383 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
384 /* hp used DAC 3 (Front) */
385 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
386 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
387 { }
388};
389
390static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
391 /*
392 * Unmute ADC0 and set the default input to mic-in
393 */
394 /* port-A for surround (rear panel) */
395 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
396 /* port-B for mic-in (rear panel) with vref */
397 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
398 /* port-C for line-in (rear panel) */
399 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
400 /* port-D for Front */
401 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
402 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
403 /* port-E for HP out (front panel) */
404 /* this has to be set to VREF80 */
405 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
406 /* route front PCM to HP */
407 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
408 /* port-F for mic-in (front panel) with vref */
409 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
410 /* port-G for CLFE (rear panel) */
411 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
412 /* port-H for side (rear panel) */
413 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
414 /* CD-in */
415 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
416 /* route front mic to ADC1*/
417 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
418 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
419 /* Unmute DAC0~3 & spdif out*/
420 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
421 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
422 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
423 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
425
426 /* Unmute Mixer 14 (mic) 1c (Line in)*/
427 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
428 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
429 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
430 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
431
432 /* Unmute Stereo Mixer 15 */
433 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
435 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
437
438 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
439 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
440 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
441 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
442 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
443 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
445 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
446 /* hp used DAC 3 (Front) */
447 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
448 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
449 { }
450};
451
452static const struct hda_verb alc861_asus_init_verbs[] = {
453 /*
454 * Unmute ADC0 and set the default input to mic-in
455 */
456 /* port-A for surround (rear panel)
457 * according to codec#0 this is the HP jack
458 */
459 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
460 /* route front PCM to HP */
461 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
462 /* port-B for mic-in (rear panel) with vref */
463 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
464 /* port-C for line-in (rear panel) */
465 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
466 /* port-D for Front */
467 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
468 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
469 /* port-E for HP out (front panel) */
470 /* this has to be set to VREF80 */
471 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
472 /* route front PCM to HP */
473 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
474 /* port-F for mic-in (front panel) with vref */
475 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
476 /* port-G for CLFE (rear panel) */
477 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
478 /* port-H for side (rear panel) */
479 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
480 /* CD-in */
481 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
482 /* route front mic to ADC1*/
483 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
485 /* Unmute DAC0~3 & spdif out*/
486 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
487 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
488 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
489 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
491 /* Unmute Mixer 14 (mic) 1c (Line in)*/
492 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
493 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
494 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
495 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
496
497 /* Unmute Stereo Mixer 15 */
498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
502
503 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
505 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
506 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
507 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
509 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
511 /* hp used DAC 3 (Front) */
512 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
514 { }
515};
516
517/* additional init verbs for ASUS laptops */
518static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
519 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
520 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
521 { }
522};
523
524static const struct hda_verb alc861_toshiba_init_verbs[] = {
525 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
526
527 { }
528};
529
530/* toggle speaker-output according to the hp-jack state */
531static void alc861_toshiba_automute(struct hda_codec *codec)
532{
533 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
534
535 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
536 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
537 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
538 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
539}
540
541static void alc861_toshiba_unsol_event(struct hda_codec *codec,
542 unsigned int res)
543{
544 if ((res >> 26) == ALC_HP_EVENT)
545 alc861_toshiba_automute(codec);
546}
547
548#define ALC861_DIGOUT_NID 0x07
549
550static const struct hda_channel_mode alc861_8ch_modes[1] = {
551 { 8, NULL }
552};
553
554static const hda_nid_t alc861_dac_nids[4] = {
555 /* front, surround, clfe, side */
556 0x03, 0x06, 0x05, 0x04
557};
558
559static const hda_nid_t alc660_dac_nids[3] = {
560 /* front, clfe, surround */
561 0x03, 0x05, 0x06
562};
563
564static const hda_nid_t alc861_adc_nids[1] = {
565 /* ADC0-2 */
566 0x08,
567};
568
569static const struct hda_input_mux alc861_capture_source = {
570 .num_items = 5,
571 .items = {
572 { "Mic", 0x0 },
573 { "Front Mic", 0x3 },
574 { "Line", 0x1 },
575 { "CD", 0x4 },
576 { "Mixer", 0x5 },
577 },
578};
579
580/*
581 * configuration and preset
582 */
583static const char * const alc861_models[ALC861_MODEL_LAST] = {
584 [ALC861_3ST] = "3stack",
585 [ALC660_3ST] = "3stack-660",
586 [ALC861_3ST_DIG] = "3stack-dig",
587 [ALC861_6ST_DIG] = "6stack-dig",
588 [ALC861_UNIWILL_M31] = "uniwill-m31",
589 [ALC861_TOSHIBA] = "toshiba",
590 [ALC861_ASUS] = "asus",
591 [ALC861_ASUS_LAPTOP] = "asus-laptop",
592 [ALC861_AUTO] = "auto",
593};
594
595static const struct snd_pci_quirk alc861_cfg_tbl[] = {
596 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
597 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
598 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
599 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
600 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
601 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
602 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
603 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
604 * Any other models that need this preset?
605 */
606 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
607 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
608 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
609 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
610 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
611 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
612 /* FIXME: the below seems conflict */
613 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
614 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
615 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
616 {}
617};
618
619static const struct alc_config_preset alc861_presets[] = {
620 [ALC861_3ST] = {
621 .mixers = { alc861_3ST_mixer },
622 .init_verbs = { alc861_threestack_init_verbs },
623 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
624 .dac_nids = alc861_dac_nids,
625 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
626 .channel_mode = alc861_threestack_modes,
627 .need_dac_fix = 1,
628 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
629 .adc_nids = alc861_adc_nids,
630 .input_mux = &alc861_capture_source,
631 },
632 [ALC861_3ST_DIG] = {
633 .mixers = { alc861_base_mixer },
634 .init_verbs = { alc861_threestack_init_verbs },
635 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
636 .dac_nids = alc861_dac_nids,
637 .dig_out_nid = ALC861_DIGOUT_NID,
638 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
639 .channel_mode = alc861_threestack_modes,
640 .need_dac_fix = 1,
641 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
642 .adc_nids = alc861_adc_nids,
643 .input_mux = &alc861_capture_source,
644 },
645 [ALC861_6ST_DIG] = {
646 .mixers = { alc861_base_mixer },
647 .init_verbs = { alc861_base_init_verbs },
648 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
649 .dac_nids = alc861_dac_nids,
650 .dig_out_nid = ALC861_DIGOUT_NID,
651 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
652 .channel_mode = alc861_8ch_modes,
653 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
654 .adc_nids = alc861_adc_nids,
655 .input_mux = &alc861_capture_source,
656 },
657 [ALC660_3ST] = {
658 .mixers = { alc861_3ST_mixer },
659 .init_verbs = { alc861_threestack_init_verbs },
660 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
661 .dac_nids = alc660_dac_nids,
662 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
663 .channel_mode = alc861_threestack_modes,
664 .need_dac_fix = 1,
665 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
666 .adc_nids = alc861_adc_nids,
667 .input_mux = &alc861_capture_source,
668 },
669 [ALC861_UNIWILL_M31] = {
670 .mixers = { alc861_uniwill_m31_mixer },
671 .init_verbs = { alc861_uniwill_m31_init_verbs },
672 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
673 .dac_nids = alc861_dac_nids,
674 .dig_out_nid = ALC861_DIGOUT_NID,
675 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
676 .channel_mode = alc861_uniwill_m31_modes,
677 .need_dac_fix = 1,
678 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
679 .adc_nids = alc861_adc_nids,
680 .input_mux = &alc861_capture_source,
681 },
682 [ALC861_TOSHIBA] = {
683 .mixers = { alc861_toshiba_mixer },
684 .init_verbs = { alc861_base_init_verbs,
685 alc861_toshiba_init_verbs },
686 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
687 .dac_nids = alc861_dac_nids,
688 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
689 .channel_mode = alc883_3ST_2ch_modes,
690 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
691 .adc_nids = alc861_adc_nids,
692 .input_mux = &alc861_capture_source,
693 .unsol_event = alc861_toshiba_unsol_event,
694 .init_hook = alc861_toshiba_automute,
695 },
696 [ALC861_ASUS] = {
697 .mixers = { alc861_asus_mixer },
698 .init_verbs = { alc861_asus_init_verbs },
699 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
700 .dac_nids = alc861_dac_nids,
701 .dig_out_nid = ALC861_DIGOUT_NID,
702 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
703 .channel_mode = alc861_asus_modes,
704 .need_dac_fix = 1,
705 .hp_nid = 0x06,
706 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
707 .adc_nids = alc861_adc_nids,
708 .input_mux = &alc861_capture_source,
709 },
710 [ALC861_ASUS_LAPTOP] = {
711 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
712 .init_verbs = { alc861_asus_init_verbs,
713 alc861_asus_laptop_init_verbs },
714 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
715 .dac_nids = alc861_dac_nids,
716 .dig_out_nid = ALC861_DIGOUT_NID,
717 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
718 .channel_mode = alc883_3ST_2ch_modes,
719 .need_dac_fix = 1,
720 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
721 .adc_nids = alc861_adc_nids,
722 .input_mux = &alc861_capture_source,
723 },
724};
725
diff --git a/sound/pci/hda/alc861vd_quirks.c b/sound/pci/hda/alc861vd_quirks.c
new file mode 100644
index 00000000000..8f28450f41f
--- /dev/null
+++ b/sound/pci/hda/alc861vd_quirks.c
@@ -0,0 +1,605 @@
1/*
2 * ALC660-VD/ALC861-VD quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC861-VD models */
7enum {
8 ALC861VD_AUTO,
9 ALC660VD_3ST,
10 ALC660VD_3ST_DIG,
11 ALC660VD_ASUS_V1S,
12 ALC861VD_3ST,
13 ALC861VD_3ST_DIG,
14 ALC861VD_6ST_DIG,
15 ALC861VD_LENOVO,
16 ALC861VD_DALLAS,
17 ALC861VD_HP,
18 ALC861VD_MODEL_LAST,
19};
20
21#define ALC861VD_DIGOUT_NID 0x06
22
23static const hda_nid_t alc861vd_dac_nids[4] = {
24 /* front, surr, clfe, side surr */
25 0x02, 0x03, 0x04, 0x05
26};
27
28/* dac_nids for ALC660vd are in a different order - according to
29 * Realtek's driver.
30 * This should probably result in a different mixer for 6stack models
31 * of ALC660vd codecs, but for now there is only 3stack mixer
32 * - and it is the same as in 861vd.
33 * adc_nids in ALC660vd are (is) the same as in 861vd
34 */
35static const hda_nid_t alc660vd_dac_nids[3] = {
36 /* front, rear, clfe, rear_surr */
37 0x02, 0x04, 0x03
38};
39
40static const hda_nid_t alc861vd_adc_nids[1] = {
41 /* ADC0 */
42 0x09,
43};
44
45static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
46
47/* input MUX */
48/* FIXME: should be a matrix-type input source selection */
49static const struct hda_input_mux alc861vd_capture_source = {
50 .num_items = 4,
51 .items = {
52 { "Mic", 0x0 },
53 { "Front Mic", 0x1 },
54 { "Line", 0x2 },
55 { "CD", 0x4 },
56 },
57};
58
59static const struct hda_input_mux alc861vd_dallas_capture_source = {
60 .num_items = 2,
61 .items = {
62 { "Mic", 0x0 },
63 { "Internal Mic", 0x1 },
64 },
65};
66
67static const struct hda_input_mux alc861vd_hp_capture_source = {
68 .num_items = 2,
69 .items = {
70 { "Front Mic", 0x0 },
71 { "ATAPI Mic", 0x1 },
72 },
73};
74
75/*
76 * 2ch mode
77 */
78static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
79 { 2, NULL }
80};
81
82/*
83 * 6ch mode
84 */
85static const struct hda_verb alc861vd_6stack_ch6_init[] = {
86 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
87 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
88 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
89 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
90 { } /* end */
91};
92
93/*
94 * 8ch mode
95 */
96static const struct hda_verb alc861vd_6stack_ch8_init[] = {
97 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
98 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
99 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
100 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
101 { } /* end */
102};
103
104static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
105 { 6, alc861vd_6stack_ch6_init },
106 { 8, alc861vd_6stack_ch8_init },
107};
108
109static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
110 {
111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
112 .name = "Channel Mode",
113 .info = alc_ch_mode_info,
114 .get = alc_ch_mode_get,
115 .put = alc_ch_mode_put,
116 },
117 { } /* end */
118};
119
120/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
121 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
122 */
123static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
124 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
125 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
126
127 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
128 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
129
130 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
131 HDA_OUTPUT),
132 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
133 HDA_OUTPUT),
134 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
135 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
136
137 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
138 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
139
140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
141
142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
145
146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
147 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
149
150 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
151 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
152
153 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
154 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
155
156 { } /* end */
157};
158
159static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
160 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
161 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
162
163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
164
165 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
168
169 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
170 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
171 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
172
173 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
174 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
175
176 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
177 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
178
179 { } /* end */
180};
181
182static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
183 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
184 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
185 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
186
187 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
188
189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
192
193 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
196
197 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
198 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
199
200 { } /* end */
201};
202
203/* Pin assignment: Speaker=0x14, HP = 0x15,
204 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
205 */
206static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
207 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
208 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
209 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
214 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
215 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
216 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
217 { } /* end */
218};
219
220/* Pin assignment: Speaker=0x14, Line-out = 0x15,
221 * Front Mic=0x18, ATAPI Mic = 0x19,
222 */
223static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
224 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
225 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
227 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
230 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
231 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
232
233 { } /* end */
234};
235
236/*
237 * generic initialization of ADC, input mixers and output mixers
238 */
239static const struct hda_verb alc861vd_volume_init_verbs[] = {
240 /*
241 * Unmute ADC0 and set the default input to mic-in
242 */
243 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
245
246 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
247 * the analog-loopback mixer widget
248 */
249 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
255
256 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
257 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
261
262 /*
263 * Set up output mixers (0x02 - 0x05)
264 */
265 /* set vol=0 to output mixers */
266 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
267 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
268 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
269 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
270
271 /* set up input amps for analog loopback */
272 /* Amp Indices: DAC = 0, mixer = 1 */
273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
274 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
275 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
276 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
278 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
279 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
280 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
281
282 { }
283};
284
285/*
286 * 3-stack pin configuration:
287 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
288 */
289static const struct hda_verb alc861vd_3stack_init_verbs[] = {
290 /*
291 * Set pin mode and muting
292 */
293 /* set front pin widgets 0x14 for output */
294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
296 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
297
298 /* Mic (rear) pin: input vref at 80% */
299 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
300 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
301 /* Front Mic pin: input vref at 80% */
302 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
303 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
304 /* Line In pin: input */
305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
307 /* Line-2 In: Headphone output (output 0 - 0x0c) */
308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
311 /* CD pin widget for input */
312 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
313
314 { }
315};
316
317/*
318 * 6-stack pin configuration:
319 */
320static const struct hda_verb alc861vd_6stack_init_verbs[] = {
321 /*
322 * Set pin mode and muting
323 */
324 /* set front pin widgets 0x14 for output */
325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
327 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
328
329 /* Rear Pin: output 1 (0x0d) */
330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
333 /* CLFE Pin: output 2 (0x0e) */
334 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
336 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
337 /* Side Pin: output 3 (0x0f) */
338 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
340 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
341
342 /* Mic (rear) pin: input vref at 80% */
343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
344 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
345 /* Front Mic pin: input vref at 80% */
346 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
347 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
348 /* Line In pin: input */
349 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
350 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
351 /* Line-2 In: Headphone output (output 0 - 0x0c) */
352 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
353 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
354 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
355 /* CD pin widget for input */
356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
357
358 { }
359};
360
361static const struct hda_verb alc861vd_eapd_verbs[] = {
362 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
363 { }
364};
365
366static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
370 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
371 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
372 {}
373};
374
375static void alc861vd_lenovo_setup(struct hda_codec *codec)
376{
377 struct alc_spec *spec = codec->spec;
378 spec->autocfg.hp_pins[0] = 0x1b;
379 spec->autocfg.speaker_pins[0] = 0x14;
380 spec->automute = 1;
381 spec->automute_mode = ALC_AUTOMUTE_AMP;
382}
383
384static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
385{
386 alc_hp_automute(codec);
387 alc88x_simple_mic_automute(codec);
388}
389
390static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
391 unsigned int res)
392{
393 switch (res >> 26) {
394 case ALC_MIC_EVENT:
395 alc88x_simple_mic_automute(codec);
396 break;
397 default:
398 alc_sku_unsol_event(codec, res);
399 break;
400 }
401}
402
403static const struct hda_verb alc861vd_dallas_verbs[] = {
404 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
405 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
406 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
407 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
408
409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
414 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
415 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
417
418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
419 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
422 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
424 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
425 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
426
427 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
428 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
429 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
430 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
431 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
432 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
433 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
434 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
435
436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
440
441 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
442 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
444
445 { } /* end */
446};
447
448/* toggle speaker-output according to the hp-jack state */
449static void alc861vd_dallas_setup(struct hda_codec *codec)
450{
451 struct alc_spec *spec = codec->spec;
452
453 spec->autocfg.hp_pins[0] = 0x15;
454 spec->autocfg.speaker_pins[0] = 0x14;
455 spec->automute = 1;
456 spec->automute_mode = ALC_AUTOMUTE_AMP;
457}
458
459/*
460 * configuration and preset
461 */
462static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
463 [ALC660VD_3ST] = "3stack-660",
464 [ALC660VD_3ST_DIG] = "3stack-660-digout",
465 [ALC660VD_ASUS_V1S] = "asus-v1s",
466 [ALC861VD_3ST] = "3stack",
467 [ALC861VD_3ST_DIG] = "3stack-digout",
468 [ALC861VD_6ST_DIG] = "6stack-digout",
469 [ALC861VD_LENOVO] = "lenovo",
470 [ALC861VD_DALLAS] = "dallas",
471 [ALC861VD_HP] = "hp",
472 [ALC861VD_AUTO] = "auto",
473};
474
475static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
476 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
477 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
478 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
479 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
480 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
481 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
482 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
483 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
484 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
485 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
486 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
487 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
488 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
489 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
490 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
491 {}
492};
493
494static const struct alc_config_preset alc861vd_presets[] = {
495 [ALC660VD_3ST] = {
496 .mixers = { alc861vd_3st_mixer },
497 .init_verbs = { alc861vd_volume_init_verbs,
498 alc861vd_3stack_init_verbs },
499 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
500 .dac_nids = alc660vd_dac_nids,
501 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
502 .channel_mode = alc861vd_3stack_2ch_modes,
503 .input_mux = &alc861vd_capture_source,
504 },
505 [ALC660VD_3ST_DIG] = {
506 .mixers = { alc861vd_3st_mixer },
507 .init_verbs = { alc861vd_volume_init_verbs,
508 alc861vd_3stack_init_verbs },
509 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
510 .dac_nids = alc660vd_dac_nids,
511 .dig_out_nid = ALC861VD_DIGOUT_NID,
512 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
513 .channel_mode = alc861vd_3stack_2ch_modes,
514 .input_mux = &alc861vd_capture_source,
515 },
516 [ALC861VD_3ST] = {
517 .mixers = { alc861vd_3st_mixer },
518 .init_verbs = { alc861vd_volume_init_verbs,
519 alc861vd_3stack_init_verbs },
520 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
521 .dac_nids = alc861vd_dac_nids,
522 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
523 .channel_mode = alc861vd_3stack_2ch_modes,
524 .input_mux = &alc861vd_capture_source,
525 },
526 [ALC861VD_3ST_DIG] = {
527 .mixers = { alc861vd_3st_mixer },
528 .init_verbs = { alc861vd_volume_init_verbs,
529 alc861vd_3stack_init_verbs },
530 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
531 .dac_nids = alc861vd_dac_nids,
532 .dig_out_nid = ALC861VD_DIGOUT_NID,
533 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
534 .channel_mode = alc861vd_3stack_2ch_modes,
535 .input_mux = &alc861vd_capture_source,
536 },
537 [ALC861VD_6ST_DIG] = {
538 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
539 .init_verbs = { alc861vd_volume_init_verbs,
540 alc861vd_6stack_init_verbs },
541 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
542 .dac_nids = alc861vd_dac_nids,
543 .dig_out_nid = ALC861VD_DIGOUT_NID,
544 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
545 .channel_mode = alc861vd_6stack_modes,
546 .input_mux = &alc861vd_capture_source,
547 },
548 [ALC861VD_LENOVO] = {
549 .mixers = { alc861vd_lenovo_mixer },
550 .init_verbs = { alc861vd_volume_init_verbs,
551 alc861vd_3stack_init_verbs,
552 alc861vd_eapd_verbs,
553 alc861vd_lenovo_unsol_verbs },
554 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
555 .dac_nids = alc660vd_dac_nids,
556 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
557 .channel_mode = alc861vd_3stack_2ch_modes,
558 .input_mux = &alc861vd_capture_source,
559 .unsol_event = alc861vd_lenovo_unsol_event,
560 .setup = alc861vd_lenovo_setup,
561 .init_hook = alc861vd_lenovo_init_hook,
562 },
563 [ALC861VD_DALLAS] = {
564 .mixers = { alc861vd_dallas_mixer },
565 .init_verbs = { alc861vd_dallas_verbs },
566 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
567 .dac_nids = alc861vd_dac_nids,
568 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
569 .channel_mode = alc861vd_3stack_2ch_modes,
570 .input_mux = &alc861vd_dallas_capture_source,
571 .unsol_event = alc_sku_unsol_event,
572 .setup = alc861vd_dallas_setup,
573 .init_hook = alc_hp_automute,
574 },
575 [ALC861VD_HP] = {
576 .mixers = { alc861vd_hp_mixer },
577 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
578 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
579 .dac_nids = alc861vd_dac_nids,
580 .dig_out_nid = ALC861VD_DIGOUT_NID,
581 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
582 .channel_mode = alc861vd_3stack_2ch_modes,
583 .input_mux = &alc861vd_hp_capture_source,
584 .unsol_event = alc_sku_unsol_event,
585 .setup = alc861vd_dallas_setup,
586 .init_hook = alc_hp_automute,
587 },
588 [ALC660VD_ASUS_V1S] = {
589 .mixers = { alc861vd_lenovo_mixer },
590 .init_verbs = { alc861vd_volume_init_verbs,
591 alc861vd_3stack_init_verbs,
592 alc861vd_eapd_verbs,
593 alc861vd_lenovo_unsol_verbs },
594 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
595 .dac_nids = alc660vd_dac_nids,
596 .dig_out_nid = ALC861VD_DIGOUT_NID,
597 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
598 .channel_mode = alc861vd_3stack_2ch_modes,
599 .input_mux = &alc861vd_capture_source,
600 .unsol_event = alc861vd_lenovo_unsol_event,
601 .setup = alc861vd_lenovo_setup,
602 .init_hook = alc861vd_lenovo_init_hook,
603 },
604};
605
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
new file mode 100644
index 00000000000..c844d2b5998
--- /dev/null
+++ b/sound/pci/hda/alc880_quirks.c
@@ -0,0 +1,1898 @@
1/*
2 * ALC880 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC880 board config type */
7enum {
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 ALC880_LG,
29 ALC880_LG_LW,
30 ALC880_MEDION_RIM,
31#ifdef CONFIG_SND_DEBUG
32 ALC880_TEST,
33#endif
34 ALC880_MODEL_LAST /* last tag */
35};
36
37/*
38 * ALC880 3-stack model
39 *
40 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
41 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
42 * F-Mic = 0x1b, HP = 0x19
43 */
44
45static const hda_nid_t alc880_dac_nids[4] = {
46 /* front, rear, clfe, rear_surr */
47 0x02, 0x05, 0x04, 0x03
48};
49
50static const hda_nid_t alc880_adc_nids[3] = {
51 /* ADC0-2 */
52 0x07, 0x08, 0x09,
53};
54
55/* The datasheet says the node 0x07 is connected from inputs,
56 * but it shows zero connection in the real implementation on some devices.
57 * Note: this is a 915GAV bug, fixed on 915GLV
58 */
59static const hda_nid_t alc880_adc_nids_alt[2] = {
60 /* ADC1-2 */
61 0x08, 0x09,
62};
63
64#define ALC880_DIGOUT_NID 0x06
65#define ALC880_DIGIN_NID 0x0a
66#define ALC880_PIN_CD_NID 0x1c
67
68static const struct hda_input_mux alc880_capture_source = {
69 .num_items = 4,
70 .items = {
71 { "Mic", 0x0 },
72 { "Front Mic", 0x3 },
73 { "Line", 0x2 },
74 { "CD", 0x4 },
75 },
76};
77
78/* channel source setting (2/6 channel selection for 3-stack) */
79/* 2ch mode */
80static const struct hda_verb alc880_threestack_ch2_init[] = {
81 /* set line-in to input, mute it */
82 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
83 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
84 /* set mic-in to input vref 80%, mute it */
85 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
86 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
87 { } /* end */
88};
89
90/* 6ch mode */
91static const struct hda_verb alc880_threestack_ch6_init[] = {
92 /* set line-in to output, unmute it */
93 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
94 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
95 /* set mic-in to output, unmute it */
96 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
97 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
98 { } /* end */
99};
100
101static const struct hda_channel_mode alc880_threestack_modes[2] = {
102 { 2, alc880_threestack_ch2_init },
103 { 6, alc880_threestack_ch6_init },
104};
105
106static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
108 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
109 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
110 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
111 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
112 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
113 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
114 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
115 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
116 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
118 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
121 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
122 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
123 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
124 {
125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
126 .name = "Channel Mode",
127 .info = alc_ch_mode_info,
128 .get = alc_ch_mode_get,
129 .put = alc_ch_mode_put,
130 },
131 { } /* end */
132};
133
134/*
135 * ALC880 5-stack model
136 *
137 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
138 * Side = 0x02 (0xd)
139 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
140 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
141 */
142
143/* additional mixers to alc880_three_stack_mixer */
144static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
145 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
146 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
147 { } /* end */
148};
149
150/* channel source setting (6/8 channel selection for 5-stack) */
151/* 6ch mode */
152static const struct hda_verb alc880_fivestack_ch6_init[] = {
153 /* set line-in to input, mute it */
154 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
155 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
156 { } /* end */
157};
158
159/* 8ch mode */
160static const struct hda_verb alc880_fivestack_ch8_init[] = {
161 /* set line-in to output, unmute it */
162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
164 { } /* end */
165};
166
167static const struct hda_channel_mode alc880_fivestack_modes[2] = {
168 { 6, alc880_fivestack_ch6_init },
169 { 8, alc880_fivestack_ch8_init },
170};
171
172
173/*
174 * ALC880 6-stack model
175 *
176 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
177 * Side = 0x05 (0x0f)
178 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
179 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
180 */
181
182static const hda_nid_t alc880_6st_dac_nids[4] = {
183 /* front, rear, clfe, rear_surr */
184 0x02, 0x03, 0x04, 0x05
185};
186
187static const struct hda_input_mux alc880_6stack_capture_source = {
188 .num_items = 4,
189 .items = {
190 { "Mic", 0x0 },
191 { "Front Mic", 0x1 },
192 { "Line", 0x2 },
193 { "CD", 0x4 },
194 },
195};
196
197/* fixed 8-channels */
198static const struct hda_channel_mode alc880_sixstack_modes[1] = {
199 { 8, NULL },
200};
201
202static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
204 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
205 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
206 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
207 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
212 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
213 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
214 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
215 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
216 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
220 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
221 {
222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
223 .name = "Channel Mode",
224 .info = alc_ch_mode_info,
225 .get = alc_ch_mode_get,
226 .put = alc_ch_mode_put,
227 },
228 { } /* end */
229};
230
231
232/*
233 * ALC880 W810 model
234 *
235 * W810 has rear IO for:
236 * Front (DAC 02)
237 * Surround (DAC 03)
238 * Center/LFE (DAC 04)
239 * Digital out (06)
240 *
241 * The system also has a pair of internal speakers, and a headphone jack.
242 * These are both connected to Line2 on the codec, hence to DAC 02.
243 *
244 * There is a variable resistor to control the speaker or headphone
245 * volume. This is a hardware-only device without a software API.
246 *
247 * Plugging headphones in will disable the internal speakers. This is
248 * implemented in hardware, not via the driver using jack sense. In
249 * a similar fashion, plugging into the rear socket marked "front" will
250 * disable both the speakers and headphones.
251 *
252 * For input, there's a microphone jack, and an "audio in" jack.
253 * These may not do anything useful with this driver yet, because I
254 * haven't setup any initialization verbs for these yet...
255 */
256
257static const hda_nid_t alc880_w810_dac_nids[3] = {
258 /* front, rear/surround, clfe */
259 0x02, 0x03, 0x04
260};
261
262/* fixed 6 channels */
263static const struct hda_channel_mode alc880_w810_modes[1] = {
264 { 6, NULL }
265};
266
267/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
268static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
269 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
270 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
271 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
272 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
273 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
274 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
275 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
276 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
277 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
278 { } /* end */
279};
280
281
282/*
283 * Z710V model
284 *
285 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
286 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
287 * Line = 0x1a
288 */
289
290static const hda_nid_t alc880_z71v_dac_nids[1] = {
291 0x02
292};
293#define ALC880_Z71V_HP_DAC 0x03
294
295/* fixed 2 channels */
296static const struct hda_channel_mode alc880_2_jack_modes[1] = {
297 { 2, NULL }
298};
299
300static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
301 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
302 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
303 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
304 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
305 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
306 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
307 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
308 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
309 { } /* end */
310};
311
312
313/*
314 * ALC880 F1734 model
315 *
316 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
317 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
318 */
319
320static const hda_nid_t alc880_f1734_dac_nids[1] = {
321 0x03
322};
323#define ALC880_F1734_HP_DAC 0x02
324
325static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
326 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
327 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
328 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
329 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
330 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
331 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
332 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
334 { } /* end */
335};
336
337static const struct hda_input_mux alc880_f1734_capture_source = {
338 .num_items = 2,
339 .items = {
340 { "Mic", 0x1 },
341 { "CD", 0x4 },
342 },
343};
344
345
346/*
347 * ALC880 ASUS model
348 *
349 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
350 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
351 * Mic = 0x18, Line = 0x1a
352 */
353
354#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
355#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
356
357static const struct snd_kcontrol_new alc880_asus_mixer[] = {
358 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
359 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
360 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
361 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
362 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
363 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
364 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
365 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
366 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
367 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
372 {
373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
374 .name = "Channel Mode",
375 .info = alc_ch_mode_info,
376 .get = alc_ch_mode_get,
377 .put = alc_ch_mode_put,
378 },
379 { } /* end */
380};
381
382/*
383 * ALC880 ASUS W1V model
384 *
385 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
386 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
387 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
388 */
389
390/* additional mixers to alc880_asus_mixer */
391static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
392 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
393 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
394 { } /* end */
395};
396
397/* TCL S700 */
398static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
399 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
400 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
403 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
406 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
407 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
408 { } /* end */
409};
410
411/* Uniwill */
412static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
413 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
414 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
415 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
416 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
417 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
418 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
419 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
420 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
427 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
429 {
430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
431 .name = "Channel Mode",
432 .info = alc_ch_mode_info,
433 .get = alc_ch_mode_get,
434 .put = alc_ch_mode_put,
435 },
436 { } /* end */
437};
438
439static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
441 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
442 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
443 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
444 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
445 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
448 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
449 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
450 { } /* end */
451};
452
453static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
454 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
457 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
460 { } /* end */
461};
462
463/*
464 * initialize the codec volumes, etc
465 */
466
467/*
468 * generic initialization of ADC, input mixers and output mixers
469 */
470static const struct hda_verb alc880_volume_init_verbs[] = {
471 /*
472 * Unmute ADC0-2 and set the default input to mic-in
473 */
474 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
476 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
477 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
478 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
479 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
480
481 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
482 * mixer widget
483 * Note: PASD motherboards uses the Line In 2 as the input for front
484 * panel mic (mic 2)
485 */
486 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
494
495 /*
496 * Set up output mixers (0x0c - 0x0f)
497 */
498 /* set vol=0 to output mixers */
499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
500 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
501 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
502 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
503 /* set up input amps for analog loopback */
504 /* Amp Indices: DAC = 0, mixer = 1 */
505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
511 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
512 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
513
514 { }
515};
516
517/*
518 * 3-stack pin configuration:
519 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
520 */
521static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
522 /*
523 * preset connection lists of input pins
524 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
525 */
526 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
527 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
528 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
529
530 /*
531 * Set pin mode and muting
532 */
533 /* set front pin widgets 0x14 for output */
534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
536 /* Mic1 (rear panel) pin widget for input and vref at 80% */
537 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
539 /* Mic2 (as headphone out) for HP output */
540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
541 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
542 /* Line In pin widget for input */
543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
545 /* Line2 (as front mic) pin widget for input and vref at 80% */
546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
547 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
548 /* CD pin widget for input */
549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
550
551 { }
552};
553
554/*
555 * 5-stack pin configuration:
556 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
557 * line-in/side = 0x1a, f-mic = 0x1b
558 */
559static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
560 /*
561 * preset connection lists of input pins
562 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
563 */
564 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
565 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
566
567 /*
568 * Set pin mode and muting
569 */
570 /* set pin widgets 0x14-0x17 for output */
571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
572 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
573 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
574 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
575 /* unmute pins for output (no gain on this amp) */
576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
578 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
579 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
580
581 /* Mic1 (rear panel) pin widget for input and vref at 80% */
582 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
583 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
584 /* Mic2 (as headphone out) for HP output */
585 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
587 /* Line In pin widget for input */
588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
590 /* Line2 (as front mic) pin widget for input and vref at 80% */
591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
593 /* CD pin widget for input */
594 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
595
596 { }
597};
598
599/*
600 * W810 pin configuration:
601 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
602 */
603static const struct hda_verb alc880_pin_w810_init_verbs[] = {
604 /* hphone/speaker input selector: front DAC */
605 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
606
607 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
608 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
612 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
613
614 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
615 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
616
617 { }
618};
619
620/*
621 * Z71V pin configuration:
622 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
623 */
624static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
628 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
629
630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
633 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
634
635 { }
636};
637
638/*
639 * 6-stack pin configuration:
640 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
641 * f-mic = 0x19, line = 0x1a, HP = 0x1b
642 */
643static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
644 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
645
646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
647 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
650 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
652 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
653 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
654
655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
661 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
662 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
664
665 { }
666};
667
668/*
669 * Uniwill pin configuration:
670 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
671 * line = 0x1a
672 */
673static const struct hda_verb alc880_uniwill_init_verbs[] = {
674 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
675
676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
677 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
678 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
680 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
681 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
682 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
683 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
690
691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
693 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
697 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
698 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
699 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
700
701 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
702 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
703
704 { }
705};
706
707/*
708* Uniwill P53
709* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
710 */
711static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
712 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
713
714 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
715 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
718 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
719 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
720 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
722 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
725 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
726
727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
733
734 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
735 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
736
737 { }
738};
739
740static const struct hda_verb alc880_beep_init_verbs[] = {
741 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
742 { }
743};
744
745static void alc880_uniwill_setup(struct hda_codec *codec)
746{
747 struct alc_spec *spec = codec->spec;
748
749 spec->autocfg.hp_pins[0] = 0x14;
750 spec->autocfg.speaker_pins[0] = 0x15;
751 spec->autocfg.speaker_pins[0] = 0x16;
752 spec->automute = 1;
753 spec->automute_mode = ALC_AUTOMUTE_AMP;
754}
755
756static void alc880_uniwill_init_hook(struct hda_codec *codec)
757{
758 alc_hp_automute(codec);
759 alc88x_simple_mic_automute(codec);
760}
761
762static void alc880_uniwill_unsol_event(struct hda_codec *codec,
763 unsigned int res)
764{
765 /* Looks like the unsol event is incompatible with the standard
766 * definition. 4bit tag is placed at 28 bit!
767 */
768 switch (res >> 28) {
769 case ALC_MIC_EVENT:
770 alc88x_simple_mic_automute(codec);
771 break;
772 default:
773 alc_sku_unsol_event(codec, res);
774 break;
775 }
776}
777
778static void alc880_uniwill_p53_setup(struct hda_codec *codec)
779{
780 struct alc_spec *spec = codec->spec;
781
782 spec->autocfg.hp_pins[0] = 0x14;
783 spec->autocfg.speaker_pins[0] = 0x15;
784 spec->automute = 1;
785 spec->automute_mode = ALC_AUTOMUTE_AMP;
786}
787
788static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
789{
790 unsigned int present;
791
792 present = snd_hda_codec_read(codec, 0x21, 0,
793 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
794 present &= HDA_AMP_VOLMASK;
795 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
796 HDA_AMP_VOLMASK, present);
797 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
798 HDA_AMP_VOLMASK, present);
799}
800
801static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
802 unsigned int res)
803{
804 /* Looks like the unsol event is incompatible with the standard
805 * definition. 4bit tag is placed at 28 bit!
806 */
807 if ((res >> 28) == ALC_DCVOL_EVENT)
808 alc880_uniwill_p53_dcvol_automute(codec);
809 else
810 alc_sku_unsol_event(codec, res);
811}
812
813/*
814 * F1734 pin configuration:
815 * HP = 0x14, speaker-out = 0x15, mic = 0x18
816 */
817static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
818 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
819 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
820 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
821 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
822 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
823
824 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
825 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
828
829 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
831 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
832 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
835 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
836 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
837 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
838
839 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
840 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
841
842 { }
843};
844
845/*
846 * ASUS pin configuration:
847 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
848 */
849static const struct hda_verb alc880_pin_asus_init_verbs[] = {
850 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
851 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
852 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
853 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
854
855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
858 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
861 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
862 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
863
864 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
866 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
868 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
869 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
870 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
871 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
872 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
873
874 { }
875};
876
877/* Enable GPIO mask and set output */
878#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
879#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
880#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
881
882/* Clevo m520g init */
883static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
884 /* headphone output */
885 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
886 /* line-out */
887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
889 /* Line-in */
890 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
892 /* CD */
893 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
894 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
895 /* Mic1 (rear panel) */
896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
897 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
898 /* Mic2 (front panel) */
899 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
900 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
901 /* headphone */
902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
904 /* change to EAPD mode */
905 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
906 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
907
908 { }
909};
910
911static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
912 /* change to EAPD mode */
913 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
914 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
915
916 /* Headphone output */
917 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
918 /* Front output*/
919 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
920 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
921
922 /* Line In pin widget for input */
923 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
924 /* CD pin widget for input */
925 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
926 /* Mic1 (rear panel) pin widget for input and vref at 80% */
927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
928
929 /* change to EAPD mode */
930 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
931 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
932
933 { }
934};
935
936/*
937 * LG m1 express dual
938 *
939 * Pin assignment:
940 * Rear Line-In/Out (blue): 0x14
941 * Build-in Mic-In: 0x15
942 * Speaker-out: 0x17
943 * HP-Out (green): 0x1b
944 * Mic-In/Out (red): 0x19
945 * SPDIF-Out: 0x1e
946 */
947
948/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
949static const hda_nid_t alc880_lg_dac_nids[3] = {
950 0x05, 0x02, 0x03
951};
952
953/* seems analog CD is not working */
954static const struct hda_input_mux alc880_lg_capture_source = {
955 .num_items = 3,
956 .items = {
957 { "Mic", 0x1 },
958 { "Line", 0x5 },
959 { "Internal Mic", 0x6 },
960 },
961};
962
963/* 2,4,6 channel modes */
964static const struct hda_verb alc880_lg_ch2_init[] = {
965 /* set line-in and mic-in to input */
966 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
967 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
968 { }
969};
970
971static const struct hda_verb alc880_lg_ch4_init[] = {
972 /* set line-in to out and mic-in to input */
973 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
974 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
975 { }
976};
977
978static const struct hda_verb alc880_lg_ch6_init[] = {
979 /* set line-in and mic-in to output */
980 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
981 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
982 { }
983};
984
985static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
986 { 2, alc880_lg_ch2_init },
987 { 4, alc880_lg_ch4_init },
988 { 6, alc880_lg_ch6_init },
989};
990
991static const struct snd_kcontrol_new alc880_lg_mixer[] = {
992 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
993 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
994 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
995 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
996 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
997 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
998 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
999 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1004 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1005 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1006 {
1007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1008 .name = "Channel Mode",
1009 .info = alc_ch_mode_info,
1010 .get = alc_ch_mode_get,
1011 .put = alc_ch_mode_put,
1012 },
1013 { } /* end */
1014};
1015
1016static const struct hda_verb alc880_lg_init_verbs[] = {
1017 /* set capture source to mic-in */
1018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1021 /* mute all amp mixer inputs */
1022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1025 /* line-in to input */
1026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1028 /* built-in mic */
1029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1030 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1031 /* speaker-out */
1032 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1033 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1034 /* mic-in to input */
1035 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1036 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1037 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1038 /* HP-out */
1039 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1040 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1041 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1042 /* jack sense */
1043 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1044 { }
1045};
1046
1047/* toggle speaker-output according to the hp-jack state */
1048static void alc880_lg_setup(struct hda_codec *codec)
1049{
1050 struct alc_spec *spec = codec->spec;
1051
1052 spec->autocfg.hp_pins[0] = 0x1b;
1053 spec->autocfg.speaker_pins[0] = 0x17;
1054 spec->automute = 1;
1055 spec->automute_mode = ALC_AUTOMUTE_AMP;
1056}
1057
1058/*
1059 * LG LW20
1060 *
1061 * Pin assignment:
1062 * Speaker-out: 0x14
1063 * Mic-In: 0x18
1064 * Built-in Mic-In: 0x19
1065 * Line-In: 0x1b
1066 * HP-Out: 0x1a
1067 * SPDIF-Out: 0x1e
1068 */
1069
1070static const struct hda_input_mux alc880_lg_lw_capture_source = {
1071 .num_items = 3,
1072 .items = {
1073 { "Mic", 0x0 },
1074 { "Internal Mic", 0x1 },
1075 { "Line In", 0x2 },
1076 },
1077};
1078
1079#define alc880_lg_lw_modes alc880_threestack_modes
1080
1081static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1082 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1083 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1084 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1085 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1086 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1087 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1088 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1089 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1090 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1091 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1092 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1093 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1094 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1095 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1096 {
1097 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1098 .name = "Channel Mode",
1099 .info = alc_ch_mode_info,
1100 .get = alc_ch_mode_get,
1101 .put = alc_ch_mode_put,
1102 },
1103 { } /* end */
1104};
1105
1106static const struct hda_verb alc880_lg_lw_init_verbs[] = {
1107 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1108 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1109 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1110
1111 /* set capture source to mic-in */
1112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1113 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1114 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1115 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1116 /* speaker-out */
1117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1119 /* HP-out */
1120 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1121 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1122 /* mic-in to input */
1123 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1124 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1125 /* built-in mic */
1126 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1127 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1128 /* jack sense */
1129 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1130 { }
1131};
1132
1133/* toggle speaker-output according to the hp-jack state */
1134static void alc880_lg_lw_setup(struct hda_codec *codec)
1135{
1136 struct alc_spec *spec = codec->spec;
1137
1138 spec->autocfg.hp_pins[0] = 0x1b;
1139 spec->autocfg.speaker_pins[0] = 0x14;
1140 spec->automute = 1;
1141 spec->automute_mode = ALC_AUTOMUTE_AMP;
1142}
1143
1144static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
1145 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1146 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1148 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1149 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1150 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
1151 { } /* end */
1152};
1153
1154static const struct hda_input_mux alc880_medion_rim_capture_source = {
1155 .num_items = 2,
1156 .items = {
1157 { "Mic", 0x0 },
1158 { "Internal Mic", 0x1 },
1159 },
1160};
1161
1162static const struct hda_verb alc880_medion_rim_init_verbs[] = {
1163 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1164
1165 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1166 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1167
1168 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1169 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1171 /* Mic2 (as headphone out) for HP output */
1172 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1174 /* Internal Speaker */
1175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1176 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1177
1178 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1179 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1180
1181 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1182 { }
1183};
1184
1185/* toggle speaker-output according to the hp-jack state */
1186static void alc880_medion_rim_automute(struct hda_codec *codec)
1187{
1188 struct alc_spec *spec = codec->spec;
1189 alc_hp_automute(codec);
1190 /* toggle EAPD */
1191 if (spec->jack_present)
1192 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
1193 else
1194 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
1195}
1196
1197static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
1198 unsigned int res)
1199{
1200 /* Looks like the unsol event is incompatible with the standard
1201 * definition. 4bit tag is placed at 28 bit!
1202 */
1203 if ((res >> 28) == ALC_HP_EVENT)
1204 alc880_medion_rim_automute(codec);
1205}
1206
1207static void alc880_medion_rim_setup(struct hda_codec *codec)
1208{
1209 struct alc_spec *spec = codec->spec;
1210
1211 spec->autocfg.hp_pins[0] = 0x14;
1212 spec->autocfg.speaker_pins[0] = 0x1b;
1213 spec->automute = 1;
1214 spec->automute_mode = ALC_AUTOMUTE_AMP;
1215}
1216
1217#ifdef CONFIG_SND_HDA_POWER_SAVE
1218static const struct hda_amp_list alc880_lg_loopbacks[] = {
1219 { 0x0b, HDA_INPUT, 1 },
1220 { 0x0b, HDA_INPUT, 6 },
1221 { 0x0b, HDA_INPUT, 7 },
1222 { } /* end */
1223};
1224#endif
1225
1226/*
1227 * Test configuration for debugging
1228 *
1229 * Almost all inputs/outputs are enabled. I/O pins can be configured via
1230 * enum controls.
1231 */
1232#ifdef CONFIG_SND_DEBUG
1233static const hda_nid_t alc880_test_dac_nids[4] = {
1234 0x02, 0x03, 0x04, 0x05
1235};
1236
1237static const struct hda_input_mux alc880_test_capture_source = {
1238 .num_items = 7,
1239 .items = {
1240 { "In-1", 0x0 },
1241 { "In-2", 0x1 },
1242 { "In-3", 0x2 },
1243 { "In-4", 0x3 },
1244 { "CD", 0x4 },
1245 { "Front", 0x5 },
1246 { "Surround", 0x6 },
1247 },
1248};
1249
1250static const struct hda_channel_mode alc880_test_modes[4] = {
1251 { 2, NULL },
1252 { 4, NULL },
1253 { 6, NULL },
1254 { 8, NULL },
1255};
1256
1257static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
1258 struct snd_ctl_elem_info *uinfo)
1259{
1260 static const char * const texts[] = {
1261 "N/A", "Line Out", "HP Out",
1262 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1263 };
1264 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1265 uinfo->count = 1;
1266 uinfo->value.enumerated.items = 8;
1267 if (uinfo->value.enumerated.item >= 8)
1268 uinfo->value.enumerated.item = 7;
1269 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1270 return 0;
1271}
1272
1273static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
1274 struct snd_ctl_elem_value *ucontrol)
1275{
1276 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1277 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1278 unsigned int pin_ctl, item = 0;
1279
1280 pin_ctl = snd_hda_codec_read(codec, nid, 0,
1281 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1282 if (pin_ctl & AC_PINCTL_OUT_EN) {
1283 if (pin_ctl & AC_PINCTL_HP_EN)
1284 item = 2;
1285 else
1286 item = 1;
1287 } else if (pin_ctl & AC_PINCTL_IN_EN) {
1288 switch (pin_ctl & AC_PINCTL_VREFEN) {
1289 case AC_PINCTL_VREF_HIZ: item = 3; break;
1290 case AC_PINCTL_VREF_50: item = 4; break;
1291 case AC_PINCTL_VREF_GRD: item = 5; break;
1292 case AC_PINCTL_VREF_80: item = 6; break;
1293 case AC_PINCTL_VREF_100: item = 7; break;
1294 }
1295 }
1296 ucontrol->value.enumerated.item[0] = item;
1297 return 0;
1298}
1299
1300static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
1301 struct snd_ctl_elem_value *ucontrol)
1302{
1303 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1304 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1305 static const unsigned int ctls[] = {
1306 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1307 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1308 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1309 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1310 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1311 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1312 };
1313 unsigned int old_ctl, new_ctl;
1314
1315 old_ctl = snd_hda_codec_read(codec, nid, 0,
1316 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1317 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1318 if (old_ctl != new_ctl) {
1319 int val;
1320 snd_hda_codec_write_cache(codec, nid, 0,
1321 AC_VERB_SET_PIN_WIDGET_CONTROL,
1322 new_ctl);
1323 val = ucontrol->value.enumerated.item[0] >= 3 ?
1324 HDA_AMP_MUTE : 0;
1325 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1326 HDA_AMP_MUTE, val);
1327 return 1;
1328 }
1329 return 0;
1330}
1331
1332static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
1333 struct snd_ctl_elem_info *uinfo)
1334{
1335 static const char * const texts[] = {
1336 "Front", "Surround", "CLFE", "Side"
1337 };
1338 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1339 uinfo->count = 1;
1340 uinfo->value.enumerated.items = 4;
1341 if (uinfo->value.enumerated.item >= 4)
1342 uinfo->value.enumerated.item = 3;
1343 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1344 return 0;
1345}
1346
1347static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
1348 struct snd_ctl_elem_value *ucontrol)
1349{
1350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1351 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1352 unsigned int sel;
1353
1354 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1355 ucontrol->value.enumerated.item[0] = sel & 3;
1356 return 0;
1357}
1358
1359static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
1360 struct snd_ctl_elem_value *ucontrol)
1361{
1362 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1363 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1364 unsigned int sel;
1365
1366 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1367 if (ucontrol->value.enumerated.item[0] != sel) {
1368 sel = ucontrol->value.enumerated.item[0] & 3;
1369 snd_hda_codec_write_cache(codec, nid, 0,
1370 AC_VERB_SET_CONNECT_SEL, sel);
1371 return 1;
1372 }
1373 return 0;
1374}
1375
1376#define PIN_CTL_TEST(xname,nid) { \
1377 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1378 .name = xname, \
1379 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1380 .info = alc_test_pin_ctl_info, \
1381 .get = alc_test_pin_ctl_get, \
1382 .put = alc_test_pin_ctl_put, \
1383 .private_value = nid \
1384 }
1385
1386#define PIN_SRC_TEST(xname,nid) { \
1387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1388 .name = xname, \
1389 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1390 .info = alc_test_pin_src_info, \
1391 .get = alc_test_pin_src_get, \
1392 .put = alc_test_pin_src_put, \
1393 .private_value = nid \
1394 }
1395
1396static const struct snd_kcontrol_new alc880_test_mixer[] = {
1397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1398 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1399 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1400 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1401 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1402 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1403 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1404 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1405 PIN_CTL_TEST("Front Pin Mode", 0x14),
1406 PIN_CTL_TEST("Surround Pin Mode", 0x15),
1407 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1408 PIN_CTL_TEST("Side Pin Mode", 0x17),
1409 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1410 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1411 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1412 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1413 PIN_SRC_TEST("In-1 Pin Source", 0x18),
1414 PIN_SRC_TEST("In-2 Pin Source", 0x19),
1415 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1416 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1417 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1418 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1419 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1420 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1421 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1422 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1423 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1424 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1425 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1426 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1427 {
1428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1429 .name = "Channel Mode",
1430 .info = alc_ch_mode_info,
1431 .get = alc_ch_mode_get,
1432 .put = alc_ch_mode_put,
1433 },
1434 { } /* end */
1435};
1436
1437static const struct hda_verb alc880_test_init_verbs[] = {
1438 /* Unmute inputs of 0x0c - 0x0f */
1439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1445 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1446 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1447 /* Vol output for 0x0c-0x0f */
1448 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1449 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1450 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1451 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1452 /* Set output pins 0x14-0x17 */
1453 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1454 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1455 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1456 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1457 /* Unmute output pins 0x14-0x17 */
1458 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1459 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1460 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1461 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1462 /* Set input pins 0x18-0x1c */
1463 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1464 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1465 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1466 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1467 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1468 /* Mute input pins 0x18-0x1b */
1469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1470 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1472 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1473 /* ADC set up */
1474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1475 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1476 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1477 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1478 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1479 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1480 /* Analog input/passthru */
1481 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1482 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1483 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1486 { }
1487};
1488#endif
1489
1490/*
1491 */
1492
1493static const char * const alc880_models[ALC880_MODEL_LAST] = {
1494 [ALC880_3ST] = "3stack",
1495 [ALC880_TCL_S700] = "tcl",
1496 [ALC880_3ST_DIG] = "3stack-digout",
1497 [ALC880_CLEVO] = "clevo",
1498 [ALC880_5ST] = "5stack",
1499 [ALC880_5ST_DIG] = "5stack-digout",
1500 [ALC880_W810] = "w810",
1501 [ALC880_Z71V] = "z71v",
1502 [ALC880_6ST] = "6stack",
1503 [ALC880_6ST_DIG] = "6stack-digout",
1504 [ALC880_ASUS] = "asus",
1505 [ALC880_ASUS_W1V] = "asus-w1v",
1506 [ALC880_ASUS_DIG] = "asus-dig",
1507 [ALC880_ASUS_DIG2] = "asus-dig2",
1508 [ALC880_UNIWILL_DIG] = "uniwill",
1509 [ALC880_UNIWILL_P53] = "uniwill-p53",
1510 [ALC880_FUJITSU] = "fujitsu",
1511 [ALC880_F1734] = "F1734",
1512 [ALC880_LG] = "lg",
1513 [ALC880_LG_LW] = "lg-lw",
1514 [ALC880_MEDION_RIM] = "medion",
1515#ifdef CONFIG_SND_DEBUG
1516 [ALC880_TEST] = "test",
1517#endif
1518 [ALC880_AUTO] = "auto",
1519};
1520
1521static const struct snd_pci_quirk alc880_cfg_tbl[] = {
1522 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
1523 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
1524 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
1525 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
1526 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
1527 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
1528 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
1529 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
1530 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
1531 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
1532 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
1533 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
1534 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
1535 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
1536 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
1537 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
1538 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
1539 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
1540 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
1541 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
1542 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
1543 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
1544 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
1545 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
1546 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
1547 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
1548 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
1549 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
1550 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
1551 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
1552 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
1553 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
1554 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
1555 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
1556 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
1557 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
1558 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
1559 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
1560 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
1561 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
1562 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
1563 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
1564 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
1565 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
1566 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
1567 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
1568 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1569 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
1570 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
1571 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
1572 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
1573 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
1574 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
1575 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
1576 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
1577 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
1578 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
1579 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
1580 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
1581 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
1582 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
1583 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
1584 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
1585 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
1586 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
1587 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
1588 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
1589 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
1590 /* default Intel */
1591 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
1592 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
1593 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1594 {}
1595};
1596
1597/*
1598 * ALC880 codec presets
1599 */
1600static const struct alc_config_preset alc880_presets[] = {
1601 [ALC880_3ST] = {
1602 .mixers = { alc880_three_stack_mixer },
1603 .init_verbs = { alc880_volume_init_verbs,
1604 alc880_pin_3stack_init_verbs },
1605 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1606 .dac_nids = alc880_dac_nids,
1607 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1608 .channel_mode = alc880_threestack_modes,
1609 .need_dac_fix = 1,
1610 .input_mux = &alc880_capture_source,
1611 },
1612 [ALC880_3ST_DIG] = {
1613 .mixers = { alc880_three_stack_mixer },
1614 .init_verbs = { alc880_volume_init_verbs,
1615 alc880_pin_3stack_init_verbs },
1616 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1617 .dac_nids = alc880_dac_nids,
1618 .dig_out_nid = ALC880_DIGOUT_NID,
1619 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1620 .channel_mode = alc880_threestack_modes,
1621 .need_dac_fix = 1,
1622 .input_mux = &alc880_capture_source,
1623 },
1624 [ALC880_TCL_S700] = {
1625 .mixers = { alc880_tcl_s700_mixer },
1626 .init_verbs = { alc880_volume_init_verbs,
1627 alc880_pin_tcl_S700_init_verbs,
1628 alc880_gpio2_init_verbs },
1629 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1630 .dac_nids = alc880_dac_nids,
1631 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
1632 .num_adc_nids = 1, /* single ADC */
1633 .hp_nid = 0x03,
1634 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1635 .channel_mode = alc880_2_jack_modes,
1636 .input_mux = &alc880_capture_source,
1637 },
1638 [ALC880_5ST] = {
1639 .mixers = { alc880_three_stack_mixer,
1640 alc880_five_stack_mixer},
1641 .init_verbs = { alc880_volume_init_verbs,
1642 alc880_pin_5stack_init_verbs },
1643 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1644 .dac_nids = alc880_dac_nids,
1645 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1646 .channel_mode = alc880_fivestack_modes,
1647 .input_mux = &alc880_capture_source,
1648 },
1649 [ALC880_5ST_DIG] = {
1650 .mixers = { alc880_three_stack_mixer,
1651 alc880_five_stack_mixer },
1652 .init_verbs = { alc880_volume_init_verbs,
1653 alc880_pin_5stack_init_verbs },
1654 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1655 .dac_nids = alc880_dac_nids,
1656 .dig_out_nid = ALC880_DIGOUT_NID,
1657 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1658 .channel_mode = alc880_fivestack_modes,
1659 .input_mux = &alc880_capture_source,
1660 },
1661 [ALC880_6ST] = {
1662 .mixers = { alc880_six_stack_mixer },
1663 .init_verbs = { alc880_volume_init_verbs,
1664 alc880_pin_6stack_init_verbs },
1665 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1666 .dac_nids = alc880_6st_dac_nids,
1667 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1668 .channel_mode = alc880_sixstack_modes,
1669 .input_mux = &alc880_6stack_capture_source,
1670 },
1671 [ALC880_6ST_DIG] = {
1672 .mixers = { alc880_six_stack_mixer },
1673 .init_verbs = { alc880_volume_init_verbs,
1674 alc880_pin_6stack_init_verbs },
1675 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1676 .dac_nids = alc880_6st_dac_nids,
1677 .dig_out_nid = ALC880_DIGOUT_NID,
1678 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1679 .channel_mode = alc880_sixstack_modes,
1680 .input_mux = &alc880_6stack_capture_source,
1681 },
1682 [ALC880_W810] = {
1683 .mixers = { alc880_w810_base_mixer },
1684 .init_verbs = { alc880_volume_init_verbs,
1685 alc880_pin_w810_init_verbs,
1686 alc880_gpio2_init_verbs },
1687 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1688 .dac_nids = alc880_w810_dac_nids,
1689 .dig_out_nid = ALC880_DIGOUT_NID,
1690 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1691 .channel_mode = alc880_w810_modes,
1692 .input_mux = &alc880_capture_source,
1693 },
1694 [ALC880_Z71V] = {
1695 .mixers = { alc880_z71v_mixer },
1696 .init_verbs = { alc880_volume_init_verbs,
1697 alc880_pin_z71v_init_verbs },
1698 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1699 .dac_nids = alc880_z71v_dac_nids,
1700 .dig_out_nid = ALC880_DIGOUT_NID,
1701 .hp_nid = 0x03,
1702 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1703 .channel_mode = alc880_2_jack_modes,
1704 .input_mux = &alc880_capture_source,
1705 },
1706 [ALC880_F1734] = {
1707 .mixers = { alc880_f1734_mixer },
1708 .init_verbs = { alc880_volume_init_verbs,
1709 alc880_pin_f1734_init_verbs },
1710 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
1711 .dac_nids = alc880_f1734_dac_nids,
1712 .hp_nid = 0x02,
1713 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1714 .channel_mode = alc880_2_jack_modes,
1715 .input_mux = &alc880_f1734_capture_source,
1716 .unsol_event = alc880_uniwill_p53_unsol_event,
1717 .setup = alc880_uniwill_p53_setup,
1718 .init_hook = alc_hp_automute,
1719 },
1720 [ALC880_ASUS] = {
1721 .mixers = { alc880_asus_mixer },
1722 .init_verbs = { alc880_volume_init_verbs,
1723 alc880_pin_asus_init_verbs,
1724 alc880_gpio1_init_verbs },
1725 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1726 .dac_nids = alc880_asus_dac_nids,
1727 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1728 .channel_mode = alc880_asus_modes,
1729 .need_dac_fix = 1,
1730 .input_mux = &alc880_capture_source,
1731 },
1732 [ALC880_ASUS_DIG] = {
1733 .mixers = { alc880_asus_mixer },
1734 .init_verbs = { alc880_volume_init_verbs,
1735 alc880_pin_asus_init_verbs,
1736 alc880_gpio1_init_verbs },
1737 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1738 .dac_nids = alc880_asus_dac_nids,
1739 .dig_out_nid = ALC880_DIGOUT_NID,
1740 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1741 .channel_mode = alc880_asus_modes,
1742 .need_dac_fix = 1,
1743 .input_mux = &alc880_capture_source,
1744 },
1745 [ALC880_ASUS_DIG2] = {
1746 .mixers = { alc880_asus_mixer },
1747 .init_verbs = { alc880_volume_init_verbs,
1748 alc880_pin_asus_init_verbs,
1749 alc880_gpio2_init_verbs }, /* use GPIO2 */
1750 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1751 .dac_nids = alc880_asus_dac_nids,
1752 .dig_out_nid = ALC880_DIGOUT_NID,
1753 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1754 .channel_mode = alc880_asus_modes,
1755 .need_dac_fix = 1,
1756 .input_mux = &alc880_capture_source,
1757 },
1758 [ALC880_ASUS_W1V] = {
1759 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
1760 .init_verbs = { alc880_volume_init_verbs,
1761 alc880_pin_asus_init_verbs,
1762 alc880_gpio1_init_verbs },
1763 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1764 .dac_nids = alc880_asus_dac_nids,
1765 .dig_out_nid = ALC880_DIGOUT_NID,
1766 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1767 .channel_mode = alc880_asus_modes,
1768 .need_dac_fix = 1,
1769 .input_mux = &alc880_capture_source,
1770 },
1771 [ALC880_UNIWILL_DIG] = {
1772 .mixers = { alc880_asus_mixer },
1773 .init_verbs = { alc880_volume_init_verbs,
1774 alc880_pin_asus_init_verbs },
1775 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1776 .dac_nids = alc880_asus_dac_nids,
1777 .dig_out_nid = ALC880_DIGOUT_NID,
1778 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1779 .channel_mode = alc880_asus_modes,
1780 .need_dac_fix = 1,
1781 .input_mux = &alc880_capture_source,
1782 },
1783 [ALC880_UNIWILL] = {
1784 .mixers = { alc880_uniwill_mixer },
1785 .init_verbs = { alc880_volume_init_verbs,
1786 alc880_uniwill_init_verbs },
1787 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1788 .dac_nids = alc880_asus_dac_nids,
1789 .dig_out_nid = ALC880_DIGOUT_NID,
1790 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1791 .channel_mode = alc880_threestack_modes,
1792 .need_dac_fix = 1,
1793 .input_mux = &alc880_capture_source,
1794 .unsol_event = alc880_uniwill_unsol_event,
1795 .setup = alc880_uniwill_setup,
1796 .init_hook = alc880_uniwill_init_hook,
1797 },
1798 [ALC880_UNIWILL_P53] = {
1799 .mixers = { alc880_uniwill_p53_mixer },
1800 .init_verbs = { alc880_volume_init_verbs,
1801 alc880_uniwill_p53_init_verbs },
1802 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1803 .dac_nids = alc880_asus_dac_nids,
1804 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1805 .channel_mode = alc880_threestack_modes,
1806 .input_mux = &alc880_capture_source,
1807 .unsol_event = alc880_uniwill_p53_unsol_event,
1808 .setup = alc880_uniwill_p53_setup,
1809 .init_hook = alc_hp_automute,
1810 },
1811 [ALC880_FUJITSU] = {
1812 .mixers = { alc880_fujitsu_mixer },
1813 .init_verbs = { alc880_volume_init_verbs,
1814 alc880_uniwill_p53_init_verbs,
1815 alc880_beep_init_verbs },
1816 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1817 .dac_nids = alc880_dac_nids,
1818 .dig_out_nid = ALC880_DIGOUT_NID,
1819 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1820 .channel_mode = alc880_2_jack_modes,
1821 .input_mux = &alc880_capture_source,
1822 .unsol_event = alc880_uniwill_p53_unsol_event,
1823 .setup = alc880_uniwill_p53_setup,
1824 .init_hook = alc_hp_automute,
1825 },
1826 [ALC880_CLEVO] = {
1827 .mixers = { alc880_three_stack_mixer },
1828 .init_verbs = { alc880_volume_init_verbs,
1829 alc880_pin_clevo_init_verbs },
1830 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1831 .dac_nids = alc880_dac_nids,
1832 .hp_nid = 0x03,
1833 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1834 .channel_mode = alc880_threestack_modes,
1835 .need_dac_fix = 1,
1836 .input_mux = &alc880_capture_source,
1837 },
1838 [ALC880_LG] = {
1839 .mixers = { alc880_lg_mixer },
1840 .init_verbs = { alc880_volume_init_verbs,
1841 alc880_lg_init_verbs },
1842 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
1843 .dac_nids = alc880_lg_dac_nids,
1844 .dig_out_nid = ALC880_DIGOUT_NID,
1845 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
1846 .channel_mode = alc880_lg_ch_modes,
1847 .need_dac_fix = 1,
1848 .input_mux = &alc880_lg_capture_source,
1849 .unsol_event = alc_sku_unsol_event,
1850 .setup = alc880_lg_setup,
1851 .init_hook = alc_hp_automute,
1852#ifdef CONFIG_SND_HDA_POWER_SAVE
1853 .loopbacks = alc880_lg_loopbacks,
1854#endif
1855 },
1856 [ALC880_LG_LW] = {
1857 .mixers = { alc880_lg_lw_mixer },
1858 .init_verbs = { alc880_volume_init_verbs,
1859 alc880_lg_lw_init_verbs },
1860 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1861 .dac_nids = alc880_dac_nids,
1862 .dig_out_nid = ALC880_DIGOUT_NID,
1863 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
1864 .channel_mode = alc880_lg_lw_modes,
1865 .input_mux = &alc880_lg_lw_capture_source,
1866 .unsol_event = alc_sku_unsol_event,
1867 .setup = alc880_lg_lw_setup,
1868 .init_hook = alc_hp_automute,
1869 },
1870 [ALC880_MEDION_RIM] = {
1871 .mixers = { alc880_medion_rim_mixer },
1872 .init_verbs = { alc880_volume_init_verbs,
1873 alc880_medion_rim_init_verbs,
1874 alc_gpio2_init_verbs },
1875 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1876 .dac_nids = alc880_dac_nids,
1877 .dig_out_nid = ALC880_DIGOUT_NID,
1878 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1879 .channel_mode = alc880_2_jack_modes,
1880 .input_mux = &alc880_medion_rim_capture_source,
1881 .unsol_event = alc880_medion_rim_unsol_event,
1882 .setup = alc880_medion_rim_setup,
1883 .init_hook = alc880_medion_rim_automute,
1884 },
1885#ifdef CONFIG_SND_DEBUG
1886 [ALC880_TEST] = {
1887 .mixers = { alc880_test_mixer },
1888 .init_verbs = { alc880_test_init_verbs },
1889 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
1890 .dac_nids = alc880_test_dac_nids,
1891 .dig_out_nid = ALC880_DIGOUT_NID,
1892 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
1893 .channel_mode = alc880_test_modes,
1894 .input_mux = &alc880_test_capture_source,
1895 },
1896#endif
1897};
1898
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
new file mode 100644
index 00000000000..617d04723b8
--- /dev/null
+++ b/sound/pci/hda/alc882_quirks.c
@@ -0,0 +1,3755 @@
1/*
2 * ALC882/ALC883/ALC888/ALC889 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC882 models */
7enum {
8 ALC882_AUTO,
9 ALC882_3ST_DIG,
10 ALC882_6ST_DIG,
11 ALC882_ARIMA,
12 ALC882_W2JC,
13 ALC882_TARGA,
14 ALC882_ASUS_A7J,
15 ALC882_ASUS_A7M,
16 ALC885_MACPRO,
17 ALC885_MBA21,
18 ALC885_MBP3,
19 ALC885_MB5,
20 ALC885_MACMINI3,
21 ALC885_IMAC24,
22 ALC885_IMAC91,
23 ALC883_3ST_2ch_DIG,
24 ALC883_3ST_6ch_DIG,
25 ALC883_3ST_6ch,
26 ALC883_6ST_DIG,
27 ALC883_TARGA_DIG,
28 ALC883_TARGA_2ch_DIG,
29 ALC883_TARGA_8ch_DIG,
30 ALC883_ACER,
31 ALC883_ACER_ASPIRE,
32 ALC888_ACER_ASPIRE_4930G,
33 ALC888_ACER_ASPIRE_6530G,
34 ALC888_ACER_ASPIRE_8930G,
35 ALC888_ACER_ASPIRE_7730G,
36 ALC883_MEDION,
37 ALC883_MEDION_WIM2160,
38 ALC883_LAPTOP_EAPD,
39 ALC883_LENOVO_101E_2ch,
40 ALC883_LENOVO_NB0763,
41 ALC888_LENOVO_MS7195_DIG,
42 ALC888_LENOVO_SKY,
43 ALC883_HAIER_W66,
44 ALC888_3ST_HP,
45 ALC888_6ST_DELL,
46 ALC883_MITAC,
47 ALC883_CLEVO_M540R,
48 ALC883_CLEVO_M720,
49 ALC883_FUJITSU_PI2515,
50 ALC888_FUJITSU_XA3530,
51 ALC883_3ST_6ch_INTEL,
52 ALC889A_INTEL,
53 ALC889_INTEL,
54 ALC888_ASUS_M90V,
55 ALC888_ASUS_EEE1601,
56 ALC889A_MB31,
57 ALC1200_ASUS_P5Q,
58 ALC883_SONY_VAIO_TT,
59 ALC882_MODEL_LAST,
60};
61
62/*
63 * 2ch mode
64 */
65static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
66/* Mic-in jack as mic in */
67 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
68 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
69/* Line-in jack as Line in */
70 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
71 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
72/* Line-Out as Front */
73 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
74 { } /* end */
75};
76
77/*
78 * 4ch mode
79 */
80static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
81/* Mic-in jack as mic in */
82 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
83 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
84/* Line-in jack as Surround */
85 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
86 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87/* Line-Out as Front */
88 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
89 { } /* end */
90};
91
92/*
93 * 6ch mode
94 */
95static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
96/* Mic-in jack as CLFE */
97 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
98 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
99/* Line-in jack as Surround */
100 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
101 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
102/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
103 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
104 { } /* end */
105};
106
107/*
108 * 8ch mode
109 */
110static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
111/* Mic-in jack as CLFE */
112 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
113 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
114/* Line-in jack as Surround */
115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
117/* Line-Out as Side */
118 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
119 { } /* end */
120};
121
122static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
123 { 2, alc888_4ST_ch2_intel_init },
124 { 4, alc888_4ST_ch4_intel_init },
125 { 6, alc888_4ST_ch6_intel_init },
126 { 8, alc888_4ST_ch8_intel_init },
127};
128
129/*
130 * ALC888 Fujitsu Siemens Amillo xa3530
131 */
132
133static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
134/* Front Mic: set to PIN_IN (empty by default) */
135 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
136/* Connect Internal HP to Front */
137 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
138 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
139 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
140/* Connect Bass HP to Front */
141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
144/* Connect Line-Out side jack (SPDIF) to Side */
145 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
146 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
147 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
148/* Connect Mic jack to CLFE */
149 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
150 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
151 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
152/* Connect Line-in jack to Surround */
153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
155 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
156/* Connect HP out jack to Front */
157 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
158 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
159 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
160/* Enable unsolicited event for HP jack and Line-out jack */
161 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
162 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
163 {}
164};
165
166static void alc889_automute_setup(struct hda_codec *codec)
167{
168 struct alc_spec *spec = codec->spec;
169
170 spec->autocfg.hp_pins[0] = 0x15;
171 spec->autocfg.speaker_pins[0] = 0x14;
172 spec->autocfg.speaker_pins[1] = 0x16;
173 spec->autocfg.speaker_pins[2] = 0x17;
174 spec->autocfg.speaker_pins[3] = 0x19;
175 spec->autocfg.speaker_pins[4] = 0x1a;
176 spec->automute = 1;
177 spec->automute_mode = ALC_AUTOMUTE_AMP;
178}
179
180static void alc889_intel_init_hook(struct hda_codec *codec)
181{
182 alc889_coef_init(codec);
183 alc_hp_automute(codec);
184}
185
186static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
187{
188 struct alc_spec *spec = codec->spec;
189
190 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
191 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
192 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
193 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
194 spec->automute = 1;
195 spec->automute_mode = ALC_AUTOMUTE_AMP;
196}
197
198/*
199 * ALC888 Acer Aspire 4930G model
200 */
201
202static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
203/* Front Mic: set to PIN_IN (empty by default) */
204 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
205/* Unselect Front Mic by default in input mixer 3 */
206 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
207/* Enable unsolicited event for HP jack */
208 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
209/* Connect Internal HP to front */
210 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
211 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
212 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
213/* Connect HP out to front */
214 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
215 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
216 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
217 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
218 { }
219};
220
221/*
222 * ALC888 Acer Aspire 6530G model
223 */
224
225static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
226/* Route to built-in subwoofer as well as speakers */
227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
229 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
230 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
231/* Bias voltage on for external mic port */
232 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
233/* Front Mic: set to PIN_IN (empty by default) */
234 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
235/* Unselect Front Mic by default in input mixer 3 */
236 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
237/* Enable unsolicited event for HP jack */
238 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
239/* Enable speaker output */
240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
241 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
242 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
243/* Enable headphone output */
244 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
245 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
246 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
247 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
248 { }
249};
250
251/*
252 *ALC888 Acer Aspire 7730G model
253 */
254
255static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
256/* Bias voltage on for external mic port */
257 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
258/* Front Mic: set to PIN_IN (empty by default) */
259 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
260/* Unselect Front Mic by default in input mixer 3 */
261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
262/* Enable unsolicited event for HP jack */
263 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
264/* Enable speaker output */
265 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
266 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
267 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
268/* Enable headphone output */
269 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
272 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
273/*Enable internal subwoofer */
274 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
275 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
276 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
277 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
278 { }
279};
280
281/*
282 * ALC889 Acer Aspire 8930G model
283 */
284
285static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
286/* Front Mic: set to PIN_IN (empty by default) */
287 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
288/* Unselect Front Mic by default in input mixer 3 */
289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
290/* Enable unsolicited event for HP jack */
291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
292/* Connect Internal Front to Front */
293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
295 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
296/* Connect Internal Rear to Rear */
297 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
298 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
299 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
300/* Connect Internal CLFE to CLFE */
301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
303 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
304/* Connect HP out to Front */
305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
308/* Enable all DACs */
309/* DAC DISABLE/MUTE 1? */
310/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
311 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
312 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
313/* DAC DISABLE/MUTE 2? */
314/* some bit here disables the other DACs. Init=0x4900 */
315 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
316 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
317/* DMIC fix
318 * This laptop has a stereo digital microphone. The mics are only 1cm apart
319 * which makes the stereo useless. However, either the mic or the ALC889
320 * makes the signal become a difference/sum signal instead of standard
321 * stereo, which is annoying. So instead we flip this bit which makes the
322 * codec replicate the sum signal to both channels, turning it into a
323 * normal mono mic.
324 */
325/* DMIC_CONTROL? Init value = 0x0001 */
326 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
327 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
328 { }
329};
330
331static const struct hda_input_mux alc888_2_capture_sources[2] = {
332 /* Front mic only available on one ADC */
333 {
334 .num_items = 4,
335 .items = {
336 { "Mic", 0x0 },
337 { "Line", 0x2 },
338 { "CD", 0x4 },
339 { "Front Mic", 0xb },
340 },
341 },
342 {
343 .num_items = 3,
344 .items = {
345 { "Mic", 0x0 },
346 { "Line", 0x2 },
347 { "CD", 0x4 },
348 },
349 }
350};
351
352static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
353 /* Interal mic only available on one ADC */
354 {
355 .num_items = 5,
356 .items = {
357 { "Mic", 0x0 },
358 { "Line In", 0x2 },
359 { "CD", 0x4 },
360 { "Input Mix", 0xa },
361 { "Internal Mic", 0xb },
362 },
363 },
364 {
365 .num_items = 4,
366 .items = {
367 { "Mic", 0x0 },
368 { "Line In", 0x2 },
369 { "CD", 0x4 },
370 { "Input Mix", 0xa },
371 },
372 }
373};
374
375static const struct hda_input_mux alc889_capture_sources[3] = {
376 /* Digital mic only available on first "ADC" */
377 {
378 .num_items = 5,
379 .items = {
380 { "Mic", 0x0 },
381 { "Line", 0x2 },
382 { "CD", 0x4 },
383 { "Front Mic", 0xb },
384 { "Input Mix", 0xa },
385 },
386 },
387 {
388 .num_items = 4,
389 .items = {
390 { "Mic", 0x0 },
391 { "Line", 0x2 },
392 { "CD", 0x4 },
393 { "Input Mix", 0xa },
394 },
395 },
396 {
397 .num_items = 4,
398 .items = {
399 { "Mic", 0x0 },
400 { "Line", 0x2 },
401 { "CD", 0x4 },
402 { "Input Mix", 0xa },
403 },
404 }
405};
406
407static const struct snd_kcontrol_new alc888_base_mixer[] = {
408 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
409 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
410 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
411 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
412 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
413 HDA_OUTPUT),
414 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
415 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
416 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
417 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
418 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
419 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
420 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
424 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
426 { } /* end */
427};
428
429static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
432 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
433 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
434 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
435 HDA_OUTPUT),
436 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
437 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
438 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
439 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
440 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 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("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
444 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
446 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
448 { } /* end */
449};
450
451static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
452 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
453 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
454 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
457 HDA_OUTPUT),
458 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
459 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
460 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
461 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
462 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
466 { } /* end */
467};
468
469
470static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
471{
472 struct alc_spec *spec = codec->spec;
473
474 spec->autocfg.hp_pins[0] = 0x15;
475 spec->autocfg.speaker_pins[0] = 0x14;
476 spec->autocfg.speaker_pins[1] = 0x16;
477 spec->autocfg.speaker_pins[2] = 0x17;
478 spec->automute = 1;
479 spec->automute_mode = ALC_AUTOMUTE_AMP;
480}
481
482static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
483{
484 struct alc_spec *spec = codec->spec;
485
486 spec->autocfg.hp_pins[0] = 0x15;
487 spec->autocfg.speaker_pins[0] = 0x14;
488 spec->autocfg.speaker_pins[1] = 0x16;
489 spec->autocfg.speaker_pins[2] = 0x17;
490 spec->automute = 1;
491 spec->automute_mode = ALC_AUTOMUTE_AMP;
492}
493
494static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
495{
496 struct alc_spec *spec = codec->spec;
497
498 spec->autocfg.hp_pins[0] = 0x15;
499 spec->autocfg.speaker_pins[0] = 0x14;
500 spec->autocfg.speaker_pins[1] = 0x16;
501 spec->autocfg.speaker_pins[2] = 0x17;
502 spec->automute = 1;
503 spec->automute_mode = ALC_AUTOMUTE_AMP;
504}
505
506static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
507{
508 struct alc_spec *spec = codec->spec;
509
510 spec->autocfg.hp_pins[0] = 0x15;
511 spec->autocfg.speaker_pins[0] = 0x14;
512 spec->autocfg.speaker_pins[1] = 0x16;
513 spec->autocfg.speaker_pins[2] = 0x1b;
514 spec->automute = 1;
515 spec->automute_mode = ALC_AUTOMUTE_AMP;
516}
517
518#define ALC882_DIGOUT_NID 0x06
519#define ALC882_DIGIN_NID 0x0a
520#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
521#define ALC883_DIGIN_NID ALC882_DIGIN_NID
522#define ALC1200_DIGOUT_NID 0x10
523
524
525static const struct hda_channel_mode alc882_ch_modes[1] = {
526 { 8, NULL }
527};
528
529/* DACs */
530static const hda_nid_t alc882_dac_nids[4] = {
531 /* front, rear, clfe, rear_surr */
532 0x02, 0x03, 0x04, 0x05
533};
534#define alc883_dac_nids alc882_dac_nids
535
536/* ADCs */
537#define alc882_adc_nids alc880_adc_nids
538#define alc882_adc_nids_alt alc880_adc_nids_alt
539#define alc883_adc_nids alc882_adc_nids_alt
540static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
541static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
542#define alc889_adc_nids alc880_adc_nids
543
544static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
545static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
546#define alc883_capsrc_nids alc882_capsrc_nids_alt
547static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
548#define alc889_capsrc_nids alc882_capsrc_nids
549
550/* input MUX */
551/* FIXME: should be a matrix-type input source selection */
552
553static const struct hda_input_mux alc882_capture_source = {
554 .num_items = 4,
555 .items = {
556 { "Mic", 0x0 },
557 { "Front Mic", 0x1 },
558 { "Line", 0x2 },
559 { "CD", 0x4 },
560 },
561};
562
563#define alc883_capture_source alc882_capture_source
564
565static const struct hda_input_mux alc889_capture_source = {
566 .num_items = 3,
567 .items = {
568 { "Front Mic", 0x0 },
569 { "Mic", 0x3 },
570 { "Line", 0x2 },
571 },
572};
573
574static const struct hda_input_mux mb5_capture_source = {
575 .num_items = 3,
576 .items = {
577 { "Mic", 0x1 },
578 { "Line", 0x7 },
579 { "CD", 0x4 },
580 },
581};
582
583static const struct hda_input_mux macmini3_capture_source = {
584 .num_items = 2,
585 .items = {
586 { "Line", 0x2 },
587 { "CD", 0x4 },
588 },
589};
590
591static const struct hda_input_mux alc883_3stack_6ch_intel = {
592 .num_items = 4,
593 .items = {
594 { "Mic", 0x1 },
595 { "Front Mic", 0x0 },
596 { "Line", 0x2 },
597 { "CD", 0x4 },
598 },
599};
600
601static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
602 .num_items = 2,
603 .items = {
604 { "Mic", 0x1 },
605 { "Line", 0x2 },
606 },
607};
608
609static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
610 .num_items = 4,
611 .items = {
612 { "Mic", 0x0 },
613 { "Internal Mic", 0x1 },
614 { "Line", 0x2 },
615 { "CD", 0x4 },
616 },
617};
618
619static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
620 .num_items = 2,
621 .items = {
622 { "Mic", 0x0 },
623 { "Internal Mic", 0x1 },
624 },
625};
626
627static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
628 .num_items = 3,
629 .items = {
630 { "Mic", 0x0 },
631 { "Front Mic", 0x1 },
632 { "Line", 0x4 },
633 },
634};
635
636static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
637 .num_items = 2,
638 .items = {
639 { "Mic", 0x0 },
640 { "Line", 0x2 },
641 },
642};
643
644static const struct hda_input_mux alc889A_mb31_capture_source = {
645 .num_items = 2,
646 .items = {
647 { "Mic", 0x0 },
648 /* Front Mic (0x01) unused */
649 { "Line", 0x2 },
650 /* Line 2 (0x03) unused */
651 /* CD (0x04) unused? */
652 },
653};
654
655static const struct hda_input_mux alc889A_imac91_capture_source = {
656 .num_items = 2,
657 .items = {
658 { "Mic", 0x01 },
659 { "Line", 0x2 }, /* Not sure! */
660 },
661};
662
663/*
664 * 2ch mode
665 */
666static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
667 { 2, NULL }
668};
669
670/*
671 * 2ch mode
672 */
673static const struct hda_verb alc882_3ST_ch2_init[] = {
674 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
675 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
676 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
677 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
678 { } /* end */
679};
680
681/*
682 * 4ch mode
683 */
684static const struct hda_verb alc882_3ST_ch4_init[] = {
685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
689 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
690 { } /* end */
691};
692
693/*
694 * 6ch mode
695 */
696static const struct hda_verb alc882_3ST_ch6_init[] = {
697 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
698 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
699 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
700 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
701 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
702 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
703 { } /* end */
704};
705
706static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
707 { 2, alc882_3ST_ch2_init },
708 { 4, alc882_3ST_ch4_init },
709 { 6, alc882_3ST_ch6_init },
710};
711
712#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
713
714/*
715 * 2ch mode
716 */
717static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
718 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
719 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
720 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
721 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
722 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
723 { } /* end */
724};
725
726/*
727 * 4ch mode
728 */
729static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
730 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
731 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
732 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
733 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
734 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
735 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
736 { } /* end */
737};
738
739/*
740 * 6ch mode
741 */
742static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
743 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
744 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
745 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
746 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
747 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
748 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
749 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
750 { } /* end */
751};
752
753static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
754 { 2, alc883_3ST_ch2_clevo_init },
755 { 4, alc883_3ST_ch4_clevo_init },
756 { 6, alc883_3ST_ch6_clevo_init },
757};
758
759
760/*
761 * 6ch mode
762 */
763static const struct hda_verb alc882_sixstack_ch6_init[] = {
764 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
765 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
766 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
767 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
768 { } /* end */
769};
770
771/*
772 * 8ch mode
773 */
774static const struct hda_verb alc882_sixstack_ch8_init[] = {
775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
776 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
777 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
778 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
779 { } /* end */
780};
781
782static const struct hda_channel_mode alc882_sixstack_modes[2] = {
783 { 6, alc882_sixstack_ch6_init },
784 { 8, alc882_sixstack_ch8_init },
785};
786
787
788/* Macbook Air 2,1 */
789
790static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
791 { 2, NULL },
792};
793
794/*
795 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
796 */
797
798/*
799 * 2ch mode
800 */
801static const struct hda_verb alc885_mbp_ch2_init[] = {
802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
803 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
804 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
805 { } /* end */
806};
807
808/*
809 * 4ch mode
810 */
811static const struct hda_verb alc885_mbp_ch4_init[] = {
812 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
813 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
814 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
815 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
816 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
817 { } /* end */
818};
819
820static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
821 { 2, alc885_mbp_ch2_init },
822 { 4, alc885_mbp_ch4_init },
823};
824
825/*
826 * 2ch
827 * Speakers/Woofer/HP = Front
828 * LineIn = Input
829 */
830static const struct hda_verb alc885_mb5_ch2_init[] = {
831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
832 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
833 { } /* end */
834};
835
836/*
837 * 6ch mode
838 * Speakers/HP = Front
839 * Woofer = LFE
840 * LineIn = Surround
841 */
842static const struct hda_verb alc885_mb5_ch6_init[] = {
843 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
844 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
845 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
846 { } /* end */
847};
848
849static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
850 { 2, alc885_mb5_ch2_init },
851 { 6, alc885_mb5_ch6_init },
852};
853
854#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
855
856/*
857 * 2ch mode
858 */
859static const struct hda_verb alc883_4ST_ch2_init[] = {
860 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
861 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
862 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
863 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
864 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
865 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
866 { } /* end */
867};
868
869/*
870 * 4ch mode
871 */
872static const struct hda_verb alc883_4ST_ch4_init[] = {
873 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
874 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
875 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
876 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
877 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
878 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
879 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
880 { } /* end */
881};
882
883/*
884 * 6ch mode
885 */
886static const struct hda_verb alc883_4ST_ch6_init[] = {
887 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
888 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
889 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
890 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
891 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
892 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
893 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
894 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
895 { } /* end */
896};
897
898/*
899 * 8ch mode
900 */
901static const struct hda_verb alc883_4ST_ch8_init[] = {
902 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
903 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
904 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
905 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
906 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
907 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
908 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
909 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
910 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
911 { } /* end */
912};
913
914static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
915 { 2, alc883_4ST_ch2_init },
916 { 4, alc883_4ST_ch4_init },
917 { 6, alc883_4ST_ch6_init },
918 { 8, alc883_4ST_ch8_init },
919};
920
921
922/*
923 * 2ch mode
924 */
925static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
926 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
927 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
928 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
929 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
930 { } /* end */
931};
932
933/*
934 * 4ch mode
935 */
936static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
937 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
938 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
939 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
940 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
941 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
942 { } /* end */
943};
944
945/*
946 * 6ch mode
947 */
948static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
949 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
950 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
951 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
952 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
953 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
954 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
955 { } /* end */
956};
957
958static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
959 { 2, alc883_3ST_ch2_intel_init },
960 { 4, alc883_3ST_ch4_intel_init },
961 { 6, alc883_3ST_ch6_intel_init },
962};
963
964/*
965 * 2ch mode
966 */
967static const struct hda_verb alc889_ch2_intel_init[] = {
968 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
969 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
970 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
971 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
972 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
973 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
974 { } /* end */
975};
976
977/*
978 * 6ch mode
979 */
980static const struct hda_verb alc889_ch6_intel_init[] = {
981 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
982 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
983 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
984 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
985 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
986 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
987 { } /* end */
988};
989
990/*
991 * 8ch mode
992 */
993static const struct hda_verb alc889_ch8_intel_init[] = {
994 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
995 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
996 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
997 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
998 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
999 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1000 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1001 { } /* end */
1002};
1003
1004static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
1005 { 2, alc889_ch2_intel_init },
1006 { 6, alc889_ch6_intel_init },
1007 { 8, alc889_ch8_intel_init },
1008};
1009
1010/*
1011 * 6ch mode
1012 */
1013static const struct hda_verb alc883_sixstack_ch6_init[] = {
1014 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
1015 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1016 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1017 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1018 { } /* end */
1019};
1020
1021/*
1022 * 8ch mode
1023 */
1024static const struct hda_verb alc883_sixstack_ch8_init[] = {
1025 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1026 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1027 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1028 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1029 { } /* end */
1030};
1031
1032static const struct hda_channel_mode alc883_sixstack_modes[2] = {
1033 { 6, alc883_sixstack_ch6_init },
1034 { 8, alc883_sixstack_ch8_init },
1035};
1036
1037
1038/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
1039 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
1040 */
1041static const struct snd_kcontrol_new alc882_base_mixer[] = {
1042 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1043 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1044 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1045 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1046 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1047 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1048 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1049 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1050 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1051 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1052 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1053 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1054 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1055 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1056 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1058 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1059 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1060 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1061 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1062 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1063 { } /* end */
1064};
1065
1066/* Macbook Air 2,1 same control for HP and internal Speaker */
1067
1068static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
1069 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1070 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
1071 { }
1072};
1073
1074
1075static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
1076 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1077 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
1078 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1079 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
1080 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1081 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1082 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
1084 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
1085 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
1086 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
1087 { } /* end */
1088};
1089
1090static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
1091 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1092 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
1093 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1094 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
1095 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1096 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
1097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
1098 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
1099 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
1100 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
1101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1102 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1103 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
1104 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
1105 { } /* end */
1106};
1107
1108static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
1109 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1110 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
1111 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1112 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
1113 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1114 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
1115 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
1116 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
1117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
1118 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
1119 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
1120 { } /* end */
1121};
1122
1123static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
1124 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1125 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
1126 { } /* end */
1127};
1128
1129
1130static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
1131 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1132 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1133 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1134 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1135 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1136 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1140 { } /* end */
1141};
1142
1143static const struct snd_kcontrol_new alc882_targa_mixer[] = {
1144 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1145 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1149 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1150 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1151 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1152 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1153 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1154 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1155 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1156 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1157 { } /* end */
1158};
1159
1160/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
1161 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
1162 */
1163static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
1164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1165 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1167 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
1168 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1169 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1172 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
1173 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
1174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1175 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1176 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1177 { } /* end */
1178};
1179
1180static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
1181 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1182 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1184 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1185 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1190 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1191 { } /* end */
1192};
1193
1194static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
1195 {
1196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1197 .name = "Channel Mode",
1198 .info = alc_ch_mode_info,
1199 .get = alc_ch_mode_get,
1200 .put = alc_ch_mode_put,
1201 },
1202 { } /* end */
1203};
1204
1205static const struct hda_verb alc882_base_init_verbs[] = {
1206 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1207 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1208 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1209 /* Rear mixer */
1210 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1211 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1212 /* CLFE mixer */
1213 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1214 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1215 /* Side mixer */
1216 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1217 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1218
1219 /* Front Pin: output 0 (0x0c) */
1220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1221 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1222 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1223 /* Rear Pin: output 1 (0x0d) */
1224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1226 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
1227 /* CLFE Pin: output 2 (0x0e) */
1228 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1229 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1230 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1231 /* Side Pin: output 3 (0x0f) */
1232 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1233 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1234 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1235 /* Mic (rear) pin: input vref at 80% */
1236 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1237 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1238 /* Front Mic pin: input vref at 80% */
1239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1240 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1241 /* Line In pin: input */
1242 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1243 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1244 /* Line-2 In: Headphone output (output 0 - 0x0c) */
1245 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1246 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1247 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1248 /* CD pin widget for input */
1249 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1250
1251 /* FIXME: use matrix-type input source selection */
1252 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1253 /* Input mixer2 */
1254 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1255 /* Input mixer3 */
1256 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1257 /* ADC2: mute amp left and right */
1258 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1259 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1260 /* ADC3: mute amp left and right */
1261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1262 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1263
1264 { }
1265};
1266
1267static const struct hda_verb alc882_adc1_init_verbs[] = {
1268 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1269 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1270 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1271 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1272 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1273 /* ADC1: mute amp left and right */
1274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1275 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1276 { }
1277};
1278
1279static const struct hda_verb alc882_eapd_verbs[] = {
1280 /* change to EAPD mode */
1281 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1282 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1283 { }
1284};
1285
1286static const struct hda_verb alc889_eapd_verbs[] = {
1287 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1288 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1289 { }
1290};
1291
1292static const struct hda_verb alc_hp15_unsol_verbs[] = {
1293 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1294 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1295 {}
1296};
1297
1298static const struct hda_verb alc885_init_verbs[] = {
1299 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1302 /* Rear mixer */
1303 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1304 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1305 /* CLFE mixer */
1306 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1308 /* Side mixer */
1309 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1310 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1311
1312 /* Front HP Pin: output 0 (0x0c) */
1313 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1314 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1315 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1316 /* Front Pin: output 0 (0x0c) */
1317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1318 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1319 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1320 /* Rear Pin: output 1 (0x0d) */
1321 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1322 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1323 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
1324 /* CLFE Pin: output 2 (0x0e) */
1325 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1326 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1327 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1328 /* Side Pin: output 3 (0x0f) */
1329 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1330 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1331 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1332 /* Mic (rear) pin: input vref at 80% */
1333 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1334 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1335 /* Front Mic pin: input vref at 80% */
1336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1338 /* Line In pin: input */
1339 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1340 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1341
1342 /* Mixer elements: 0x18, , 0x1a, 0x1b */
1343 /* Input mixer1 */
1344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1345 /* Input mixer2 */
1346 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1347 /* Input mixer3 */
1348 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1349 /* ADC2: mute amp left and right */
1350 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1351 /* ADC3: mute amp left and right */
1352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1353
1354 { }
1355};
1356
1357static const struct hda_verb alc885_init_input_verbs[] = {
1358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1361 { }
1362};
1363
1364
1365/* Unmute Selector 24h and set the default input to front mic */
1366static const struct hda_verb alc889_init_input_verbs[] = {
1367 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
1368 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 { }
1370};
1371
1372
1373#define alc883_init_verbs alc882_base_init_verbs
1374
1375/* Mac Pro test */
1376static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
1377 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1378 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1379 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
1380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
1381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
1382 /* FIXME: this looks suspicious...
1383 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
1384 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
1385 */
1386 { } /* end */
1387};
1388
1389static const struct hda_verb alc882_macpro_init_verbs[] = {
1390 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1394 /* Front Pin: output 0 (0x0c) */
1395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1397 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1398 /* Front Mic pin: input vref at 80% */
1399 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1400 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1401 /* Speaker: output */
1402 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1403 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1404 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
1405 /* Headphone output (output 0 - 0x0c) */
1406 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1407 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1408 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1409
1410 /* FIXME: use matrix-type input source selection */
1411 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1412 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1413 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1414 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1415 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1416 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1417 /* Input mixer2 */
1418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1420 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1421 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1422 /* Input mixer3 */
1423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1426 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1427 /* ADC1: mute amp left and right */
1428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1429 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1430 /* ADC2: mute amp left and right */
1431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1432 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1433 /* ADC3: mute amp left and right */
1434 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1435 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1436
1437 { }
1438};
1439
1440/* Macbook 5,1 */
1441static const struct hda_verb alc885_mb5_init_verbs[] = {
1442 /* DACs */
1443 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1444 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1445 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1446 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1447 /* Front mixer */
1448 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1449 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1451 /* Surround mixer */
1452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1454 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1455 /* LFE mixer */
1456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1457 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1458 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1459 /* HP mixer */
1460 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1463 /* Front Pin (0x0c) */
1464 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1465 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1466 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1467 /* LFE Pin (0x0e) */
1468 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1469 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1470 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
1471 /* HP Pin (0x0f) */
1472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1474 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
1475 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1476 /* Front Mic pin: input vref at 80% */
1477 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1478 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1479 /* Line In pin */
1480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1482
1483 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
1484 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
1485 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
1486 { }
1487};
1488
1489/* Macmini 3,1 */
1490static const struct hda_verb alc885_macmini3_init_verbs[] = {
1491 /* DACs */
1492 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1493 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1494 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1496 /* Front mixer */
1497 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1498 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1500 /* Surround mixer */
1501 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1502 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1503 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1504 /* LFE mixer */
1505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1506 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1508 /* HP mixer */
1509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1511 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1512 /* Front Pin (0x0c) */
1513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1515 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1516 /* LFE Pin (0x0e) */
1517 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1519 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
1520 /* HP Pin (0x0f) */
1521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1523 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
1524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1525 /* Line In pin */
1526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1528
1529 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1532 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1533 { }
1534};
1535
1536
1537static const struct hda_verb alc885_mba21_init_verbs[] = {
1538 /*Internal and HP Speaker Mixer*/
1539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1542 /*Internal Speaker Pin (0x0c)*/
1543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1545 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1546 /* HP Pin: output 0 (0x0e) */
1547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
1548 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1549 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1550 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
1551 /* Line in (is hp when jack connected)*/
1552 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
1553 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1554
1555 { }
1556 };
1557
1558
1559/* Macbook Pro rev3 */
1560static const struct hda_verb alc885_mbp3_init_verbs[] = {
1561 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1565 /* Rear mixer */
1566 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1568 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1569 /* HP mixer */
1570 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1571 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1572 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1573 /* Front Pin: output 0 (0x0c) */
1574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1576 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1577 /* HP Pin: output 0 (0x0e) */
1578 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
1579 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1580 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
1581 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1582 /* Mic (rear) pin: input vref at 80% */
1583 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1585 /* Front Mic pin: input vref at 80% */
1586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1588 /* Line In pin: use output 1 when in LineOut mode */
1589 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1591 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1592
1593 /* FIXME: use matrix-type input source selection */
1594 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1595 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1596 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1597 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1598 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1599 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1600 /* Input mixer2 */
1601 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1602 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1605 /* Input mixer3 */
1606 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1610 /* ADC1: mute amp left and right */
1611 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1612 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1613 /* ADC2: mute amp left and right */
1614 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1615 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1616 /* ADC3: mute amp left and right */
1617 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1618 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1619
1620 { }
1621};
1622
1623/* iMac 9,1 */
1624static const struct hda_verb alc885_imac91_init_verbs[] = {
1625 /* Internal Speaker Pin (0x0c) */
1626 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1627 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1628 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1631 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1632 /* HP Pin: Rear */
1633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1635 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1636 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
1637 /* Line in Rear */
1638 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
1639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1640 /* Front Mic pin: input vref at 80% */
1641 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1642 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1643 /* Rear mixer */
1644 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1645 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1647 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
1648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1651 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1656 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1661 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1666 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1667 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1668 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1669 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1671 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1672 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1673 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1674 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1675 { }
1676};
1677
1678/* iMac 24 mixer. */
1679static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
1680 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1681 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
1682 { } /* end */
1683};
1684
1685/* iMac 24 init verbs. */
1686static const struct hda_verb alc885_imac24_init_verbs[] = {
1687 /* Internal speakers: output 0 (0x0c) */
1688 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1691 /* Internal speakers: output 0 (0x0c) */
1692 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1695 /* Headphone: output 0 (0x0c) */
1696 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1697 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1700 /* Front Mic: input vref at 80% */
1701 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1702 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1703 { }
1704};
1705
1706/* Toggle speaker-output according to the hp-jack state */
1707static void alc885_imac24_setup(struct hda_codec *codec)
1708{
1709 struct alc_spec *spec = codec->spec;
1710
1711 spec->autocfg.hp_pins[0] = 0x14;
1712 spec->autocfg.speaker_pins[0] = 0x18;
1713 spec->autocfg.speaker_pins[1] = 0x1a;
1714 spec->automute = 1;
1715 spec->automute_mode = ALC_AUTOMUTE_AMP;
1716}
1717
1718#define alc885_mb5_setup alc885_imac24_setup
1719#define alc885_macmini3_setup alc885_imac24_setup
1720
1721/* Macbook Air 2,1 */
1722static void alc885_mba21_setup(struct hda_codec *codec)
1723{
1724 struct alc_spec *spec = codec->spec;
1725
1726 spec->autocfg.hp_pins[0] = 0x14;
1727 spec->autocfg.speaker_pins[0] = 0x18;
1728 spec->automute = 1;
1729 spec->automute_mode = ALC_AUTOMUTE_AMP;
1730}
1731
1732
1733
1734static void alc885_mbp3_setup(struct hda_codec *codec)
1735{
1736 struct alc_spec *spec = codec->spec;
1737
1738 spec->autocfg.hp_pins[0] = 0x15;
1739 spec->autocfg.speaker_pins[0] = 0x14;
1740 spec->automute = 1;
1741 spec->automute_mode = ALC_AUTOMUTE_AMP;
1742}
1743
1744static void alc885_imac91_setup(struct hda_codec *codec)
1745{
1746 struct alc_spec *spec = codec->spec;
1747
1748 spec->autocfg.hp_pins[0] = 0x14;
1749 spec->autocfg.speaker_pins[0] = 0x18;
1750 spec->autocfg.speaker_pins[1] = 0x1a;
1751 spec->automute = 1;
1752 spec->automute_mode = ALC_AUTOMUTE_AMP;
1753}
1754
1755static const struct hda_verb alc882_targa_verbs[] = {
1756 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1757 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1758
1759 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1761
1762 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1763 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1764 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1765
1766 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1767 { } /* end */
1768};
1769
1770/* toggle speaker-output according to the hp-jack state */
1771static void alc882_targa_automute(struct hda_codec *codec)
1772{
1773 struct alc_spec *spec = codec->spec;
1774 alc_hp_automute(codec);
1775 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
1776 spec->jack_present ? 1 : 3);
1777}
1778
1779static void alc882_targa_setup(struct hda_codec *codec)
1780{
1781 struct alc_spec *spec = codec->spec;
1782
1783 spec->autocfg.hp_pins[0] = 0x14;
1784 spec->autocfg.speaker_pins[0] = 0x1b;
1785 spec->automute = 1;
1786 spec->automute_mode = ALC_AUTOMUTE_AMP;
1787}
1788
1789static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
1790{
1791 if ((res >> 26) == ALC_HP_EVENT)
1792 alc882_targa_automute(codec);
1793}
1794
1795static const struct hda_verb alc882_asus_a7j_verbs[] = {
1796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1798
1799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1801 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1802
1803 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1805 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1806
1807 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1808 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1809 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1810 { } /* end */
1811};
1812
1813static const struct hda_verb alc882_asus_a7m_verbs[] = {
1814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1815 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1816
1817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1820
1821 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1822 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1823 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1824
1825 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1826 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1827 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1828 { } /* end */
1829};
1830
1831static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1832{
1833 unsigned int gpiostate, gpiomask, gpiodir;
1834
1835 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
1836 AC_VERB_GET_GPIO_DATA, 0);
1837
1838 if (!muted)
1839 gpiostate |= (1 << pin);
1840 else
1841 gpiostate &= ~(1 << pin);
1842
1843 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
1844 AC_VERB_GET_GPIO_MASK, 0);
1845 gpiomask |= (1 << pin);
1846
1847 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
1848 AC_VERB_GET_GPIO_DIRECTION, 0);
1849 gpiodir |= (1 << pin);
1850
1851
1852 snd_hda_codec_write(codec, codec->afg, 0,
1853 AC_VERB_SET_GPIO_MASK, gpiomask);
1854 snd_hda_codec_write(codec, codec->afg, 0,
1855 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1856
1857 msleep(1);
1858
1859 snd_hda_codec_write(codec, codec->afg, 0,
1860 AC_VERB_SET_GPIO_DATA, gpiostate);
1861}
1862
1863/* set up GPIO at initialization */
1864static void alc885_macpro_init_hook(struct hda_codec *codec)
1865{
1866 alc882_gpio_mute(codec, 0, 0);
1867 alc882_gpio_mute(codec, 1, 0);
1868}
1869
1870/* set up GPIO and update auto-muting at initialization */
1871static void alc885_imac24_init_hook(struct hda_codec *codec)
1872{
1873 alc885_macpro_init_hook(codec);
1874 alc_hp_automute(codec);
1875}
1876
1877/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
1878static const struct hda_verb alc889A_mb31_ch2_init[] = {
1879 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
1880 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1881 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
1882 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
1883 { } /* end */
1884};
1885
1886/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
1887static const struct hda_verb alc889A_mb31_ch4_init[] = {
1888 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
1889 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1890 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
1891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
1892 { } /* end */
1893};
1894
1895/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
1896static const struct hda_verb alc889A_mb31_ch5_init[] = {
1897 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
1898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1899 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
1900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
1901 { } /* end */
1902};
1903
1904/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
1905static const struct hda_verb alc889A_mb31_ch6_init[] = {
1906 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
1907 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
1908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
1909 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
1910 { } /* end */
1911};
1912
1913static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
1914 { 2, alc889A_mb31_ch2_init },
1915 { 4, alc889A_mb31_ch4_init },
1916 { 5, alc889A_mb31_ch5_init },
1917 { 6, alc889A_mb31_ch6_init },
1918};
1919
1920static const struct hda_verb alc883_medion_eapd_verbs[] = {
1921 /* eanable EAPD on medion laptop */
1922 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1923 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
1924 { }
1925};
1926
1927#define alc883_base_mixer alc882_base_mixer
1928
1929static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
1930 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1931 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1932 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1933 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1934 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1935 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1936 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1938 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1939 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1940 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1941 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1942 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1943 { } /* end */
1944};
1945
1946static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
1947 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1948 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1949 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1950 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1952 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1954 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1955 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
1956 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1957 { } /* end */
1958};
1959
1960static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
1961 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1962 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1963 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1964 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1966 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1968 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
1970 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1971 { } /* end */
1972};
1973
1974static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
1975 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1976 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1978 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1979 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1981 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1982 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1983 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1985 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1986 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1987 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1988 { } /* end */
1989};
1990
1991static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
1992 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1993 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1994 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1995 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1996 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1997 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1998 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1999 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2005 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2006 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2008 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2009 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2010 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2011 { } /* end */
2012};
2013
2014static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
2015 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2016 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2017 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2018 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2019 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2020 HDA_OUTPUT),
2021 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2022 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2023 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2024 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2025 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2026 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2027 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2028 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2030 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
2031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2032 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2033 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
2034 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2035 { } /* end */
2036};
2037
2038static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
2039 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2040 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2041 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2042 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2043 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2044 HDA_OUTPUT),
2045 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2046 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2047 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2048 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2049 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
2050 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2051 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2052 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2053 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2054 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
2055 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2056 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2057 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
2058 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2059 { } /* end */
2060};
2061
2062static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
2063 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2064 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2065 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2066 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2067 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2068 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2069 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2070 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2077 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2079 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2080 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2081 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2082 { } /* end */
2083};
2084
2085static const struct snd_kcontrol_new alc883_targa_mixer[] = {
2086 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2087 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2089 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2090 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2091 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2092 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2093 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2094 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2095 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2097 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2101 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2103 { } /* end */
2104};
2105
2106static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
2107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2108 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2110 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2111 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2112 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2114 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2116 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2117 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
2118 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2119 { } /* end */
2120};
2121
2122static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
2123 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2124 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2125 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2126 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
2127 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2128 { } /* end */
2129};
2130
2131static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
2132 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2133 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2135 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2140 { } /* end */
2141};
2142
2143static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
2144 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2145 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
2146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2151 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2152 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2153 { } /* end */
2154};
2155
2156static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
2157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2158 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2159 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2160 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
2161 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
2162 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
2163 { } /* end */
2164};
2165
2166static const struct hda_verb alc883_medion_wim2160_verbs[] = {
2167 /* Unmute front mixer */
2168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2170
2171 /* Set speaker pin to front mixer */
2172 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2173
2174 /* Init headphone pin */
2175 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2177 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
2178 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2179
2180 { } /* end */
2181};
2182
2183/* toggle speaker-output according to the hp-jack state */
2184static void alc883_medion_wim2160_setup(struct hda_codec *codec)
2185{
2186 struct alc_spec *spec = codec->spec;
2187
2188 spec->autocfg.hp_pins[0] = 0x1a;
2189 spec->autocfg.speaker_pins[0] = 0x15;
2190 spec->automute = 1;
2191 spec->automute_mode = ALC_AUTOMUTE_AMP;
2192}
2193
2194static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
2195 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2196 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2198 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2199 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2201 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2202 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2203 { } /* end */
2204};
2205
2206static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
2207 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2208 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2211 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2212 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2216 { } /* end */
2217};
2218
2219static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
2220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
2225 0x0d, 1, 0x0, HDA_OUTPUT),
2226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2238 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2239 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2240 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2241 { } /* end */
2242};
2243
2244static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
2245 /* Output mixers */
2246 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
2247 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
2248 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2249 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
2250 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
2251 HDA_OUTPUT),
2252 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
2253 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
2254 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
2255 /* Output switches */
2256 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
2257 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
2258 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
2259 /* Boost mixers */
2260 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
2262 /* Input mixers */
2263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
2264 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2265 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2266 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2267 { } /* end */
2268};
2269
2270static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
2271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2272 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2275 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
2276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2277 { } /* end */
2278};
2279
2280static const struct hda_bind_ctls alc883_bind_cap_vol = {
2281 .ops = &snd_hda_bind_vol,
2282 .values = {
2283 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
2284 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
2285 0
2286 },
2287};
2288
2289static const struct hda_bind_ctls alc883_bind_cap_switch = {
2290 .ops = &snd_hda_bind_sw,
2291 .values = {
2292 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
2293 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
2294 0
2295 },
2296};
2297
2298static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
2299 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2300 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2307 { } /* end */
2308};
2309
2310static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
2311 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
2312 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
2313 {
2314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2315 /* .name = "Capture Source", */
2316 .name = "Input Source",
2317 .count = 1,
2318 .info = alc_mux_enum_info,
2319 .get = alc_mux_enum_get,
2320 .put = alc_mux_enum_put,
2321 },
2322 { } /* end */
2323};
2324
2325static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
2326 {
2327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2328 .name = "Channel Mode",
2329 .info = alc_ch_mode_info,
2330 .get = alc_ch_mode_get,
2331 .put = alc_ch_mode_put,
2332 },
2333 { } /* end */
2334};
2335
2336/* toggle speaker-output according to the hp-jack state */
2337static void alc883_mitac_setup(struct hda_codec *codec)
2338{
2339 struct alc_spec *spec = codec->spec;
2340
2341 spec->autocfg.hp_pins[0] = 0x15;
2342 spec->autocfg.speaker_pins[0] = 0x14;
2343 spec->autocfg.speaker_pins[1] = 0x17;
2344 spec->automute = 1;
2345 spec->automute_mode = ALC_AUTOMUTE_AMP;
2346}
2347
2348static const struct hda_verb alc883_mitac_verbs[] = {
2349 /* HP */
2350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2352 /* Subwoofer */
2353 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2354 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2355
2356 /* enable unsolicited event */
2357 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2358 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, */
2359
2360 { } /* end */
2361};
2362
2363static const struct hda_verb alc883_clevo_m540r_verbs[] = {
2364 /* HP */
2365 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2367 /* Int speaker */
2368 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
2369
2370 /* enable unsolicited event */
2371 /*
2372 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2373 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2374 */
2375
2376 { } /* end */
2377};
2378
2379static const struct hda_verb alc883_clevo_m720_verbs[] = {
2380 /* HP */
2381 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2383 /* Int speaker */
2384 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
2385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2386
2387 /* enable unsolicited event */
2388 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2389 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2390
2391 { } /* end */
2392};
2393
2394static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
2395 /* HP */
2396 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2397 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2398 /* Subwoofer */
2399 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
2400 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2401
2402 /* enable unsolicited event */
2403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2404
2405 { } /* end */
2406};
2407
2408static const struct hda_verb alc883_targa_verbs[] = {
2409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2411
2412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2413 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2414
2415/* Connect Line-Out side jack (SPDIF) to Side */
2416 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2417 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2418 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2419/* Connect Mic jack to CLFE */
2420 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2421 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2422 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2423/* Connect Line-in jack to Surround */
2424 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2426 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2427/* Connect HP out jack to Front */
2428 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2429 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2430 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2431
2432 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2433
2434 { } /* end */
2435};
2436
2437static const struct hda_verb alc883_lenovo_101e_verbs[] = {
2438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2439 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT|AC_USRSP_EN},
2440 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT|AC_USRSP_EN},
2441 { } /* end */
2442};
2443
2444static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
2445 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2447 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2449 { } /* end */
2450};
2451
2452static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
2453 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2456 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT | AC_USRSP_EN},
2457 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2458 { } /* end */
2459};
2460
2461static const struct hda_verb alc883_haier_w66_verbs[] = {
2462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2464
2465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2466
2467 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2468 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2469 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2471 { } /* end */
2472};
2473
2474static const struct hda_verb alc888_lenovo_sky_verbs[] = {
2475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2477 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2479 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2480 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
2482 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2483 { } /* end */
2484};
2485
2486static const struct hda_verb alc888_6st_dell_verbs[] = {
2487 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2488 { }
2489};
2490
2491static const struct hda_verb alc883_vaiott_verbs[] = {
2492 /* HP */
2493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2495
2496 /* enable unsolicited event */
2497 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2498
2499 { } /* end */
2500};
2501
2502static void alc888_3st_hp_setup(struct hda_codec *codec)
2503{
2504 struct alc_spec *spec = codec->spec;
2505
2506 spec->autocfg.hp_pins[0] = 0x1b;
2507 spec->autocfg.speaker_pins[0] = 0x14;
2508 spec->autocfg.speaker_pins[1] = 0x16;
2509 spec->autocfg.speaker_pins[2] = 0x18;
2510 spec->automute = 1;
2511 spec->automute_mode = ALC_AUTOMUTE_AMP;
2512}
2513
2514static const struct hda_verb alc888_3st_hp_verbs[] = {
2515 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
2516 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
2517 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
2518 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2519 { } /* end */
2520};
2521
2522/*
2523 * 2ch mode
2524 */
2525static const struct hda_verb alc888_3st_hp_2ch_init[] = {
2526 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2527 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2528 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2529 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2530 { } /* end */
2531};
2532
2533/*
2534 * 4ch mode
2535 */
2536static const struct hda_verb alc888_3st_hp_4ch_init[] = {
2537 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2538 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2540 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2541 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
2542 { } /* end */
2543};
2544
2545/*
2546 * 6ch mode
2547 */
2548static const struct hda_verb alc888_3st_hp_6ch_init[] = {
2549 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2550 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2551 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
2552 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2553 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2554 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
2555 { } /* end */
2556};
2557
2558static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
2559 { 2, alc888_3st_hp_2ch_init },
2560 { 4, alc888_3st_hp_4ch_init },
2561 { 6, alc888_3st_hp_6ch_init },
2562};
2563
2564static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
2565{
2566 struct alc_spec *spec = codec->spec;
2567
2568 spec->autocfg.hp_pins[0] = 0x1b;
2569 spec->autocfg.line_out_pins[0] = 0x14;
2570 spec->autocfg.speaker_pins[0] = 0x15;
2571 spec->automute = 1;
2572 spec->automute_mode = ALC_AUTOMUTE_AMP;
2573}
2574
2575/* toggle speaker-output according to the hp-jack state */
2576static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
2577{
2578 struct alc_spec *spec = codec->spec;
2579
2580 spec->autocfg.hp_pins[0] = 0x14;
2581 spec->autocfg.speaker_pins[0] = 0x15;
2582 spec->automute = 1;
2583 spec->automute_mode = ALC_AUTOMUTE_AMP;
2584}
2585
2586/* toggle speaker-output according to the hp-jack state */
2587#define alc883_targa_init_hook alc882_targa_init_hook
2588#define alc883_targa_unsol_event alc882_targa_unsol_event
2589
2590static void alc883_clevo_m720_setup(struct hda_codec *codec)
2591{
2592 struct alc_spec *spec = codec->spec;
2593
2594 spec->autocfg.hp_pins[0] = 0x15;
2595 spec->autocfg.speaker_pins[0] = 0x14;
2596 spec->automute = 1;
2597 spec->automute_mode = ALC_AUTOMUTE_AMP;
2598}
2599
2600static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
2601{
2602 alc_hp_automute(codec);
2603 alc88x_simple_mic_automute(codec);
2604}
2605
2606static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
2607 unsigned int res)
2608{
2609 switch (res >> 26) {
2610 case ALC_MIC_EVENT:
2611 alc88x_simple_mic_automute(codec);
2612 break;
2613 default:
2614 alc_sku_unsol_event(codec, res);
2615 break;
2616 }
2617}
2618
2619/* toggle speaker-output according to the hp-jack state */
2620static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
2621{
2622 struct alc_spec *spec = codec->spec;
2623
2624 spec->autocfg.hp_pins[0] = 0x14;
2625 spec->autocfg.speaker_pins[0] = 0x15;
2626 spec->automute = 1;
2627 spec->automute_mode = ALC_AUTOMUTE_AMP;
2628}
2629
2630static void alc883_haier_w66_setup(struct hda_codec *codec)
2631{
2632 struct alc_spec *spec = codec->spec;
2633
2634 spec->autocfg.hp_pins[0] = 0x1b;
2635 spec->autocfg.speaker_pins[0] = 0x14;
2636 spec->automute = 1;
2637 spec->automute_mode = ALC_AUTOMUTE_AMP;
2638}
2639
2640static void alc883_lenovo_101e_setup(struct hda_codec *codec)
2641{
2642 struct alc_spec *spec = codec->spec;
2643
2644 spec->autocfg.hp_pins[0] = 0x1b;
2645 spec->autocfg.line_out_pins[0] = 0x14;
2646 spec->autocfg.speaker_pins[0] = 0x15;
2647 spec->automute = 1;
2648 spec->detect_line = 1;
2649 spec->automute_lines = 1;
2650 spec->automute_mode = ALC_AUTOMUTE_AMP;
2651}
2652
2653/* toggle speaker-output according to the hp-jack state */
2654static void alc883_acer_aspire_setup(struct hda_codec *codec)
2655{
2656 struct alc_spec *spec = codec->spec;
2657
2658 spec->autocfg.hp_pins[0] = 0x14;
2659 spec->autocfg.speaker_pins[0] = 0x15;
2660 spec->autocfg.speaker_pins[1] = 0x16;
2661 spec->automute = 1;
2662 spec->automute_mode = ALC_AUTOMUTE_AMP;
2663}
2664
2665static const struct hda_verb alc883_acer_eapd_verbs[] = {
2666 /* HP Pin: output 0 (0x0c) */
2667 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2668 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2669 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2670 /* Front Pin: output 0 (0x0c) */
2671 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2674 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
2675 /* eanable EAPD on medion laptop */
2676 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2677 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
2678 /* enable unsolicited event */
2679 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2680 { }
2681};
2682
2683static void alc888_6st_dell_setup(struct hda_codec *codec)
2684{
2685 struct alc_spec *spec = codec->spec;
2686
2687 spec->autocfg.hp_pins[0] = 0x1b;
2688 spec->autocfg.speaker_pins[0] = 0x14;
2689 spec->autocfg.speaker_pins[1] = 0x15;
2690 spec->autocfg.speaker_pins[2] = 0x16;
2691 spec->autocfg.speaker_pins[3] = 0x17;
2692 spec->automute = 1;
2693 spec->automute_mode = ALC_AUTOMUTE_AMP;
2694}
2695
2696static void alc888_lenovo_sky_setup(struct hda_codec *codec)
2697{
2698 struct alc_spec *spec = codec->spec;
2699
2700 spec->autocfg.hp_pins[0] = 0x1b;
2701 spec->autocfg.speaker_pins[0] = 0x14;
2702 spec->autocfg.speaker_pins[1] = 0x15;
2703 spec->autocfg.speaker_pins[2] = 0x16;
2704 spec->autocfg.speaker_pins[3] = 0x17;
2705 spec->autocfg.speaker_pins[4] = 0x1a;
2706 spec->automute = 1;
2707 spec->automute_mode = ALC_AUTOMUTE_AMP;
2708}
2709
2710static void alc883_vaiott_setup(struct hda_codec *codec)
2711{
2712 struct alc_spec *spec = codec->spec;
2713
2714 spec->autocfg.hp_pins[0] = 0x15;
2715 spec->autocfg.speaker_pins[0] = 0x14;
2716 spec->autocfg.speaker_pins[1] = 0x17;
2717 spec->automute = 1;
2718 spec->automute_mode = ALC_AUTOMUTE_AMP;
2719}
2720
2721static const struct hda_verb alc888_asus_m90v_verbs[] = {
2722 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2723 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2724 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2725 /* enable unsolicited event */
2726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2727 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2728 { } /* end */
2729};
2730
2731static void alc883_mode2_setup(struct hda_codec *codec)
2732{
2733 struct alc_spec *spec = codec->spec;
2734
2735 spec->autocfg.hp_pins[0] = 0x1b;
2736 spec->autocfg.speaker_pins[0] = 0x14;
2737 spec->autocfg.speaker_pins[1] = 0x15;
2738 spec->autocfg.speaker_pins[2] = 0x16;
2739 spec->ext_mic_pin = 0x18;
2740 spec->int_mic_pin = 0x19;
2741 spec->auto_mic = 1;
2742 spec->automute = 1;
2743 spec->automute_mode = ALC_AUTOMUTE_AMP;
2744}
2745
2746static const struct hda_verb alc888_asus_eee1601_verbs[] = {
2747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2748 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2749 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2752 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2753 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
2754 /* enable unsolicited event */
2755 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2756 { } /* end */
2757};
2758
2759static void alc883_eee1601_inithook(struct hda_codec *codec)
2760{
2761 struct alc_spec *spec = codec->spec;
2762
2763 spec->autocfg.hp_pins[0] = 0x14;
2764 spec->autocfg.speaker_pins[0] = 0x1b;
2765 alc_hp_automute(codec);
2766}
2767
2768static const struct hda_verb alc889A_mb31_verbs[] = {
2769 /* Init rear pin (used as headphone output) */
2770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
2771 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
2772 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2773 /* Init line pin (used as output in 4ch and 6ch mode) */
2774 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
2775 /* Init line 2 pin (used as headphone out by default) */
2776 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
2777 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
2778 { } /* end */
2779};
2780
2781/* Mute speakers according to the headphone jack state */
2782static void alc889A_mb31_automute(struct hda_codec *codec)
2783{
2784 unsigned int present;
2785
2786 /* Mute only in 2ch or 4ch mode */
2787 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
2788 == 0x00) {
2789 present = snd_hda_jack_detect(codec, 0x15);
2790 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2791 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2792 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2793 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2794 }
2795}
2796
2797static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
2798{
2799 if ((res >> 26) == ALC_HP_EVENT)
2800 alc889A_mb31_automute(codec);
2801}
2802
2803static const hda_nid_t alc883_slave_dig_outs[] = {
2804 ALC1200_DIGOUT_NID, 0,
2805};
2806
2807static const hda_nid_t alc1200_slave_dig_outs[] = {
2808 ALC883_DIGOUT_NID, 0,
2809};
2810
2811/*
2812 * configuration and preset
2813 */
2814static const char * const alc882_models[ALC882_MODEL_LAST] = {
2815 [ALC882_3ST_DIG] = "3stack-dig",
2816 [ALC882_6ST_DIG] = "6stack-dig",
2817 [ALC882_ARIMA] = "arima",
2818 [ALC882_W2JC] = "w2jc",
2819 [ALC882_TARGA] = "targa",
2820 [ALC882_ASUS_A7J] = "asus-a7j",
2821 [ALC882_ASUS_A7M] = "asus-a7m",
2822 [ALC885_MACPRO] = "macpro",
2823 [ALC885_MB5] = "mb5",
2824 [ALC885_MACMINI3] = "macmini3",
2825 [ALC885_MBA21] = "mba21",
2826 [ALC885_MBP3] = "mbp3",
2827 [ALC885_IMAC24] = "imac24",
2828 [ALC885_IMAC91] = "imac91",
2829 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
2830 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
2831 [ALC883_3ST_6ch] = "3stack-6ch",
2832 [ALC883_6ST_DIG] = "alc883-6stack-dig",
2833 [ALC883_TARGA_DIG] = "targa-dig",
2834 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
2835 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
2836 [ALC883_ACER] = "acer",
2837 [ALC883_ACER_ASPIRE] = "acer-aspire",
2838 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
2839 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
2840 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
2841 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
2842 [ALC883_MEDION] = "medion",
2843 [ALC883_MEDION_WIM2160] = "medion-wim2160",
2844 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
2845 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
2846 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
2847 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
2848 [ALC888_LENOVO_SKY] = "lenovo-sky",
2849 [ALC883_HAIER_W66] = "haier-w66",
2850 [ALC888_3ST_HP] = "3stack-hp",
2851 [ALC888_6ST_DELL] = "6stack-dell",
2852 [ALC883_MITAC] = "mitac",
2853 [ALC883_CLEVO_M540R] = "clevo-m540r",
2854 [ALC883_CLEVO_M720] = "clevo-m720",
2855 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
2856 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
2857 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
2858 [ALC889A_INTEL] = "intel-alc889a",
2859 [ALC889_INTEL] = "intel-x58",
2860 [ALC1200_ASUS_P5Q] = "asus-p5q",
2861 [ALC889A_MB31] = "mb31",
2862 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
2863 [ALC882_AUTO] = "auto",
2864};
2865
2866static const struct snd_pci_quirk alc882_cfg_tbl[] = {
2867 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
2868
2869 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
2870 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
2871 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
2872 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
2873 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
2874 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
2875 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2876 ALC888_ACER_ASPIRE_4930G),
2877 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2878 ALC888_ACER_ASPIRE_4930G),
2879 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2880 ALC888_ACER_ASPIRE_8930G),
2881 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2882 ALC888_ACER_ASPIRE_8930G),
2883 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
2884 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
2885 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2886 ALC888_ACER_ASPIRE_6530G),
2887 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2888 ALC888_ACER_ASPIRE_6530G),
2889 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2890 ALC888_ACER_ASPIRE_7730G),
2891 /* default Acer -- disabled as it causes more problems.
2892 * model=auto should work fine now
2893 */
2894 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
2895
2896 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
2897
2898 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
2899 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
2900 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
2901 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
2902 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
2903 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
2904
2905 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
2906 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
2907 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
2908 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
2909 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
2910 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
2911 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
2912 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
2913 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
2914 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
2915 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
2916
2917 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
2918 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
2919 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2920 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
2921 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
2922 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
2923 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
2924 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
2925 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
2926
2927 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
2928 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
2929 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
2930 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2931 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
2932 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
2933 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
2934 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
2935 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
2936 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
2937 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
2938 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
2939 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
2940 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
2941 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
2942 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
2943 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
2944 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
2945 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
2946 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
2947 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
2948 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
2949 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
2950 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
2951 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
2952 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
2953 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
2954 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
2955 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
2956 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
2957 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
2958
2959 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
2960 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
2961 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
2962 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
2963 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
2964 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
2965 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
2966 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
2967 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
2968 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
2969 ALC883_FUJITSU_PI2515),
2970 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
2971 ALC888_FUJITSU_XA3530),
2972 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
2973 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2974 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2975 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2976 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
2977 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
2978 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
2979 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
2980
2981 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
2982 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2983 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
2984 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
2985 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
2986 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
2987 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
2988
2989 {}
2990};
2991
2992/* codec SSID table for Intel Mac */
2993static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
2994 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
2995 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
2996 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
2997 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
2998 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
2999 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
3000 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
3001 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
3002 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
3003 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
3004 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
3005 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
3006 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
3007 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
3008 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
3009 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3010 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
3011 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
3012 * so apparently no perfect solution yet
3013 */
3014 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
3015 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
3016 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
3017 {} /* terminator */
3018};
3019
3020static const struct alc_config_preset alc882_presets[] = {
3021 [ALC882_3ST_DIG] = {
3022 .mixers = { alc882_base_mixer },
3023 .init_verbs = { alc882_base_init_verbs,
3024 alc882_adc1_init_verbs },
3025 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3026 .dac_nids = alc882_dac_nids,
3027 .dig_out_nid = ALC882_DIGOUT_NID,
3028 .dig_in_nid = ALC882_DIGIN_NID,
3029 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3030 .channel_mode = alc882_ch_modes,
3031 .need_dac_fix = 1,
3032 .input_mux = &alc882_capture_source,
3033 },
3034 [ALC882_6ST_DIG] = {
3035 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
3036 .init_verbs = { alc882_base_init_verbs,
3037 alc882_adc1_init_verbs },
3038 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3039 .dac_nids = alc882_dac_nids,
3040 .dig_out_nid = ALC882_DIGOUT_NID,
3041 .dig_in_nid = ALC882_DIGIN_NID,
3042 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
3043 .channel_mode = alc882_sixstack_modes,
3044 .input_mux = &alc882_capture_source,
3045 },
3046 [ALC882_ARIMA] = {
3047 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
3048 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3049 alc882_eapd_verbs },
3050 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3051 .dac_nids = alc882_dac_nids,
3052 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
3053 .channel_mode = alc882_sixstack_modes,
3054 .input_mux = &alc882_capture_source,
3055 },
3056 [ALC882_W2JC] = {
3057 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
3058 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3059 alc882_eapd_verbs, alc880_gpio1_init_verbs },
3060 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3061 .dac_nids = alc882_dac_nids,
3062 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3063 .channel_mode = alc880_threestack_modes,
3064 .need_dac_fix = 1,
3065 .input_mux = &alc882_capture_source,
3066 .dig_out_nid = ALC882_DIGOUT_NID,
3067 },
3068 [ALC885_MBA21] = {
3069 .mixers = { alc885_mba21_mixer },
3070 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
3071 .num_dacs = 2,
3072 .dac_nids = alc882_dac_nids,
3073 .channel_mode = alc885_mba21_ch_modes,
3074 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
3075 .input_mux = &alc882_capture_source,
3076 .unsol_event = alc_sku_unsol_event,
3077 .setup = alc885_mba21_setup,
3078 .init_hook = alc_hp_automute,
3079 },
3080 [ALC885_MBP3] = {
3081 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
3082 .init_verbs = { alc885_mbp3_init_verbs,
3083 alc880_gpio1_init_verbs },
3084 .num_dacs = 2,
3085 .dac_nids = alc882_dac_nids,
3086 .hp_nid = 0x04,
3087 .channel_mode = alc885_mbp_4ch_modes,
3088 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
3089 .input_mux = &alc882_capture_source,
3090 .dig_out_nid = ALC882_DIGOUT_NID,
3091 .dig_in_nid = ALC882_DIGIN_NID,
3092 .unsol_event = alc_sku_unsol_event,
3093 .setup = alc885_mbp3_setup,
3094 .init_hook = alc_hp_automute,
3095 },
3096 [ALC885_MB5] = {
3097 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
3098 .init_verbs = { alc885_mb5_init_verbs,
3099 alc880_gpio1_init_verbs },
3100 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3101 .dac_nids = alc882_dac_nids,
3102 .channel_mode = alc885_mb5_6ch_modes,
3103 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
3104 .input_mux = &mb5_capture_source,
3105 .dig_out_nid = ALC882_DIGOUT_NID,
3106 .dig_in_nid = ALC882_DIGIN_NID,
3107 .unsol_event = alc_sku_unsol_event,
3108 .setup = alc885_mb5_setup,
3109 .init_hook = alc_hp_automute,
3110 },
3111 [ALC885_MACMINI3] = {
3112 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
3113 .init_verbs = { alc885_macmini3_init_verbs,
3114 alc880_gpio1_init_verbs },
3115 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3116 .dac_nids = alc882_dac_nids,
3117 .channel_mode = alc885_macmini3_6ch_modes,
3118 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
3119 .input_mux = &macmini3_capture_source,
3120 .dig_out_nid = ALC882_DIGOUT_NID,
3121 .dig_in_nid = ALC882_DIGIN_NID,
3122 .unsol_event = alc_sku_unsol_event,
3123 .setup = alc885_macmini3_setup,
3124 .init_hook = alc_hp_automute,
3125 },
3126 [ALC885_MACPRO] = {
3127 .mixers = { alc882_macpro_mixer },
3128 .init_verbs = { alc882_macpro_init_verbs },
3129 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3130 .dac_nids = alc882_dac_nids,
3131 .dig_out_nid = ALC882_DIGOUT_NID,
3132 .dig_in_nid = ALC882_DIGIN_NID,
3133 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3134 .channel_mode = alc882_ch_modes,
3135 .input_mux = &alc882_capture_source,
3136 .init_hook = alc885_macpro_init_hook,
3137 },
3138 [ALC885_IMAC24] = {
3139 .mixers = { alc885_imac24_mixer },
3140 .init_verbs = { alc885_imac24_init_verbs },
3141 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3142 .dac_nids = alc882_dac_nids,
3143 .dig_out_nid = ALC882_DIGOUT_NID,
3144 .dig_in_nid = ALC882_DIGIN_NID,
3145 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3146 .channel_mode = alc882_ch_modes,
3147 .input_mux = &alc882_capture_source,
3148 .unsol_event = alc_sku_unsol_event,
3149 .setup = alc885_imac24_setup,
3150 .init_hook = alc885_imac24_init_hook,
3151 },
3152 [ALC885_IMAC91] = {
3153 .mixers = {alc885_imac91_mixer},
3154 .init_verbs = { alc885_imac91_init_verbs,
3155 alc880_gpio1_init_verbs },
3156 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3157 .dac_nids = alc882_dac_nids,
3158 .channel_mode = alc885_mba21_ch_modes,
3159 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
3160 .input_mux = &alc889A_imac91_capture_source,
3161 .dig_out_nid = ALC882_DIGOUT_NID,
3162 .dig_in_nid = ALC882_DIGIN_NID,
3163 .unsol_event = alc_sku_unsol_event,
3164 .setup = alc885_imac91_setup,
3165 .init_hook = alc_hp_automute,
3166 },
3167 [ALC882_TARGA] = {
3168 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
3169 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3170 alc880_gpio3_init_verbs, alc882_targa_verbs},
3171 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3172 .dac_nids = alc882_dac_nids,
3173 .dig_out_nid = ALC882_DIGOUT_NID,
3174 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3175 .adc_nids = alc882_adc_nids,
3176 .capsrc_nids = alc882_capsrc_nids,
3177 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
3178 .channel_mode = alc882_3ST_6ch_modes,
3179 .need_dac_fix = 1,
3180 .input_mux = &alc882_capture_source,
3181 .unsol_event = alc_sku_unsol_event,
3182 .setup = alc882_targa_setup,
3183 .init_hook = alc882_targa_automute,
3184 },
3185 [ALC882_ASUS_A7J] = {
3186 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
3187 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3188 alc882_asus_a7j_verbs},
3189 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3190 .dac_nids = alc882_dac_nids,
3191 .dig_out_nid = ALC882_DIGOUT_NID,
3192 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3193 .adc_nids = alc882_adc_nids,
3194 .capsrc_nids = alc882_capsrc_nids,
3195 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
3196 .channel_mode = alc882_3ST_6ch_modes,
3197 .need_dac_fix = 1,
3198 .input_mux = &alc882_capture_source,
3199 },
3200 [ALC882_ASUS_A7M] = {
3201 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
3202 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3203 alc882_eapd_verbs, alc880_gpio1_init_verbs,
3204 alc882_asus_a7m_verbs },
3205 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3206 .dac_nids = alc882_dac_nids,
3207 .dig_out_nid = ALC882_DIGOUT_NID,
3208 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3209 .channel_mode = alc880_threestack_modes,
3210 .need_dac_fix = 1,
3211 .input_mux = &alc882_capture_source,
3212 },
3213 [ALC883_3ST_2ch_DIG] = {
3214 .mixers = { alc883_3ST_2ch_mixer },
3215 .init_verbs = { alc883_init_verbs },
3216 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3217 .dac_nids = alc883_dac_nids,
3218 .dig_out_nid = ALC883_DIGOUT_NID,
3219 .dig_in_nid = ALC883_DIGIN_NID,
3220 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3221 .channel_mode = alc883_3ST_2ch_modes,
3222 .input_mux = &alc883_capture_source,
3223 },
3224 [ALC883_3ST_6ch_DIG] = {
3225 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3226 .init_verbs = { alc883_init_verbs },
3227 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3228 .dac_nids = alc883_dac_nids,
3229 .dig_out_nid = ALC883_DIGOUT_NID,
3230 .dig_in_nid = ALC883_DIGIN_NID,
3231 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3232 .channel_mode = alc883_3ST_6ch_modes,
3233 .need_dac_fix = 1,
3234 .input_mux = &alc883_capture_source,
3235 },
3236 [ALC883_3ST_6ch] = {
3237 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3238 .init_verbs = { alc883_init_verbs },
3239 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3240 .dac_nids = alc883_dac_nids,
3241 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3242 .channel_mode = alc883_3ST_6ch_modes,
3243 .need_dac_fix = 1,
3244 .input_mux = &alc883_capture_source,
3245 },
3246 [ALC883_3ST_6ch_INTEL] = {
3247 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
3248 .init_verbs = { alc883_init_verbs },
3249 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3250 .dac_nids = alc883_dac_nids,
3251 .dig_out_nid = ALC883_DIGOUT_NID,
3252 .dig_in_nid = ALC883_DIGIN_NID,
3253 .slave_dig_outs = alc883_slave_dig_outs,
3254 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
3255 .channel_mode = alc883_3ST_6ch_intel_modes,
3256 .need_dac_fix = 1,
3257 .input_mux = &alc883_3stack_6ch_intel,
3258 },
3259 [ALC889A_INTEL] = {
3260 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
3261 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
3262 alc_hp15_unsol_verbs },
3263 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3264 .dac_nids = alc883_dac_nids,
3265 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3266 .adc_nids = alc889_adc_nids,
3267 .dig_out_nid = ALC883_DIGOUT_NID,
3268 .dig_in_nid = ALC883_DIGIN_NID,
3269 .slave_dig_outs = alc883_slave_dig_outs,
3270 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
3271 .channel_mode = alc889_8ch_intel_modes,
3272 .capsrc_nids = alc889_capsrc_nids,
3273 .input_mux = &alc889_capture_source,
3274 .setup = alc889_automute_setup,
3275 .init_hook = alc_hp_automute,
3276 .unsol_event = alc_sku_unsol_event,
3277 .need_dac_fix = 1,
3278 },
3279 [ALC889_INTEL] = {
3280 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
3281 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
3282 alc889_eapd_verbs, alc_hp15_unsol_verbs},
3283 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3284 .dac_nids = alc883_dac_nids,
3285 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3286 .adc_nids = alc889_adc_nids,
3287 .dig_out_nid = ALC883_DIGOUT_NID,
3288 .dig_in_nid = ALC883_DIGIN_NID,
3289 .slave_dig_outs = alc883_slave_dig_outs,
3290 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
3291 .channel_mode = alc889_8ch_intel_modes,
3292 .capsrc_nids = alc889_capsrc_nids,
3293 .input_mux = &alc889_capture_source,
3294 .setup = alc889_automute_setup,
3295 .init_hook = alc889_intel_init_hook,
3296 .unsol_event = alc_sku_unsol_event,
3297 .need_dac_fix = 1,
3298 },
3299 [ALC883_6ST_DIG] = {
3300 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3301 .init_verbs = { alc883_init_verbs },
3302 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3303 .dac_nids = alc883_dac_nids,
3304 .dig_out_nid = ALC883_DIGOUT_NID,
3305 .dig_in_nid = ALC883_DIGIN_NID,
3306 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3307 .channel_mode = alc883_sixstack_modes,
3308 .input_mux = &alc883_capture_source,
3309 },
3310 [ALC883_TARGA_DIG] = {
3311 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
3312 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3313 alc883_targa_verbs},
3314 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3315 .dac_nids = alc883_dac_nids,
3316 .dig_out_nid = ALC883_DIGOUT_NID,
3317 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3318 .channel_mode = alc883_3ST_6ch_modes,
3319 .need_dac_fix = 1,
3320 .input_mux = &alc883_capture_source,
3321 .unsol_event = alc883_targa_unsol_event,
3322 .setup = alc882_targa_setup,
3323 .init_hook = alc882_targa_automute,
3324 },
3325 [ALC883_TARGA_2ch_DIG] = {
3326 .mixers = { alc883_targa_2ch_mixer},
3327 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3328 alc883_targa_verbs},
3329 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3330 .dac_nids = alc883_dac_nids,
3331 .adc_nids = alc883_adc_nids_alt,
3332 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3333 .capsrc_nids = alc883_capsrc_nids,
3334 .dig_out_nid = ALC883_DIGOUT_NID,
3335 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3336 .channel_mode = alc883_3ST_2ch_modes,
3337 .input_mux = &alc883_capture_source,
3338 .unsol_event = alc883_targa_unsol_event,
3339 .setup = alc882_targa_setup,
3340 .init_hook = alc882_targa_automute,
3341 },
3342 [ALC883_TARGA_8ch_DIG] = {
3343 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
3344 alc883_chmode_mixer },
3345 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3346 alc883_targa_verbs },
3347 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3348 .dac_nids = alc883_dac_nids,
3349 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3350 .adc_nids = alc883_adc_nids_rev,
3351 .capsrc_nids = alc883_capsrc_nids_rev,
3352 .dig_out_nid = ALC883_DIGOUT_NID,
3353 .dig_in_nid = ALC883_DIGIN_NID,
3354 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
3355 .channel_mode = alc883_4ST_8ch_modes,
3356 .need_dac_fix = 1,
3357 .input_mux = &alc883_capture_source,
3358 .unsol_event = alc883_targa_unsol_event,
3359 .setup = alc882_targa_setup,
3360 .init_hook = alc882_targa_automute,
3361 },
3362 [ALC883_ACER] = {
3363 .mixers = { alc883_base_mixer },
3364 /* On TravelMate laptops, GPIO 0 enables the internal speaker
3365 * and the headphone jack. Turn this on and rely on the
3366 * standard mute methods whenever the user wants to turn
3367 * these outputs off.
3368 */
3369 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
3370 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3371 .dac_nids = alc883_dac_nids,
3372 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3373 .channel_mode = alc883_3ST_2ch_modes,
3374 .input_mux = &alc883_capture_source,
3375 },
3376 [ALC883_ACER_ASPIRE] = {
3377 .mixers = { alc883_acer_aspire_mixer },
3378 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
3379 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3380 .dac_nids = alc883_dac_nids,
3381 .dig_out_nid = ALC883_DIGOUT_NID,
3382 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3383 .channel_mode = alc883_3ST_2ch_modes,
3384 .input_mux = &alc883_capture_source,
3385 .unsol_event = alc_sku_unsol_event,
3386 .setup = alc883_acer_aspire_setup,
3387 .init_hook = alc_hp_automute,
3388 },
3389 [ALC888_ACER_ASPIRE_4930G] = {
3390 .mixers = { alc888_acer_aspire_4930g_mixer,
3391 alc883_chmode_mixer },
3392 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3393 alc888_acer_aspire_4930g_verbs },
3394 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3395 .dac_nids = alc883_dac_nids,
3396 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3397 .adc_nids = alc883_adc_nids_rev,
3398 .capsrc_nids = alc883_capsrc_nids_rev,
3399 .dig_out_nid = ALC883_DIGOUT_NID,
3400 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3401 .channel_mode = alc883_3ST_6ch_modes,
3402 .need_dac_fix = 1,
3403 .const_channel_count = 6,
3404 .num_mux_defs =
3405 ARRAY_SIZE(alc888_2_capture_sources),
3406 .input_mux = alc888_2_capture_sources,
3407 .unsol_event = alc_sku_unsol_event,
3408 .setup = alc888_acer_aspire_4930g_setup,
3409 .init_hook = alc_hp_automute,
3410 },
3411 [ALC888_ACER_ASPIRE_6530G] = {
3412 .mixers = { alc888_acer_aspire_6530_mixer },
3413 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3414 alc888_acer_aspire_6530g_verbs },
3415 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3416 .dac_nids = alc883_dac_nids,
3417 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3418 .adc_nids = alc883_adc_nids_rev,
3419 .capsrc_nids = alc883_capsrc_nids_rev,
3420 .dig_out_nid = ALC883_DIGOUT_NID,
3421 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3422 .channel_mode = alc883_3ST_2ch_modes,
3423 .num_mux_defs =
3424 ARRAY_SIZE(alc888_2_capture_sources),
3425 .input_mux = alc888_acer_aspire_6530_sources,
3426 .unsol_event = alc_sku_unsol_event,
3427 .setup = alc888_acer_aspire_6530g_setup,
3428 .init_hook = alc_hp_automute,
3429 },
3430 [ALC888_ACER_ASPIRE_8930G] = {
3431 .mixers = { alc889_acer_aspire_8930g_mixer,
3432 alc883_chmode_mixer },
3433 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3434 alc889_acer_aspire_8930g_verbs,
3435 alc889_eapd_verbs},
3436 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3437 .dac_nids = alc883_dac_nids,
3438 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3439 .adc_nids = alc889_adc_nids,
3440 .capsrc_nids = alc889_capsrc_nids,
3441 .dig_out_nid = ALC883_DIGOUT_NID,
3442 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3443 .channel_mode = alc883_3ST_6ch_modes,
3444 .need_dac_fix = 1,
3445 .const_channel_count = 6,
3446 .num_mux_defs =
3447 ARRAY_SIZE(alc889_capture_sources),
3448 .input_mux = alc889_capture_sources,
3449 .unsol_event = alc_sku_unsol_event,
3450 .setup = alc889_acer_aspire_8930g_setup,
3451 .init_hook = alc_hp_automute,
3452#ifdef CONFIG_SND_HDA_POWER_SAVE
3453 .power_hook = alc_power_eapd,
3454#endif
3455 },
3456 [ALC888_ACER_ASPIRE_7730G] = {
3457 .mixers = { alc883_3ST_6ch_mixer,
3458 alc883_chmode_mixer },
3459 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3460 alc888_acer_aspire_7730G_verbs },
3461 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3462 .dac_nids = alc883_dac_nids,
3463 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3464 .adc_nids = alc883_adc_nids_rev,
3465 .capsrc_nids = alc883_capsrc_nids_rev,
3466 .dig_out_nid = ALC883_DIGOUT_NID,
3467 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3468 .channel_mode = alc883_3ST_6ch_modes,
3469 .need_dac_fix = 1,
3470 .const_channel_count = 6,
3471 .input_mux = &alc883_capture_source,
3472 .unsol_event = alc_sku_unsol_event,
3473 .setup = alc888_acer_aspire_7730g_setup,
3474 .init_hook = alc_hp_automute,
3475 },
3476 [ALC883_MEDION] = {
3477 .mixers = { alc883_fivestack_mixer,
3478 alc883_chmode_mixer },
3479 .init_verbs = { alc883_init_verbs,
3480 alc883_medion_eapd_verbs },
3481 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3482 .dac_nids = alc883_dac_nids,
3483 .adc_nids = alc883_adc_nids_alt,
3484 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3485 .capsrc_nids = alc883_capsrc_nids,
3486 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3487 .channel_mode = alc883_sixstack_modes,
3488 .input_mux = &alc883_capture_source,
3489 },
3490 [ALC883_MEDION_WIM2160] = {
3491 .mixers = { alc883_medion_wim2160_mixer },
3492 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
3493 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3494 .dac_nids = alc883_dac_nids,
3495 .dig_out_nid = ALC883_DIGOUT_NID,
3496 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
3497 .adc_nids = alc883_adc_nids,
3498 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3499 .channel_mode = alc883_3ST_2ch_modes,
3500 .input_mux = &alc883_capture_source,
3501 .unsol_event = alc_sku_unsol_event,
3502 .setup = alc883_medion_wim2160_setup,
3503 .init_hook = alc_hp_automute,
3504 },
3505 [ALC883_LAPTOP_EAPD] = {
3506 .mixers = { alc883_base_mixer },
3507 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
3508 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3509 .dac_nids = alc883_dac_nids,
3510 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3511 .channel_mode = alc883_3ST_2ch_modes,
3512 .input_mux = &alc883_capture_source,
3513 },
3514 [ALC883_CLEVO_M540R] = {
3515 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3516 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
3517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3518 .dac_nids = alc883_dac_nids,
3519 .dig_out_nid = ALC883_DIGOUT_NID,
3520 .dig_in_nid = ALC883_DIGIN_NID,
3521 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
3522 .channel_mode = alc883_3ST_6ch_clevo_modes,
3523 .need_dac_fix = 1,
3524 .input_mux = &alc883_capture_source,
3525 /* This machine has the hardware HP auto-muting, thus
3526 * we need no software mute via unsol event
3527 */
3528 },
3529 [ALC883_CLEVO_M720] = {
3530 .mixers = { alc883_clevo_m720_mixer },
3531 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
3532 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3533 .dac_nids = alc883_dac_nids,
3534 .dig_out_nid = ALC883_DIGOUT_NID,
3535 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3536 .channel_mode = alc883_3ST_2ch_modes,
3537 .input_mux = &alc883_capture_source,
3538 .unsol_event = alc883_clevo_m720_unsol_event,
3539 .setup = alc883_clevo_m720_setup,
3540 .init_hook = alc883_clevo_m720_init_hook,
3541 },
3542 [ALC883_LENOVO_101E_2ch] = {
3543 .mixers = { alc883_lenovo_101e_2ch_mixer},
3544 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
3545 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3546 .dac_nids = alc883_dac_nids,
3547 .adc_nids = alc883_adc_nids_alt,
3548 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3549 .capsrc_nids = alc883_capsrc_nids,
3550 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3551 .channel_mode = alc883_3ST_2ch_modes,
3552 .input_mux = &alc883_lenovo_101e_capture_source,
3553 .setup = alc883_lenovo_101e_setup,
3554 .unsol_event = alc_sku_unsol_event,
3555 .init_hook = alc_inithook,
3556 },
3557 [ALC883_LENOVO_NB0763] = {
3558 .mixers = { alc883_lenovo_nb0763_mixer },
3559 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
3560 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3561 .dac_nids = alc883_dac_nids,
3562 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3563 .channel_mode = alc883_3ST_2ch_modes,
3564 .need_dac_fix = 1,
3565 .input_mux = &alc883_lenovo_nb0763_capture_source,
3566 .unsol_event = alc_sku_unsol_event,
3567 .setup = alc883_lenovo_nb0763_setup,
3568 .init_hook = alc_hp_automute,
3569 },
3570 [ALC888_LENOVO_MS7195_DIG] = {
3571 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3572 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
3573 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3574 .dac_nids = alc883_dac_nids,
3575 .dig_out_nid = ALC883_DIGOUT_NID,
3576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3577 .channel_mode = alc883_3ST_6ch_modes,
3578 .need_dac_fix = 1,
3579 .input_mux = &alc883_capture_source,
3580 .unsol_event = alc_sku_unsol_event,
3581 .setup = alc888_lenovo_ms7195_setup,
3582 .init_hook = alc_inithook,
3583 },
3584 [ALC883_HAIER_W66] = {
3585 .mixers = { alc883_targa_2ch_mixer},
3586 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
3587 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3588 .dac_nids = alc883_dac_nids,
3589 .dig_out_nid = ALC883_DIGOUT_NID,
3590 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3591 .channel_mode = alc883_3ST_2ch_modes,
3592 .input_mux = &alc883_capture_source,
3593 .unsol_event = alc_sku_unsol_event,
3594 .setup = alc883_haier_w66_setup,
3595 .init_hook = alc_hp_automute,
3596 },
3597 [ALC888_3ST_HP] = {
3598 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3599 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
3600 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3601 .dac_nids = alc883_dac_nids,
3602 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
3603 .channel_mode = alc888_3st_hp_modes,
3604 .need_dac_fix = 1,
3605 .input_mux = &alc883_capture_source,
3606 .unsol_event = alc_sku_unsol_event,
3607 .setup = alc888_3st_hp_setup,
3608 .init_hook = alc_hp_automute,
3609 },
3610 [ALC888_6ST_DELL] = {
3611 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3612 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
3613 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3614 .dac_nids = alc883_dac_nids,
3615 .dig_out_nid = ALC883_DIGOUT_NID,
3616 .dig_in_nid = ALC883_DIGIN_NID,
3617 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3618 .channel_mode = alc883_sixstack_modes,
3619 .input_mux = &alc883_capture_source,
3620 .unsol_event = alc_sku_unsol_event,
3621 .setup = alc888_6st_dell_setup,
3622 .init_hook = alc_hp_automute,
3623 },
3624 [ALC883_MITAC] = {
3625 .mixers = { alc883_mitac_mixer },
3626 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
3627 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3628 .dac_nids = alc883_dac_nids,
3629 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3630 .channel_mode = alc883_3ST_2ch_modes,
3631 .input_mux = &alc883_capture_source,
3632 .unsol_event = alc_sku_unsol_event,
3633 .setup = alc883_mitac_setup,
3634 .init_hook = alc_hp_automute,
3635 },
3636 [ALC883_FUJITSU_PI2515] = {
3637 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
3638 .init_verbs = { alc883_init_verbs,
3639 alc883_2ch_fujitsu_pi2515_verbs},
3640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3641 .dac_nids = alc883_dac_nids,
3642 .dig_out_nid = ALC883_DIGOUT_NID,
3643 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3644 .channel_mode = alc883_3ST_2ch_modes,
3645 .input_mux = &alc883_fujitsu_pi2515_capture_source,
3646 .unsol_event = alc_sku_unsol_event,
3647 .setup = alc883_2ch_fujitsu_pi2515_setup,
3648 .init_hook = alc_hp_automute,
3649 },
3650 [ALC888_FUJITSU_XA3530] = {
3651 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
3652 .init_verbs = { alc883_init_verbs,
3653 alc888_fujitsu_xa3530_verbs },
3654 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3655 .dac_nids = alc883_dac_nids,
3656 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3657 .adc_nids = alc883_adc_nids_rev,
3658 .capsrc_nids = alc883_capsrc_nids_rev,
3659 .dig_out_nid = ALC883_DIGOUT_NID,
3660 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
3661 .channel_mode = alc888_4ST_8ch_intel_modes,
3662 .num_mux_defs =
3663 ARRAY_SIZE(alc888_2_capture_sources),
3664 .input_mux = alc888_2_capture_sources,
3665 .unsol_event = alc_sku_unsol_event,
3666 .setup = alc888_fujitsu_xa3530_setup,
3667 .init_hook = alc_hp_automute,
3668 },
3669 [ALC888_LENOVO_SKY] = {
3670 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
3671 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
3672 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3673 .dac_nids = alc883_dac_nids,
3674 .dig_out_nid = ALC883_DIGOUT_NID,
3675 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3676 .channel_mode = alc883_sixstack_modes,
3677 .need_dac_fix = 1,
3678 .input_mux = &alc883_lenovo_sky_capture_source,
3679 .unsol_event = alc_sku_unsol_event,
3680 .setup = alc888_lenovo_sky_setup,
3681 .init_hook = alc_hp_automute,
3682 },
3683 [ALC888_ASUS_M90V] = {
3684 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3685 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
3686 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3687 .dac_nids = alc883_dac_nids,
3688 .dig_out_nid = ALC883_DIGOUT_NID,
3689 .dig_in_nid = ALC883_DIGIN_NID,
3690 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3691 .channel_mode = alc883_3ST_6ch_modes,
3692 .need_dac_fix = 1,
3693 .input_mux = &alc883_fujitsu_pi2515_capture_source,
3694 .unsol_event = alc_sku_unsol_event,
3695 .setup = alc883_mode2_setup,
3696 .init_hook = alc_inithook,
3697 },
3698 [ALC888_ASUS_EEE1601] = {
3699 .mixers = { alc883_asus_eee1601_mixer },
3700 .cap_mixer = alc883_asus_eee1601_cap_mixer,
3701 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
3702 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3703 .dac_nids = alc883_dac_nids,
3704 .dig_out_nid = ALC883_DIGOUT_NID,
3705 .dig_in_nid = ALC883_DIGIN_NID,
3706 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3707 .channel_mode = alc883_3ST_2ch_modes,
3708 .need_dac_fix = 1,
3709 .input_mux = &alc883_asus_eee1601_capture_source,
3710 .unsol_event = alc_sku_unsol_event,
3711 .init_hook = alc883_eee1601_inithook,
3712 },
3713 [ALC1200_ASUS_P5Q] = {
3714 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3715 .init_verbs = { alc883_init_verbs },
3716 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3717 .dac_nids = alc883_dac_nids,
3718 .dig_out_nid = ALC1200_DIGOUT_NID,
3719 .dig_in_nid = ALC883_DIGIN_NID,
3720 .slave_dig_outs = alc1200_slave_dig_outs,
3721 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3722 .channel_mode = alc883_sixstack_modes,
3723 .input_mux = &alc883_capture_source,
3724 },
3725 [ALC889A_MB31] = {
3726 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
3727 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
3728 alc880_gpio1_init_verbs },
3729 .adc_nids = alc883_adc_nids,
3730 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
3731 .capsrc_nids = alc883_capsrc_nids,
3732 .dac_nids = alc883_dac_nids,
3733 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3734 .channel_mode = alc889A_mb31_6ch_modes,
3735 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
3736 .input_mux = &alc889A_mb31_capture_source,
3737 .dig_out_nid = ALC883_DIGOUT_NID,
3738 .unsol_event = alc889A_mb31_unsol_event,
3739 .init_hook = alc889A_mb31_automute,
3740 },
3741 [ALC883_SONY_VAIO_TT] = {
3742 .mixers = { alc883_vaiott_mixer },
3743 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
3744 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3745 .dac_nids = alc883_dac_nids,
3746 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3747 .channel_mode = alc883_3ST_2ch_modes,
3748 .input_mux = &alc883_capture_source,
3749 .unsol_event = alc_sku_unsol_event,
3750 .setup = alc883_vaiott_setup,
3751 .init_hook = alc_hp_automute,
3752 },
3753};
3754
3755
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
new file mode 100644
index 00000000000..2be1129cf45
--- /dev/null
+++ b/sound/pci/hda/alc_quirks.c
@@ -0,0 +1,467 @@
1/*
2 * Common codes for Realtek codec quirks
3 * included by patch_realtek.c
4 */
5
6/*
7 * configuration template - to be copied to the spec instance
8 */
9struct alc_config_preset {
10 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
11 * with spec
12 */
13 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
14 const struct hda_verb *init_verbs[5];
15 unsigned int num_dacs;
16 const hda_nid_t *dac_nids;
17 hda_nid_t dig_out_nid; /* optional */
18 hda_nid_t hp_nid; /* optional */
19 const hda_nid_t *slave_dig_outs;
20 unsigned int num_adc_nids;
21 const hda_nid_t *adc_nids;
22 const hda_nid_t *capsrc_nids;
23 hda_nid_t dig_in_nid;
24 unsigned int num_channel_mode;
25 const struct hda_channel_mode *channel_mode;
26 int need_dac_fix;
27 int const_channel_count;
28 unsigned int num_mux_defs;
29 const struct hda_input_mux *input_mux;
30 void (*unsol_event)(struct hda_codec *, unsigned int);
31 void (*setup)(struct hda_codec *);
32 void (*init_hook)(struct hda_codec *);
33#ifdef CONFIG_SND_HDA_POWER_SAVE
34 const struct hda_amp_list *loopbacks;
35 void (*power_hook)(struct hda_codec *codec);
36#endif
37};
38
39/*
40 * channel mode setting
41 */
42static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
43 struct snd_ctl_elem_info *uinfo)
44{
45 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
46 struct alc_spec *spec = codec->spec;
47 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
48 spec->num_channel_mode);
49}
50
51static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
52 struct snd_ctl_elem_value *ucontrol)
53{
54 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
55 struct alc_spec *spec = codec->spec;
56 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
57 spec->num_channel_mode,
58 spec->ext_channel_count);
59}
60
61static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
62 struct snd_ctl_elem_value *ucontrol)
63{
64 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
65 struct alc_spec *spec = codec->spec;
66 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
67 spec->num_channel_mode,
68 &spec->ext_channel_count);
69 if (err >= 0 && !spec->const_channel_count) {
70 spec->multiout.max_channels = spec->ext_channel_count;
71 if (spec->need_dac_fix)
72 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
73 }
74 return err;
75}
76
77/*
78 * Control the mode of pin widget settings via the mixer. "pc" is used
79 * instead of "%" to avoid consequences of accidentally treating the % as
80 * being part of a format specifier. Maximum allowed length of a value is
81 * 63 characters plus NULL terminator.
82 *
83 * Note: some retasking pin complexes seem to ignore requests for input
84 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
85 * are requested. Therefore order this list so that this behaviour will not
86 * cause problems when mixer clients move through the enum sequentially.
87 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
88 * March 2006.
89 */
90static const char * const alc_pin_mode_names[] = {
91 "Mic 50pc bias", "Mic 80pc bias",
92 "Line in", "Line out", "Headphone out",
93};
94static const unsigned char alc_pin_mode_values[] = {
95 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
96};
97/* The control can present all 5 options, or it can limit the options based
98 * in the pin being assumed to be exclusively an input or an output pin. In
99 * addition, "input" pins may or may not process the mic bias option
100 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
101 * accept requests for bias as of chip versions up to March 2006) and/or
102 * wiring in the computer.
103 */
104#define ALC_PIN_DIR_IN 0x00
105#define ALC_PIN_DIR_OUT 0x01
106#define ALC_PIN_DIR_INOUT 0x02
107#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
108#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
109
110/* Info about the pin modes supported by the different pin direction modes.
111 * For each direction the minimum and maximum values are given.
112 */
113static const signed char alc_pin_mode_dir_info[5][2] = {
114 { 0, 2 }, /* ALC_PIN_DIR_IN */
115 { 3, 4 }, /* ALC_PIN_DIR_OUT */
116 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
117 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
118 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
119};
120#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
121#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
122#define alc_pin_mode_n_items(_dir) \
123 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
124
125static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_info *uinfo)
127{
128 unsigned int item_num = uinfo->value.enumerated.item;
129 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
130
131 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
132 uinfo->count = 1;
133 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
134
135 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
136 item_num = alc_pin_mode_min(dir);
137 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
138 return 0;
139}
140
141static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
142 struct snd_ctl_elem_value *ucontrol)
143{
144 unsigned int i;
145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
146 hda_nid_t nid = kcontrol->private_value & 0xffff;
147 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
148 long *valp = ucontrol->value.integer.value;
149 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
150 AC_VERB_GET_PIN_WIDGET_CONTROL,
151 0x00);
152
153 /* Find enumerated value for current pinctl setting */
154 i = alc_pin_mode_min(dir);
155 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
156 i++;
157 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
158 return 0;
159}
160
161static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
163{
164 signed int change;
165 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
166 hda_nid_t nid = kcontrol->private_value & 0xffff;
167 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
168 long val = *ucontrol->value.integer.value;
169 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
170 AC_VERB_GET_PIN_WIDGET_CONTROL,
171 0x00);
172
173 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
174 val = alc_pin_mode_min(dir);
175
176 change = pinctl != alc_pin_mode_values[val];
177 if (change) {
178 /* Set pin mode to that requested */
179 snd_hda_codec_write_cache(codec, nid, 0,
180 AC_VERB_SET_PIN_WIDGET_CONTROL,
181 alc_pin_mode_values[val]);
182
183 /* Also enable the retasking pin's input/output as required
184 * for the requested pin mode. Enum values of 2 or less are
185 * input modes.
186 *
187 * Dynamically switching the input/output buffers probably
188 * reduces noise slightly (particularly on input) so we'll
189 * do it. However, having both input and output buffers
190 * enabled simultaneously doesn't seem to be problematic if
191 * this turns out to be necessary in the future.
192 */
193 if (val <= 2) {
194 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
195 HDA_AMP_MUTE, HDA_AMP_MUTE);
196 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
197 HDA_AMP_MUTE, 0);
198 } else {
199 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
200 HDA_AMP_MUTE, HDA_AMP_MUTE);
201 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
202 HDA_AMP_MUTE, 0);
203 }
204 }
205 return change;
206}
207
208#define ALC_PIN_MODE(xname, nid, dir) \
209 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
210 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
211 .info = alc_pin_mode_info, \
212 .get = alc_pin_mode_get, \
213 .put = alc_pin_mode_put, \
214 .private_value = nid | (dir<<16) }
215
216/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
217 * together using a mask with more than one bit set. This control is
218 * currently used only by the ALC260 test model. At this stage they are not
219 * needed for any "production" models.
220 */
221#ifdef CONFIG_SND_DEBUG
222#define alc_gpio_data_info snd_ctl_boolean_mono_info
223
224static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
225 struct snd_ctl_elem_value *ucontrol)
226{
227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
228 hda_nid_t nid = kcontrol->private_value & 0xffff;
229 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
230 long *valp = ucontrol->value.integer.value;
231 unsigned int val = snd_hda_codec_read(codec, nid, 0,
232 AC_VERB_GET_GPIO_DATA, 0x00);
233
234 *valp = (val & mask) != 0;
235 return 0;
236}
237static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
238 struct snd_ctl_elem_value *ucontrol)
239{
240 signed int change;
241 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
242 hda_nid_t nid = kcontrol->private_value & 0xffff;
243 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
244 long val = *ucontrol->value.integer.value;
245 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
246 AC_VERB_GET_GPIO_DATA,
247 0x00);
248
249 /* Set/unset the masked GPIO bit(s) as needed */
250 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
251 if (val == 0)
252 gpio_data &= ~mask;
253 else
254 gpio_data |= mask;
255 snd_hda_codec_write_cache(codec, nid, 0,
256 AC_VERB_SET_GPIO_DATA, gpio_data);
257
258 return change;
259}
260#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
261 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
262 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
263 .info = alc_gpio_data_info, \
264 .get = alc_gpio_data_get, \
265 .put = alc_gpio_data_put, \
266 .private_value = nid | (mask<<16) }
267#endif /* CONFIG_SND_DEBUG */
268
269/* A switch control to allow the enabling of the digital IO pins on the
270 * ALC260. This is incredibly simplistic; the intention of this control is
271 * to provide something in the test model allowing digital outputs to be
272 * identified if present. If models are found which can utilise these
273 * outputs a more complete mixer control can be devised for those models if
274 * necessary.
275 */
276#ifdef CONFIG_SND_DEBUG
277#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
278
279static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_value *ucontrol)
281{
282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
283 hda_nid_t nid = kcontrol->private_value & 0xffff;
284 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
285 long *valp = ucontrol->value.integer.value;
286 unsigned int val = snd_hda_codec_read(codec, nid, 0,
287 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
288
289 *valp = (val & mask) != 0;
290 return 0;
291}
292static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
293 struct snd_ctl_elem_value *ucontrol)
294{
295 signed int change;
296 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297 hda_nid_t nid = kcontrol->private_value & 0xffff;
298 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
299 long val = *ucontrol->value.integer.value;
300 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
301 AC_VERB_GET_DIGI_CONVERT_1,
302 0x00);
303
304 /* Set/unset the masked control bit(s) as needed */
305 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
306 if (val==0)
307 ctrl_data &= ~mask;
308 else
309 ctrl_data |= mask;
310 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
311 ctrl_data);
312
313 return change;
314}
315#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
316 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
317 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
318 .info = alc_spdif_ctrl_info, \
319 .get = alc_spdif_ctrl_get, \
320 .put = alc_spdif_ctrl_put, \
321 .private_value = nid | (mask<<16) }
322#endif /* CONFIG_SND_DEBUG */
323
324/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
325 * Again, this is only used in the ALC26x test models to help identify when
326 * the EAPD line must be asserted for features to work.
327 */
328#ifdef CONFIG_SND_DEBUG
329#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
330
331static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
332 struct snd_ctl_elem_value *ucontrol)
333{
334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335 hda_nid_t nid = kcontrol->private_value & 0xffff;
336 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
337 long *valp = ucontrol->value.integer.value;
338 unsigned int val = snd_hda_codec_read(codec, nid, 0,
339 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
340
341 *valp = (val & mask) != 0;
342 return 0;
343}
344
345static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol)
347{
348 int change;
349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350 hda_nid_t nid = kcontrol->private_value & 0xffff;
351 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
352 long val = *ucontrol->value.integer.value;
353 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
354 AC_VERB_GET_EAPD_BTLENABLE,
355 0x00);
356
357 /* Set/unset the masked control bit(s) as needed */
358 change = (!val ? 0 : mask) != (ctrl_data & mask);
359 if (!val)
360 ctrl_data &= ~mask;
361 else
362 ctrl_data |= mask;
363 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
364 ctrl_data);
365
366 return change;
367}
368
369#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
370 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
371 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
372 .info = alc_eapd_ctrl_info, \
373 .get = alc_eapd_ctrl_get, \
374 .put = alc_eapd_ctrl_put, \
375 .private_value = nid | (mask<<16) }
376#endif /* CONFIG_SND_DEBUG */
377
378static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
379{
380 struct alc_spec *spec = codec->spec;
381 struct auto_pin_cfg *cfg = &spec->autocfg;
382
383 if (!cfg->line_outs) {
384 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
385 cfg->line_out_pins[cfg->line_outs])
386 cfg->line_outs++;
387 }
388 if (!cfg->speaker_outs) {
389 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
390 cfg->speaker_pins[cfg->speaker_outs])
391 cfg->speaker_outs++;
392 }
393 if (!cfg->hp_outs) {
394 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
395 cfg->hp_pins[cfg->hp_outs])
396 cfg->hp_outs++;
397 }
398}
399
400/*
401 * set up from the preset table
402 */
403static void setup_preset(struct hda_codec *codec,
404 const struct alc_config_preset *preset)
405{
406 struct alc_spec *spec = codec->spec;
407 int i;
408
409 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
410 add_mixer(spec, preset->mixers[i]);
411 spec->cap_mixer = preset->cap_mixer;
412 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
413 i++)
414 add_verb(spec, preset->init_verbs[i]);
415
416 spec->channel_mode = preset->channel_mode;
417 spec->num_channel_mode = preset->num_channel_mode;
418 spec->need_dac_fix = preset->need_dac_fix;
419 spec->const_channel_count = preset->const_channel_count;
420
421 if (preset->const_channel_count)
422 spec->multiout.max_channels = preset->const_channel_count;
423 else
424 spec->multiout.max_channels = spec->channel_mode[0].channels;
425 spec->ext_channel_count = spec->channel_mode[0].channels;
426
427 spec->multiout.num_dacs = preset->num_dacs;
428 spec->multiout.dac_nids = preset->dac_nids;
429 spec->multiout.dig_out_nid = preset->dig_out_nid;
430 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
431 spec->multiout.hp_nid = preset->hp_nid;
432
433 spec->num_mux_defs = preset->num_mux_defs;
434 if (!spec->num_mux_defs)
435 spec->num_mux_defs = 1;
436 spec->input_mux = preset->input_mux;
437
438 spec->num_adc_nids = preset->num_adc_nids;
439 spec->adc_nids = preset->adc_nids;
440 spec->capsrc_nids = preset->capsrc_nids;
441 spec->dig_in_nid = preset->dig_in_nid;
442
443 spec->unsol_event = preset->unsol_event;
444 spec->init_hook = preset->init_hook;
445#ifdef CONFIG_SND_HDA_POWER_SAVE
446 spec->power_hook = preset->power_hook;
447 spec->loopback.amplist = preset->loopbacks;
448#endif
449
450 if (preset->setup)
451 preset->setup(codec);
452
453 alc_fixup_autocfg_pin_nums(codec);
454}
455
456
457/* auto-toggle front mic */
458static void alc88x_simple_mic_automute(struct hda_codec *codec)
459{
460 unsigned int present;
461 unsigned char bits;
462
463 present = snd_hda_jack_detect(codec, 0x18);
464 bits = present ? HDA_AMP_MUTE : 0;
465 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
466}
467