aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-07 12:23:21 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-07 12:27:29 -0400
commit1d045db96ad9b8f4d876d5945ab097425252e4ab (patch)
treeb7479a54398cec0a3fc72b357790a986e38990cb
parent0e4a73ae5893d61ae10a9f219e2f3371e44589a8 (diff)
ALSA: hda - Split quirk codes from patch_realtek.c
Put the all static quirk codes out of patch_realtek.c, split into the file for each codec model. For controlling the build of quirk codes, a new Kconfig, CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS is introduced. By setting this off, all quirk codes won't be built, thus you can save lots of memory. The codes in patch_realtek.c are also shuffled and more comments are given, but the contents aren't changed. This is just a refactoring. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/Kconfig13
-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.c681
-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
-rw-r--r--sound/pci/hda/patch_realtek.c15010
13 files changed, 14124 insertions, 13921 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 85217bd96d8..70762fca57e 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -83,6 +83,19 @@ config SND_HDA_CODEC_REALTEK
83 snd-hda-codec-realtek. 83 snd-hda-codec-realtek.
84 This module is automatically loaded at probing. 84 This module is automatically loaded at probing.
85 85
86config SND_HDA_ENABLE_REALTEK_QUIRKS
87 bool "Build static quirks for Realtek codecs"
88 depends on SND_HDA_CODEC_REALTEK
89 default y
90 help
91 Say Y here to build the static quirks codes for Realtek codecs.
92 If you need the "model" preset that the default BIOS auto-parser
93 can't handle, turn this option on.
94
95 If your device works with model=auto option, basically you don't
96 need the quirk code. By turning this off, you can reduce the
97 module size quite a lot.
98
86config SND_HDA_CODEC_ANALOG 99config SND_HDA_CODEC_ANALOG
87 bool "Build Analog Device HD-audio codec support" 100 bool "Build Analog Device HD-audio codec support"
88 default y 101 default y
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..be58bf2f3ae
--- /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 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_capture_alt_mixer,
496 alc268_beep_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_capture_alt_mixer,
511 alc268_beep_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_capture_alt_mixer,
529 alc268_beep_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_capture_alt_mixer,
547 alc268_beep_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,
565 alc268_beep_mixer,
566 alc268_capture_nosrc_mixer },
567 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
568 alc268_acer_aspire_one_verbs },
569 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
570 .dac_nids = alc268_dac_nids,
571 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
572 .adc_nids = alc268_adc_nids_alt,
573 .capsrc_nids = alc268_capsrc_nids,
574 .hp_nid = 0x03,
575 .num_channel_mode = ARRAY_SIZE(alc268_modes),
576 .channel_mode = alc268_modes,
577 .unsol_event = alc_sku_unsol_event,
578 .setup = alc268_acer_lc_setup,
579 .init_hook = alc_inithook,
580 },
581 [ALC268_DELL] = {
582 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
583 alc268_capture_nosrc_mixer },
584 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
585 alc268_dell_verbs },
586 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
587 .dac_nids = alc268_dac_nids,
588 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
589 .adc_nids = alc268_adc_nids_alt,
590 .capsrc_nids = alc268_capsrc_nids,
591 .hp_nid = 0x02,
592 .num_channel_mode = ARRAY_SIZE(alc268_modes),
593 .channel_mode = alc268_modes,
594 .unsol_event = alc_sku_unsol_event,
595 .setup = alc268_dell_setup,
596 .init_hook = alc_inithook,
597 },
598 [ALC268_ZEPTO] = {
599 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
600 alc268_beep_mixer },
601 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
602 alc268_toshiba_verbs },
603 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
604 .dac_nids = alc268_dac_nids,
605 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
606 .adc_nids = alc268_adc_nids_alt,
607 .capsrc_nids = alc268_capsrc_nids,
608 .hp_nid = 0x03,
609 .dig_out_nid = ALC268_DIGOUT_NID,
610 .num_channel_mode = ARRAY_SIZE(alc268_modes),
611 .channel_mode = alc268_modes,
612 .input_mux = &alc268_capture_source,
613 .unsol_event = alc_sku_unsol_event,
614 .setup = alc268_toshiba_setup,
615 .init_hook = alc_inithook,
616 },
617#ifdef CONFIG_SND_DEBUG
618 [ALC268_TEST] = {
619 .mixers = { alc268_test_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..14fdcf29b15
--- /dev/null
+++ b/sound/pci/hda/alc269_quirks.c
@@ -0,0 +1,681 @@
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, 0x16e3, "ASUS UX50", ALC269_DMIC),
535 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
536 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
537 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
538 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
539 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
540 ALC269_DMIC),
541 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
542 ALC269_DMIC),
543 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
544 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
545 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
546 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
547 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
548 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
549 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
550 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
551 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
552 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
553 {}
554};
555
556static const struct alc_config_preset alc269_presets[] = {
557 [ALC269_BASIC] = {
558 .mixers = { alc269_base_mixer },
559 .init_verbs = { alc269_init_verbs },
560 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
561 .dac_nids = alc269_dac_nids,
562 .hp_nid = 0x03,
563 .num_channel_mode = ARRAY_SIZE(alc269_modes),
564 .channel_mode = alc269_modes,
565 .input_mux = &alc269_capture_source,
566 },
567 [ALC269_QUANTA_FL1] = {
568 .mixers = { alc269_quanta_fl1_mixer },
569 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
570 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
571 .dac_nids = alc269_dac_nids,
572 .hp_nid = 0x03,
573 .num_channel_mode = ARRAY_SIZE(alc269_modes),
574 .channel_mode = alc269_modes,
575 .input_mux = &alc269_capture_source,
576 .unsol_event = alc269_quanta_fl1_unsol_event,
577 .setup = alc269_quanta_fl1_setup,
578 .init_hook = alc269_quanta_fl1_init_hook,
579 },
580 [ALC269_AMIC] = {
581 .mixers = { alc269_laptop_mixer },
582 .cap_mixer = alc269_laptop_analog_capture_mixer,
583 .init_verbs = { alc269_init_verbs,
584 alc269_laptop_amic_init_verbs },
585 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
586 .dac_nids = alc269_dac_nids,
587 .hp_nid = 0x03,
588 .num_channel_mode = ARRAY_SIZE(alc269_modes),
589 .channel_mode = alc269_modes,
590 .unsol_event = alc_sku_unsol_event,
591 .setup = alc269_laptop_amic_setup,
592 .init_hook = alc_inithook,
593 },
594 [ALC269_DMIC] = {
595 .mixers = { alc269_laptop_mixer },
596 .cap_mixer = alc269_laptop_digital_capture_mixer,
597 .init_verbs = { alc269_init_verbs,
598 alc269_laptop_dmic_init_verbs },
599 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
600 .dac_nids = alc269_dac_nids,
601 .hp_nid = 0x03,
602 .num_channel_mode = ARRAY_SIZE(alc269_modes),
603 .channel_mode = alc269_modes,
604 .unsol_event = alc_sku_unsol_event,
605 .setup = alc269_laptop_dmic_setup,
606 .init_hook = alc_inithook,
607 },
608 [ALC269VB_AMIC] = {
609 .mixers = { alc269vb_laptop_mixer },
610 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
611 .init_verbs = { alc269vb_init_verbs,
612 alc269vb_laptop_amic_init_verbs },
613 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
614 .dac_nids = alc269_dac_nids,
615 .hp_nid = 0x03,
616 .num_channel_mode = ARRAY_SIZE(alc269_modes),
617 .channel_mode = alc269_modes,
618 .unsol_event = alc_sku_unsol_event,
619 .setup = alc269vb_laptop_amic_setup,
620 .init_hook = alc_inithook,
621 },
622 [ALC269VB_DMIC] = {
623 .mixers = { alc269vb_laptop_mixer },
624 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
625 .init_verbs = { alc269vb_init_verbs,
626 alc269vb_laptop_dmic_init_verbs },
627 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
628 .dac_nids = alc269_dac_nids,
629 .hp_nid = 0x03,
630 .num_channel_mode = ARRAY_SIZE(alc269_modes),
631 .channel_mode = alc269_modes,
632 .unsol_event = alc_sku_unsol_event,
633 .setup = alc269vb_laptop_dmic_setup,
634 .init_hook = alc_inithook,
635 },
636 [ALC269_FUJITSU] = {
637 .mixers = { alc269_fujitsu_mixer },
638 .cap_mixer = alc269_laptop_digital_capture_mixer,
639 .init_verbs = { alc269_init_verbs,
640 alc269_laptop_dmic_init_verbs },
641 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
642 .dac_nids = alc269_dac_nids,
643 .hp_nid = 0x03,
644 .num_channel_mode = ARRAY_SIZE(alc269_modes),
645 .channel_mode = alc269_modes,
646 .unsol_event = alc_sku_unsol_event,
647 .setup = alc269_laptop_dmic_setup,
648 .init_hook = alc_inithook,
649 },
650 [ALC269_LIFEBOOK] = {
651 .mixers = { alc269_lifebook_mixer },
652 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
653 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
654 .dac_nids = alc269_dac_nids,
655 .hp_nid = 0x03,
656 .num_channel_mode = ARRAY_SIZE(alc269_modes),
657 .channel_mode = alc269_modes,
658 .input_mux = &alc269_capture_source,
659 .unsol_event = alc269_lifebook_unsol_event,
660 .setup = alc269_lifebook_setup,
661 .init_hook = alc269_lifebook_init_hook,
662 },
663 [ALC271_ACER] = {
664 .mixers = { alc269_asus_mixer },
665 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
666 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
667 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
668 .dac_nids = alc269_dac_nids,
669 .adc_nids = alc262_dmic_adc_nids,
670 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
671 .capsrc_nids = alc262_dmic_capsrc_nids,
672 .num_channel_mode = ARRAY_SIZE(alc269_modes),
673 .channel_mode = alc269_modes,
674 .input_mux = &alc269_capture_source,
675 .dig_out_nid = ALC880_DIGOUT_NID,
676 .unsol_event = alc_sku_unsol_event,
677 .setup = alc269vb_laptop_dmic_setup,
678 .init_hook = alc_inithook,
679 },
680};
681
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
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 8366e02df3c..c1adb3bce7e 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Universal Interface for Intel High Definition Audio Codec 2 * Universal Interface for Intel High Definition Audio Codec
3 * 3 *
4 * HD audio interface patch for ALC 260/880/882 codecs 4 * HD audio interface patch for Realtek ALC codecs
5 * 5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> 6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw> 7 * PeiSen Hou <pshou@realtek.com.tw>
@@ -33,236 +33,11 @@
33#include "hda_local.h" 33#include "hda_local.h"
34#include "hda_beep.h" 34#include "hda_beep.h"
35 35
36#define ALC880_FRONT_EVENT 0x01 36/* unsol event tags */
37#define ALC880_DCVOL_EVENT 0x02 37#define ALC_FRONT_EVENT 0x01
38#define ALC880_HP_EVENT 0x04 38#define ALC_DCVOL_EVENT 0x02
39#define ALC880_MIC_EVENT 0x08 39#define ALC_HP_EVENT 0x04
40 40#define ALC_MIC_EVENT 0x08
41/* ALC880 board config type */
42enum {
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
48 ALC880_Z71V,
49 ALC880_6ST,
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
55 ALC880_ASUS_DIG2,
56 ALC880_FUJITSU,
57 ALC880_UNIWILL_DIG,
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
62 ALC880_LG,
63 ALC880_LG_LW,
64 ALC880_MEDION_RIM,
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
68 ALC880_AUTO,
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
76 ALC260_HP_DC7600,
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
79 ALC260_ACER,
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
82 ALC260_FAVORIT100,
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
86 ALC260_AUTO,
87 ALC260_MODEL_LAST /* last tag */
88};
89
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
95 ALC262_FUJITSU,
96 ALC262_HP_BPC,
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
99 ALC262_HP_TC_T5735,
100 ALC262_HP_RP5700,
101 ALC262_BENQ_ED8,
102 ALC262_SONY_ASSAMD,
103 ALC262_BENQ_T31,
104 ALC262_ULTRA,
105 ALC262_LENOVO_3000,
106 ALC262_NEC,
107 ALC262_TOSHIBA_S06,
108 ALC262_TOSHIBA_RX1,
109 ALC262_TYAN,
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
114/* ALC268 models */
115enum {
116 ALC267_QUANTA_IL1,
117 ALC268_3ST,
118 ALC268_TOSHIBA,
119 ALC268_ACER,
120 ALC268_ACER_DMIC,
121 ALC268_ACER_ASPIRE_ONE,
122 ALC268_DELL,
123 ALC268_ZEPTO,
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
134 ALC269_QUANTA_FL1,
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
139 ALC269_FUJITSU,
140 ALC269_LIFEBOOK,
141 ALC271_ACER,
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
146/* ALC861 models */
147enum {
148 ALC861_3ST,
149 ALC660_3ST,
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
152 ALC861_UNIWILL_M31,
153 ALC861_TOSHIBA,
154 ALC861_ASUS,
155 ALC861_ASUS_LAPTOP,
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
163 ALC660VD_3ST_DIG,
164 ALC660VD_ASUS_V1S,
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
168 ALC861VD_LENOVO,
169 ALC861VD_DALLAS,
170 ALC861VD_HP,
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
182 ALC662_ASUS_EEEPC_P701,
183 ALC662_ASUS_EEEPC_EP20,
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
199 ALC272_SAMSUNG_NC10,
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
208 ALC882_ARIMA,
209 ALC882_W2JC,
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
212 ALC882_ASUS_A7M,
213 ALC885_MACPRO,
214 ALC885_MBA21,
215 ALC885_MBP3,
216 ALC885_MB5,
217 ALC885_MACMINI3,
218 ALC885_IMAC24,
219 ALC885_IMAC91,
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
226 ALC883_TARGA_8ch_DIG,
227 ALC883_ACER,
228 ALC883_ACER_ASPIRE,
229 ALC888_ACER_ASPIRE_4930G,
230 ALC888_ACER_ASPIRE_6530G,
231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G,
233 ALC883_MEDION,
234 ALC883_MEDION_WIM2160,
235 ALC883_LAPTOP_EAPD,
236 ALC883_LENOVO_101E_2ch,
237 ALC883_LENOVO_NB0763,
238 ALC888_LENOVO_MS7195_DIG,
239 ALC888_LENOVO_SKY,
240 ALC883_HAIER_W66,
241 ALC888_3ST_HP,
242 ALC888_6ST_DELL,
243 ALC883_MITAC,
244 ALC883_CLEVO_M540R,
245 ALC883_CLEVO_M720,
246 ALC883_FUJITSU_PI2515,
247 ALC888_FUJITSU_XA3530,
248 ALC883_3ST_6ch_INTEL,
249 ALC889A_INTEL,
250 ALC889_INTEL,
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
253 ALC889A_MB31,
254 ALC1200_ASUS_P5Q,
255 ALC883_SONY_VAIO_TT,
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
258};
259
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266 41
267/* for GPIO Poll */ 42/* for GPIO Poll */
268#define GPIO_MASK 0x03 43#define GPIO_MASK 0x03
@@ -429,39 +204,7 @@ struct alc_spec {
429 struct alc_multi_io multi_io[4]; 204 struct alc_multi_io multi_io[4];
430}; 205};
431 206
432/* 207#define ALC_MODEL_AUTO 0 /* common for all chips */
433 * configuration template - to be copied to the spec instance
434 */
435struct alc_config_preset {
436 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
437 * with spec
438 */
439 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
440 const struct hda_verb *init_verbs[5];
441 unsigned int num_dacs;
442 const hda_nid_t *dac_nids;
443 hda_nid_t dig_out_nid; /* optional */
444 hda_nid_t hp_nid; /* optional */
445 const hda_nid_t *slave_dig_outs;
446 unsigned int num_adc_nids;
447 const hda_nid_t *adc_nids;
448 const hda_nid_t *capsrc_nids;
449 hda_nid_t dig_in_nid;
450 unsigned int num_channel_mode;
451 const struct hda_channel_mode *channel_mode;
452 int need_dac_fix;
453 int const_channel_count;
454 unsigned int num_mux_defs;
455 const struct hda_input_mux *input_mux;
456 void (*unsol_event)(struct hda_codec *, unsigned int);
457 void (*setup)(struct hda_codec *);
458 void (*init_hook)(struct hda_codec *);
459#ifdef CONFIG_SND_HDA_POWER_SAVE
460 const struct hda_amp_list *loopbacks;
461 void (*power_hook)(struct hda_codec *codec);
462#endif
463};
464
465 208
466/* 209/*
467 * input MUX handling 210 * input MUX handling
@@ -568,345 +311,6 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
568} 311}
569 312
570/* 313/*
571 * channel mode setting
572 */
573static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_info *uinfo)
575{
576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
577 struct alc_spec *spec = codec->spec;
578 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
579 spec->num_channel_mode);
580}
581
582static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol)
584{
585 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
586 struct alc_spec *spec = codec->spec;
587 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
588 spec->num_channel_mode,
589 spec->ext_channel_count);
590}
591
592static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
593 struct snd_ctl_elem_value *ucontrol)
594{
595 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
596 struct alc_spec *spec = codec->spec;
597 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
598 spec->num_channel_mode,
599 &spec->ext_channel_count);
600 if (err >= 0 && !spec->const_channel_count) {
601 spec->multiout.max_channels = spec->ext_channel_count;
602 if (spec->need_dac_fix)
603 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
604 }
605 return err;
606}
607
608/*
609 * Control the mode of pin widget settings via the mixer. "pc" is used
610 * instead of "%" to avoid consequences of accidentally treating the % as
611 * being part of a format specifier. Maximum allowed length of a value is
612 * 63 characters plus NULL terminator.
613 *
614 * Note: some retasking pin complexes seem to ignore requests for input
615 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
616 * are requested. Therefore order this list so that this behaviour will not
617 * cause problems when mixer clients move through the enum sequentially.
618 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
619 * March 2006.
620 */
621static const char * const alc_pin_mode_names[] = {
622 "Mic 50pc bias", "Mic 80pc bias",
623 "Line in", "Line out", "Headphone out",
624};
625static const unsigned char alc_pin_mode_values[] = {
626 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
627};
628/* The control can present all 5 options, or it can limit the options based
629 * in the pin being assumed to be exclusively an input or an output pin. In
630 * addition, "input" pins may or may not process the mic bias option
631 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
632 * accept requests for bias as of chip versions up to March 2006) and/or
633 * wiring in the computer.
634 */
635#define ALC_PIN_DIR_IN 0x00
636#define ALC_PIN_DIR_OUT 0x01
637#define ALC_PIN_DIR_INOUT 0x02
638#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
639#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
640
641/* Info about the pin modes supported by the different pin direction modes.
642 * For each direction the minimum and maximum values are given.
643 */
644static const signed char alc_pin_mode_dir_info[5][2] = {
645 { 0, 2 }, /* ALC_PIN_DIR_IN */
646 { 3, 4 }, /* ALC_PIN_DIR_OUT */
647 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
648 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
649 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
650};
651#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
652#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
653#define alc_pin_mode_n_items(_dir) \
654 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
655
656static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
657 struct snd_ctl_elem_info *uinfo)
658{
659 unsigned int item_num = uinfo->value.enumerated.item;
660 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
661
662 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
663 uinfo->count = 1;
664 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
665
666 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
667 item_num = alc_pin_mode_min(dir);
668 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
669 return 0;
670}
671
672static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
674{
675 unsigned int i;
676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
677 hda_nid_t nid = kcontrol->private_value & 0xffff;
678 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
679 long *valp = ucontrol->value.integer.value;
680 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
681 AC_VERB_GET_PIN_WIDGET_CONTROL,
682 0x00);
683
684 /* Find enumerated value for current pinctl setting */
685 i = alc_pin_mode_min(dir);
686 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
687 i++;
688 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
689 return 0;
690}
691
692static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
693 struct snd_ctl_elem_value *ucontrol)
694{
695 signed int change;
696 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
697 hda_nid_t nid = kcontrol->private_value & 0xffff;
698 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
699 long val = *ucontrol->value.integer.value;
700 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
701 AC_VERB_GET_PIN_WIDGET_CONTROL,
702 0x00);
703
704 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
705 val = alc_pin_mode_min(dir);
706
707 change = pinctl != alc_pin_mode_values[val];
708 if (change) {
709 /* Set pin mode to that requested */
710 snd_hda_codec_write_cache(codec, nid, 0,
711 AC_VERB_SET_PIN_WIDGET_CONTROL,
712 alc_pin_mode_values[val]);
713
714 /* Also enable the retasking pin's input/output as required
715 * for the requested pin mode. Enum values of 2 or less are
716 * input modes.
717 *
718 * Dynamically switching the input/output buffers probably
719 * reduces noise slightly (particularly on input) so we'll
720 * do it. However, having both input and output buffers
721 * enabled simultaneously doesn't seem to be problematic if
722 * this turns out to be necessary in the future.
723 */
724 if (val <= 2) {
725 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
726 HDA_AMP_MUTE, HDA_AMP_MUTE);
727 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
728 HDA_AMP_MUTE, 0);
729 } else {
730 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
731 HDA_AMP_MUTE, HDA_AMP_MUTE);
732 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
733 HDA_AMP_MUTE, 0);
734 }
735 }
736 return change;
737}
738
739#define ALC_PIN_MODE(xname, nid, dir) \
740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
741 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
742 .info = alc_pin_mode_info, \
743 .get = alc_pin_mode_get, \
744 .put = alc_pin_mode_put, \
745 .private_value = nid | (dir<<16) }
746
747/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
748 * together using a mask with more than one bit set. This control is
749 * currently used only by the ALC260 test model. At this stage they are not
750 * needed for any "production" models.
751 */
752#ifdef CONFIG_SND_DEBUG
753#define alc_gpio_data_info snd_ctl_boolean_mono_info
754
755static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
756 struct snd_ctl_elem_value *ucontrol)
757{
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 hda_nid_t nid = kcontrol->private_value & 0xffff;
760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
761 long *valp = ucontrol->value.integer.value;
762 unsigned int val = snd_hda_codec_read(codec, nid, 0,
763 AC_VERB_GET_GPIO_DATA, 0x00);
764
765 *valp = (val & mask) != 0;
766 return 0;
767}
768static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
769 struct snd_ctl_elem_value *ucontrol)
770{
771 signed int change;
772 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
773 hda_nid_t nid = kcontrol->private_value & 0xffff;
774 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
775 long val = *ucontrol->value.integer.value;
776 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
777 AC_VERB_GET_GPIO_DATA,
778 0x00);
779
780 /* Set/unset the masked GPIO bit(s) as needed */
781 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
782 if (val == 0)
783 gpio_data &= ~mask;
784 else
785 gpio_data |= mask;
786 snd_hda_codec_write_cache(codec, nid, 0,
787 AC_VERB_SET_GPIO_DATA, gpio_data);
788
789 return change;
790}
791#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
792 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
793 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
794 .info = alc_gpio_data_info, \
795 .get = alc_gpio_data_get, \
796 .put = alc_gpio_data_put, \
797 .private_value = nid | (mask<<16) }
798#endif /* CONFIG_SND_DEBUG */
799
800/* A switch control to allow the enabling of the digital IO pins on the
801 * ALC260. This is incredibly simplistic; the intention of this control is
802 * to provide something in the test model allowing digital outputs to be
803 * identified if present. If models are found which can utilise these
804 * outputs a more complete mixer control can be devised for those models if
805 * necessary.
806 */
807#ifdef CONFIG_SND_DEBUG
808#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
809
810static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
811 struct snd_ctl_elem_value *ucontrol)
812{
813 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
814 hda_nid_t nid = kcontrol->private_value & 0xffff;
815 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
816 long *valp = ucontrol->value.integer.value;
817 unsigned int val = snd_hda_codec_read(codec, nid, 0,
818 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
819
820 *valp = (val & mask) != 0;
821 return 0;
822}
823static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
824 struct snd_ctl_elem_value *ucontrol)
825{
826 signed int change;
827 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
828 hda_nid_t nid = kcontrol->private_value & 0xffff;
829 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
830 long val = *ucontrol->value.integer.value;
831 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
832 AC_VERB_GET_DIGI_CONVERT_1,
833 0x00);
834
835 /* Set/unset the masked control bit(s) as needed */
836 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
837 if (val==0)
838 ctrl_data &= ~mask;
839 else
840 ctrl_data |= mask;
841 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
842 ctrl_data);
843
844 return change;
845}
846#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
847 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
848 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
849 .info = alc_spdif_ctrl_info, \
850 .get = alc_spdif_ctrl_get, \
851 .put = alc_spdif_ctrl_put, \
852 .private_value = nid | (mask<<16) }
853#endif /* CONFIG_SND_DEBUG */
854
855/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
856 * Again, this is only used in the ALC26x test models to help identify when
857 * the EAPD line must be asserted for features to work.
858 */
859#ifdef CONFIG_SND_DEBUG
860#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
861
862static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
863 struct snd_ctl_elem_value *ucontrol)
864{
865 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
866 hda_nid_t nid = kcontrol->private_value & 0xffff;
867 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
868 long *valp = ucontrol->value.integer.value;
869 unsigned int val = snd_hda_codec_read(codec, nid, 0,
870 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
871
872 *valp = (val & mask) != 0;
873 return 0;
874}
875
876static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
877 struct snd_ctl_elem_value *ucontrol)
878{
879 int change;
880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
881 hda_nid_t nid = kcontrol->private_value & 0xffff;
882 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
883 long val = *ucontrol->value.integer.value;
884 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
885 AC_VERB_GET_EAPD_BTLENABLE,
886 0x00);
887
888 /* Set/unset the masked control bit(s) as needed */
889 change = (!val ? 0 : mask) != (ctrl_data & mask);
890 if (!val)
891 ctrl_data &= ~mask;
892 else
893 ctrl_data |= mask;
894 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
895 ctrl_data);
896
897 return change;
898}
899
900#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
901 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
902 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
903 .info = alc_eapd_ctrl_info, \
904 .get = alc_eapd_ctrl_get, \
905 .put = alc_eapd_ctrl_put, \
906 .private_value = nid | (mask<<16) }
907#endif /* CONFIG_SND_DEBUG */
908
909/*
910 * set up the input pin config (depending on the given auto-pin type) 314 * set up the input pin config (depending on the given auto-pin type)
911 */ 315 */
912static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 316static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
@@ -934,29 +338,10 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
934 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 338 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
935} 339}
936 340
937static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
938{
939 struct alc_spec *spec = codec->spec;
940 struct auto_pin_cfg *cfg = &spec->autocfg;
941
942 if (!cfg->line_outs) {
943 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
944 cfg->line_out_pins[cfg->line_outs])
945 cfg->line_outs++;
946 }
947 if (!cfg->speaker_outs) {
948 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
949 cfg->speaker_pins[cfg->speaker_outs])
950 cfg->speaker_outs++;
951 }
952 if (!cfg->hp_outs) {
953 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
954 cfg->hp_pins[cfg->hp_outs])
955 cfg->hp_outs++;
956 }
957}
958
959/* 341/*
342 * Append the given mixer and verb elements for the later use
343 * The mixer array is referred in build_controls(), and init_verbs are
344 * called in init().
960 */ 345 */
961static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) 346static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
962{ 347{
@@ -973,61 +358,8 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
973} 358}
974 359
975/* 360/*
976 * set up from the preset table 361 * GPIO setup tables, used in initialization
977 */ 362 */
978static void setup_preset(struct hda_codec *codec,
979 const struct alc_config_preset *preset)
980{
981 struct alc_spec *spec = codec->spec;
982 int i;
983
984 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
985 add_mixer(spec, preset->mixers[i]);
986 spec->cap_mixer = preset->cap_mixer;
987 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
988 i++)
989 add_verb(spec, preset->init_verbs[i]);
990
991 spec->channel_mode = preset->channel_mode;
992 spec->num_channel_mode = preset->num_channel_mode;
993 spec->need_dac_fix = preset->need_dac_fix;
994 spec->const_channel_count = preset->const_channel_count;
995
996 if (preset->const_channel_count)
997 spec->multiout.max_channels = preset->const_channel_count;
998 else
999 spec->multiout.max_channels = spec->channel_mode[0].channels;
1000 spec->ext_channel_count = spec->channel_mode[0].channels;
1001
1002 spec->multiout.num_dacs = preset->num_dacs;
1003 spec->multiout.dac_nids = preset->dac_nids;
1004 spec->multiout.dig_out_nid = preset->dig_out_nid;
1005 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
1006 spec->multiout.hp_nid = preset->hp_nid;
1007
1008 spec->num_mux_defs = preset->num_mux_defs;
1009 if (!spec->num_mux_defs)
1010 spec->num_mux_defs = 1;
1011 spec->input_mux = preset->input_mux;
1012
1013 spec->num_adc_nids = preset->num_adc_nids;
1014 spec->adc_nids = preset->adc_nids;
1015 spec->capsrc_nids = preset->capsrc_nids;
1016 spec->dig_in_nid = preset->dig_in_nid;
1017
1018 spec->unsol_event = preset->unsol_event;
1019 spec->init_hook = preset->init_hook;
1020#ifdef CONFIG_SND_HDA_POWER_SAVE
1021 spec->power_hook = preset->power_hook;
1022 spec->loopback.amplist = preset->loopbacks;
1023#endif
1024
1025 if (preset->setup)
1026 preset->setup(codec);
1027
1028 alc_fixup_autocfg_pin_nums(codec);
1029}
1030
1031/* Enable GPIO mask and set output */ 363/* Enable GPIO mask and set output */
1032static const struct hda_verb alc_gpio1_init_verbs[] = { 364static const struct hda_verb alc_gpio1_init_verbs[] = {
1033 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 365 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
@@ -1082,6 +414,11 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1082 alc_fix_pll(codec); 414 alc_fix_pll(codec);
1083} 415}
1084 416
417/*
418 * Jack-reporting via input-jack layer
419 */
420
421/* initialization of jacks; currently checks only a few known pins */
1085static int alc_init_jacks(struct hda_codec *codec) 422static int alc_init_jacks(struct hda_codec *codec)
1086{ 423{
1087#ifdef CONFIG_SND_HDA_INPUT_JACK 424#ifdef CONFIG_SND_HDA_INPUT_JACK
@@ -1117,7 +454,12 @@ static int alc_init_jacks(struct hda_codec *codec)
1117 return 0; 454 return 0;
1118} 455}
1119 456
1120static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 457/*
458 * Jack detections for HP auto-mute and mic-switch
459 */
460
461/* check each pin in the given array; returns true if any of them is plugged */
462static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1121{ 463{
1122 int i, present = 0; 464 int i, present = 0;
1123 465
@@ -1131,6 +473,7 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1131 return present; 473 return present;
1132} 474}
1133 475
476/* standard HP/line-out auto-mute helper */
1134static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 477static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1135 bool mute, bool hp_out) 478 bool mute, bool hp_out)
1136{ 479{
@@ -1201,6 +544,7 @@ static void update_speakers(struct hda_codec *codec)
1201 spec->autocfg.line_out_pins, on, false); 544 spec->autocfg.line_out_pins, on, false);
1202} 545}
1203 546
547/* standard HP-automute helper */
1204static void alc_hp_automute(struct hda_codec *codec) 548static void alc_hp_automute(struct hda_codec *codec)
1205{ 549{
1206 struct alc_spec *spec = codec->spec; 550 struct alc_spec *spec = codec->spec;
@@ -1213,6 +557,7 @@ static void alc_hp_automute(struct hda_codec *codec)
1213 update_speakers(codec); 557 update_speakers(codec);
1214} 558}
1215 559
560/* standard line-out-automute helper */
1216static void alc_line_automute(struct hda_codec *codec) 561static void alc_line_automute(struct hda_codec *codec)
1217{ 562{
1218 struct alc_spec *spec = codec->spec; 563 struct alc_spec *spec = codec->spec;
@@ -1228,6 +573,7 @@ static void alc_line_automute(struct hda_codec *codec)
1228#define get_connection_index(codec, mux, nid) \ 573#define get_connection_index(codec, mux, nid) \
1229 snd_hda_get_conn_index(codec, mux, nid, 0) 574 snd_hda_get_conn_index(codec, mux, nid, 0)
1230 575
576/* standard mic auto-switch helper */
1231static void alc_mic_automute(struct hda_codec *codec) 577static void alc_mic_automute(struct hda_codec *codec)
1232{ 578{
1233 struct alc_spec *spec = codec->spec; 579 struct alc_spec *spec = codec->spec;
@@ -1261,18 +607,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1261 else 607 else
1262 res >>= 26; 608 res >>= 26;
1263 switch (res) { 609 switch (res) {
1264 case ALC880_HP_EVENT: 610 case ALC_HP_EVENT:
1265 alc_hp_automute(codec); 611 alc_hp_automute(codec);
1266 break; 612 break;
1267 case ALC880_FRONT_EVENT: 613 case ALC_FRONT_EVENT:
1268 alc_line_automute(codec); 614 alc_line_automute(codec);
1269 break; 615 break;
1270 case ALC880_MIC_EVENT: 616 case ALC_MIC_EVENT:
1271 alc_mic_automute(codec); 617 alc_mic_automute(codec);
1272 break; 618 break;
1273 } 619 }
1274} 620}
1275 621
622/* call init functions of standard auto-mute helpers */
1276static void alc_inithook(struct hda_codec *codec) 623static void alc_inithook(struct hda_codec *codec)
1277{ 624{
1278 alc_hp_automute(codec); 625 alc_hp_automute(codec);
@@ -1298,6 +645,7 @@ static void alc888_coef_init(struct hda_codec *codec)
1298 AC_VERB_SET_PROC_COEF, 0x3030); 645 AC_VERB_SET_PROC_COEF, 0x3030);
1299} 646}
1300 647
648/* additional initialization for ALC889 variants */
1301static void alc889_coef_init(struct hda_codec *codec) 649static void alc889_coef_init(struct hda_codec *codec)
1302{ 650{
1303 unsigned int tmp; 651 unsigned int tmp;
@@ -1339,6 +687,7 @@ static void alc_eapd_shutup(struct hda_codec *codec)
1339 msleep(200); 687 msleep(200);
1340} 688}
1341 689
690/* generic EAPD initialization */
1342static void alc_auto_init_amp(struct hda_codec *codec, int type) 691static void alc_auto_init_amp(struct hda_codec *codec, int type)
1343{ 692{
1344 unsigned int tmp; 693 unsigned int tmp;
@@ -1398,6 +747,9 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1398 } 747 }
1399} 748}
1400 749
750/*
751 * Auto-Mute mode mixer enum support
752 */
1401static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, 753static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1402 struct snd_ctl_elem_info *uinfo) 754 struct snd_ctl_elem_info *uinfo)
1403{ 755{
@@ -1484,7 +836,11 @@ static const struct snd_kcontrol_new alc_automute_mode_enum = {
1484 .put = alc_automute_mode_put, 836 .put = alc_automute_mode_put,
1485}; 837};
1486 838
1487static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); 839static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
840{
841 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
842 return snd_array_new(&spec->kctls);
843}
1488 844
1489static int alc_add_automute_mode_enum(struct hda_codec *codec) 845static int alc_add_automute_mode_enum(struct hda_codec *codec)
1490{ 846{
@@ -1501,6 +857,10 @@ static int alc_add_automute_mode_enum(struct hda_codec *codec)
1501 return 0; 857 return 0;
1502} 858}
1503 859
860/*
861 * Check the availability of HP/line-out auto-mute;
862 * Set up appropriately if really supported
863 */
1504static void alc_init_auto_hp(struct hda_codec *codec) 864static void alc_init_auto_hp(struct hda_codec *codec)
1505{ 865{
1506 struct alc_spec *spec = codec->spec; 866 struct alc_spec *spec = codec->spec;
@@ -1539,7 +899,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1539 nid); 899 nid);
1540 snd_hda_codec_write_cache(codec, nid, 0, 900 snd_hda_codec_write_cache(codec, nid, 0,
1541 AC_VERB_SET_UNSOLICITED_ENABLE, 901 AC_VERB_SET_UNSOLICITED_ENABLE,
1542 AC_USRSP_EN | ALC880_HP_EVENT); 902 AC_USRSP_EN | ALC_HP_EVENT);
1543 spec->automute = 1; 903 spec->automute = 1;
1544 spec->automute_mode = ALC_AUTOMUTE_PIN; 904 spec->automute_mode = ALC_AUTOMUTE_PIN;
1545 } 905 }
@@ -1554,7 +914,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1554 "on NID 0x%x\n", nid); 914 "on NID 0x%x\n", nid);
1555 snd_hda_codec_write_cache(codec, nid, 0, 915 snd_hda_codec_write_cache(codec, nid, 0,
1556 AC_VERB_SET_UNSOLICITED_ENABLE, 916 AC_VERB_SET_UNSOLICITED_ENABLE,
1557 AC_USRSP_EN | ALC880_FRONT_EVENT); 917 AC_USRSP_EN | ALC_FRONT_EVENT);
1558 spec->detect_line = 1; 918 spec->detect_line = 1;
1559 } 919 }
1560 spec->automute_lines = spec->detect_line; 920 spec->automute_lines = spec->detect_line;
@@ -1567,6 +927,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1567 } 927 }
1568} 928}
1569 929
930/* return the position of NID in the list, or -1 if not found */
1570static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 931static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1571{ 932{
1572 int i; 933 int i;
@@ -1576,7 +937,47 @@ static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1576 return -1; 937 return -1;
1577} 938}
1578 939
1579static bool alc_check_dyn_adc_switch(struct hda_codec *codec); 940/* check whether dynamic ADC-switching is available */
941static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
942{
943 struct alc_spec *spec = codec->spec;
944 struct hda_input_mux *imux = &spec->private_imux[0];
945 int i, n, idx;
946 hda_nid_t cap, pin;
947
948 if (imux != spec->input_mux) /* no dynamic imux? */
949 return false;
950
951 for (n = 0; n < spec->num_adc_nids; n++) {
952 cap = spec->private_capsrc_nids[n];
953 for (i = 0; i < imux->num_items; i++) {
954 pin = spec->imux_pins[i];
955 if (!pin)
956 return false;
957 if (get_connection_index(codec, cap, pin) < 0)
958 break;
959 }
960 if (i >= imux->num_items)
961 return false; /* no ADC-switch is needed */
962 }
963
964 for (i = 0; i < imux->num_items; i++) {
965 pin = spec->imux_pins[i];
966 for (n = 0; n < spec->num_adc_nids; n++) {
967 cap = spec->private_capsrc_nids[n];
968 idx = get_connection_index(codec, cap, pin);
969 if (idx >= 0) {
970 imux->items[i].index = idx;
971 spec->dyn_adc_idx[i] = n;
972 break;
973 }
974 }
975 }
976
977 snd_printdd("realtek: enabling ADC switching\n");
978 spec->dyn_adc_switch = 1;
979 return true;
980}
1580 981
1581/* rebuild imux for matching with the given auto-mic pins (if not yet) */ 982/* rebuild imux for matching with the given auto-mic pins (if not yet) */
1582static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) 983static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
@@ -1637,17 +1038,21 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1637 1038
1638 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0, 1039 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0,
1639 AC_VERB_SET_UNSOLICITED_ENABLE, 1040 AC_VERB_SET_UNSOLICITED_ENABLE,
1640 AC_USRSP_EN | ALC880_MIC_EVENT); 1041 AC_USRSP_EN | ALC_MIC_EVENT);
1641 if (spec->dock_mic_pin) 1042 if (spec->dock_mic_pin)
1642 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0, 1043 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0,
1643 AC_VERB_SET_UNSOLICITED_ENABLE, 1044 AC_VERB_SET_UNSOLICITED_ENABLE,
1644 AC_USRSP_EN | ALC880_MIC_EVENT); 1045 AC_USRSP_EN | ALC_MIC_EVENT);
1645 1046
1646 spec->auto_mic_valid_imux = 1; 1047 spec->auto_mic_valid_imux = 1;
1647 spec->auto_mic = 1; 1048 spec->auto_mic = 1;
1648 return true; 1049 return true;
1649} 1050}
1650 1051
1052/*
1053 * Check the availability of auto-mic switch;
1054 * Set up if really supported
1055 */
1651static void alc_init_auto_mic(struct hda_codec *codec) 1056static void alc_init_auto_mic(struct hda_codec *codec)
1652{ 1057{
1653 struct alc_spec *spec = codec->spec; 1058 struct alc_spec *spec = codec->spec;
@@ -1713,6 +1118,17 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1713 spec->unsol_event = alc_sku_unsol_event; 1118 spec->unsol_event = alc_sku_unsol_event;
1714} 1119}
1715 1120
1121/* check the availabilities of auto-mute and auto-mic switches */
1122static void alc_auto_check_switches(struct hda_codec *codec)
1123{
1124 alc_init_auto_hp(codec);
1125 alc_init_auto_mic(codec);
1126}
1127
1128/*
1129 * Realtek SSID verification
1130 */
1131
1716/* Could be any non-zero and even value. When used as fixup, tells 1132/* Could be any non-zero and even value. When used as fixup, tells
1717 * the driver to ignore any present sku defines. 1133 * the driver to ignore any present sku defines.
1718 */ 1134 */
@@ -1783,6 +1199,7 @@ do_sku:
1783 return 0; 1199 return 0;
1784} 1200}
1785 1201
1202/* return true if the given NID is found in the list */
1786static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 1203static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1787{ 1204{
1788 return find_idx_in_nid_list(nid, list, nums) >= 0; 1205 return find_idx_in_nid_list(nid, list, nums) >= 0;
@@ -1917,13 +1334,6 @@ static void alc_ssid_check(struct hda_codec *codec,
1917 } 1334 }
1918} 1335}
1919 1336
1920/* check the availabilities of auto-mute and auto-mic switches */
1921static void alc_auto_check_switches(struct hda_codec *codec)
1922{
1923 alc_init_auto_hp(codec);
1924 alc_init_auto_mic(codec);
1925}
1926
1927/* 1337/*
1928 * Fix-up pin default configurations and add default verbs 1338 * Fix-up pin default configurations and add default verbs
1929 */ 1339 */
@@ -2069,6 +1479,9 @@ static void alc_pick_fixup(struct hda_codec *codec,
2069 } 1479 }
2070} 1480}
2071 1481
1482/*
1483 * COEF access helper functions
1484 */
2072static int alc_read_coef_idx(struct hda_codec *codec, 1485static int alc_read_coef_idx(struct hda_codec *codec,
2073 unsigned int coef_idx) 1486 unsigned int coef_idx)
2074{ 1487{
@@ -2089,6 +1502,10 @@ static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2089 coef_val); 1502 coef_val);
2090} 1503}
2091 1504
1505/*
1506 * Digital I/O handling
1507 */
1508
2092/* set right pin controls for digital I/O */ 1509/* set right pin controls for digital I/O */
2093static void alc_auto_init_digital(struct hda_codec *codec) 1510static void alc_auto_init_digital(struct hda_codec *codec)
2094{ 1511{
@@ -2167,562 +1584,8 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
2167} 1584}
2168 1585
2169/* 1586/*
2170 * ALC888 1587 * capture mixer elements
2171 */
2172
2173/*
2174 * 2ch mode
2175 */
2176static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2177/* Mic-in jack as mic in */
2178 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2179 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2180/* Line-in jack as Line in */
2181 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2182 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2183/* Line-Out as Front */
2184 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2185 { } /* end */
2186};
2187
2188/*
2189 * 4ch mode
2190 */
2191static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2192/* Mic-in jack as mic in */
2193 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2194 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2195/* Line-in jack as Surround */
2196 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2197 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2198/* Line-Out as Front */
2199 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2200 { } /* end */
2201};
2202
2203/*
2204 * 6ch mode
2205 */
2206static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2207/* Mic-in jack as CLFE */
2208 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2209 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2210/* Line-in jack as Surround */
2211 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2212 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2213/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2214 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2215 { } /* end */
2216};
2217
2218/*
2219 * 8ch mode
2220 */
2221static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2222/* Mic-in jack as CLFE */
2223 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2224 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2225/* Line-in jack as Surround */
2226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2228/* Line-Out as Side */
2229 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2230 { } /* end */
2231};
2232
2233static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2234 { 2, alc888_4ST_ch2_intel_init },
2235 { 4, alc888_4ST_ch4_intel_init },
2236 { 6, alc888_4ST_ch6_intel_init },
2237 { 8, alc888_4ST_ch8_intel_init },
2238};
2239
2240/*
2241 * ALC888 Fujitsu Siemens Amillo xa3530
2242 */
2243
2244static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2245/* Front Mic: set to PIN_IN (empty by default) */
2246 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2247/* Connect Internal HP to Front */
2248 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2250 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2251/* Connect Bass HP to Front */
2252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2253 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2254 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2255/* Connect Line-Out side jack (SPDIF) to Side */
2256 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2257 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2258 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2259/* Connect Mic jack to CLFE */
2260 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2261 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2262 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2263/* Connect Line-in jack to Surround */
2264 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2265 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2266 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2267/* Connect HP out jack to Front */
2268 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2269 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2270 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2271/* Enable unsolicited event for HP jack and Line-out jack */
2272 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2273 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2274 {}
2275};
2276
2277static void alc889_automute_setup(struct hda_codec *codec)
2278{
2279 struct alc_spec *spec = codec->spec;
2280
2281 spec->autocfg.hp_pins[0] = 0x15;
2282 spec->autocfg.speaker_pins[0] = 0x14;
2283 spec->autocfg.speaker_pins[1] = 0x16;
2284 spec->autocfg.speaker_pins[2] = 0x17;
2285 spec->autocfg.speaker_pins[3] = 0x19;
2286 spec->autocfg.speaker_pins[4] = 0x1a;
2287 spec->automute = 1;
2288 spec->automute_mode = ALC_AUTOMUTE_AMP;
2289}
2290
2291static void alc889_intel_init_hook(struct hda_codec *codec)
2292{
2293 alc889_coef_init(codec);
2294 alc_hp_automute(codec);
2295}
2296
2297static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2298{
2299 struct alc_spec *spec = codec->spec;
2300
2301 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2302 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2303 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2304 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2305 spec->automute = 1;
2306 spec->automute_mode = ALC_AUTOMUTE_AMP;
2307}
2308
2309/*
2310 * ALC888 Acer Aspire 4930G model
2311 */
2312
2313static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2314/* Front Mic: set to PIN_IN (empty by default) */
2315 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2316/* Unselect Front Mic by default in input mixer 3 */
2317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2318/* Enable unsolicited event for HP jack */
2319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2320/* Connect Internal HP to front */
2321 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2322 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2323 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2324/* Connect HP out to front */
2325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2328 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2329 { }
2330};
2331
2332/*
2333 * ALC888 Acer Aspire 6530G model
2334 */
2335
2336static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2337/* Route to built-in subwoofer as well as speakers */
2338 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2340 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2342/* Bias voltage on for external mic port */
2343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2344/* Front Mic: set to PIN_IN (empty by default) */
2345 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2346/* Unselect Front Mic by default in input mixer 3 */
2347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2348/* Enable unsolicited event for HP jack */
2349 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2350/* Enable speaker output */
2351 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2352 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2353 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2354/* Enable headphone output */
2355 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2356 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2357 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2358 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2359 { }
2360};
2361
2362/*
2363 *ALC888 Acer Aspire 7730G model
2364 */
2365
2366static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2367/* Bias voltage on for external mic port */
2368 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2369/* Front Mic: set to PIN_IN (empty by default) */
2370 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2371/* Unselect Front Mic by default in input mixer 3 */
2372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2373/* Enable unsolicited event for HP jack */
2374 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2375/* Enable speaker output */
2376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2377 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2378 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2379/* Enable headphone output */
2380 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2382 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2383 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2384/*Enable internal subwoofer */
2385 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2386 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2387 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2388 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2389 { }
2390};
2391
2392/*
2393 * ALC889 Acer Aspire 8930G model
2394 */
2395
2396static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2397/* Front Mic: set to PIN_IN (empty by default) */
2398 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2399/* Unselect Front Mic by default in input mixer 3 */
2400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2401/* Enable unsolicited event for HP jack */
2402 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2403/* Connect Internal Front to Front */
2404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2405 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2406 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2407/* Connect Internal Rear to Rear */
2408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2411/* Connect Internal CLFE to CLFE */
2412 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2413 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2414 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2415/* Connect HP out to Front */
2416 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2417 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2418 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2419/* Enable all DACs */
2420/* DAC DISABLE/MUTE 1? */
2421/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2422 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2423 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2424/* DAC DISABLE/MUTE 2? */
2425/* some bit here disables the other DACs. Init=0x4900 */
2426 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2427 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2428/* DMIC fix
2429 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2430 * which makes the stereo useless. However, either the mic or the ALC889
2431 * makes the signal become a difference/sum signal instead of standard
2432 * stereo, which is annoying. So instead we flip this bit which makes the
2433 * codec replicate the sum signal to both channels, turning it into a
2434 * normal mono mic.
2435 */
2436/* DMIC_CONTROL? Init value = 0x0001 */
2437 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2438 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2439 { }
2440};
2441
2442static const struct hda_input_mux alc888_2_capture_sources[2] = {
2443 /* Front mic only available on one ADC */
2444 {
2445 .num_items = 4,
2446 .items = {
2447 { "Mic", 0x0 },
2448 { "Line", 0x2 },
2449 { "CD", 0x4 },
2450 { "Front Mic", 0xb },
2451 },
2452 },
2453 {
2454 .num_items = 3,
2455 .items = {
2456 { "Mic", 0x0 },
2457 { "Line", 0x2 },
2458 { "CD", 0x4 },
2459 },
2460 }
2461};
2462
2463static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2464 /* Interal mic only available on one ADC */
2465 {
2466 .num_items = 5,
2467 .items = {
2468 { "Mic", 0x0 },
2469 { "Line In", 0x2 },
2470 { "CD", 0x4 },
2471 { "Input Mix", 0xa },
2472 { "Internal Mic", 0xb },
2473 },
2474 },
2475 {
2476 .num_items = 4,
2477 .items = {
2478 { "Mic", 0x0 },
2479 { "Line In", 0x2 },
2480 { "CD", 0x4 },
2481 { "Input Mix", 0xa },
2482 },
2483 }
2484};
2485
2486static const struct hda_input_mux alc889_capture_sources[3] = {
2487 /* Digital mic only available on first "ADC" */
2488 {
2489 .num_items = 5,
2490 .items = {
2491 { "Mic", 0x0 },
2492 { "Line", 0x2 },
2493 { "CD", 0x4 },
2494 { "Front Mic", 0xb },
2495 { "Input Mix", 0xa },
2496 },
2497 },
2498 {
2499 .num_items = 4,
2500 .items = {
2501 { "Mic", 0x0 },
2502 { "Line", 0x2 },
2503 { "CD", 0x4 },
2504 { "Input Mix", 0xa },
2505 },
2506 },
2507 {
2508 .num_items = 4,
2509 .items = {
2510 { "Mic", 0x0 },
2511 { "Line", 0x2 },
2512 { "CD", 0x4 },
2513 { "Input Mix", 0xa },
2514 },
2515 }
2516};
2517
2518static const struct snd_kcontrol_new alc888_base_mixer[] = {
2519 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2520 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2521 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2522 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2523 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2524 HDA_OUTPUT),
2525 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2526 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2527 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2528 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2529 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2535 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2537 { } /* end */
2538};
2539
2540static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2541 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2542 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2543 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2544 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2545 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2546 HDA_OUTPUT),
2547 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2548 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2550 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2551 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2552 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2553 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2554 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2555 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2557 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2558 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2559 { } /* end */
2560};
2561
2562static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2563 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2564 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2565 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2566 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2567 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2568 HDA_OUTPUT),
2569 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2570 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2571 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2572 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2573 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2575 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2577 { } /* end */
2578};
2579
2580
2581static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2582{
2583 struct alc_spec *spec = codec->spec;
2584
2585 spec->autocfg.hp_pins[0] = 0x15;
2586 spec->autocfg.speaker_pins[0] = 0x14;
2587 spec->autocfg.speaker_pins[1] = 0x16;
2588 spec->autocfg.speaker_pins[2] = 0x17;
2589 spec->automute = 1;
2590 spec->automute_mode = ALC_AUTOMUTE_AMP;
2591}
2592
2593static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2594{
2595 struct alc_spec *spec = codec->spec;
2596
2597 spec->autocfg.hp_pins[0] = 0x15;
2598 spec->autocfg.speaker_pins[0] = 0x14;
2599 spec->autocfg.speaker_pins[1] = 0x16;
2600 spec->autocfg.speaker_pins[2] = 0x17;
2601 spec->automute = 1;
2602 spec->automute_mode = ALC_AUTOMUTE_AMP;
2603}
2604
2605static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2606{
2607 struct alc_spec *spec = codec->spec;
2608
2609 spec->autocfg.hp_pins[0] = 0x15;
2610 spec->autocfg.speaker_pins[0] = 0x14;
2611 spec->autocfg.speaker_pins[1] = 0x16;
2612 spec->autocfg.speaker_pins[2] = 0x17;
2613 spec->automute = 1;
2614 spec->automute_mode = ALC_AUTOMUTE_AMP;
2615}
2616
2617static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2618{
2619 struct alc_spec *spec = codec->spec;
2620
2621 spec->autocfg.hp_pins[0] = 0x15;
2622 spec->autocfg.speaker_pins[0] = 0x14;
2623 spec->autocfg.speaker_pins[1] = 0x16;
2624 spec->autocfg.speaker_pins[2] = 0x1b;
2625 spec->automute = 1;
2626 spec->automute_mode = ALC_AUTOMUTE_AMP;
2627}
2628
2629/*
2630 * ALC880 3-stack model
2631 *
2632 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2633 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2634 * F-Mic = 0x1b, HP = 0x19
2635 */ 1588 */
2636
2637static const hda_nid_t alc880_dac_nids[4] = {
2638 /* front, rear, clfe, rear_surr */
2639 0x02, 0x05, 0x04, 0x03
2640};
2641
2642static const hda_nid_t alc880_adc_nids[3] = {
2643 /* ADC0-2 */
2644 0x07, 0x08, 0x09,
2645};
2646
2647/* The datasheet says the node 0x07 is connected from inputs,
2648 * but it shows zero connection in the real implementation on some devices.
2649 * Note: this is a 915GAV bug, fixed on 915GLV
2650 */
2651static const hda_nid_t alc880_adc_nids_alt[2] = {
2652 /* ADC1-2 */
2653 0x08, 0x09,
2654};
2655
2656#define ALC880_DIGOUT_NID 0x06
2657#define ALC880_DIGIN_NID 0x0a
2658
2659static const struct hda_input_mux alc880_capture_source = {
2660 .num_items = 4,
2661 .items = {
2662 { "Mic", 0x0 },
2663 { "Front Mic", 0x3 },
2664 { "Line", 0x2 },
2665 { "CD", 0x4 },
2666 },
2667};
2668
2669/* channel source setting (2/6 channel selection for 3-stack) */
2670/* 2ch mode */
2671static const struct hda_verb alc880_threestack_ch2_init[] = {
2672 /* set line-in to input, mute it */
2673 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2674 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2675 /* set mic-in to input vref 80%, mute it */
2676 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2677 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2678 { } /* end */
2679};
2680
2681/* 6ch mode */
2682static const struct hda_verb alc880_threestack_ch6_init[] = {
2683 /* set line-in to output, unmute it */
2684 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2685 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2686 /* set mic-in to output, unmute it */
2687 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2688 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2689 { } /* end */
2690};
2691
2692static const struct hda_channel_mode alc880_threestack_modes[2] = {
2693 { 2, alc880_threestack_ch2_init },
2694 { 6, alc880_threestack_ch6_init },
2695};
2696
2697static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2698 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2699 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2700 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2701 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2702 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2703 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2704 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2705 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2711 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2712 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2713 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2715 {
2716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2717 .name = "Channel Mode",
2718 .info = alc_ch_mode_info,
2719 .get = alc_ch_mode_get,
2720 .put = alc_ch_mode_put,
2721 },
2722 { } /* end */
2723};
2724
2725/* capture mixer elements */
2726static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 1589static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2727 struct snd_ctl_elem_info *uinfo) 1590 struct snd_ctl_elem_info *uinfo)
2728{ 1591{
@@ -2886,335 +1749,6 @@ DEFINE_CAPMIX_NOSRC(2);
2886DEFINE_CAPMIX_NOSRC(3); 1749DEFINE_CAPMIX_NOSRC(3);
2887 1750
2888/* 1751/*
2889 * ALC880 5-stack model
2890 *
2891 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2892 * Side = 0x02 (0xd)
2893 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2894 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2895 */
2896
2897/* additional mixers to alc880_three_stack_mixer */
2898static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2899 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2900 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2901 { } /* end */
2902};
2903
2904/* channel source setting (6/8 channel selection for 5-stack) */
2905/* 6ch mode */
2906static const struct hda_verb alc880_fivestack_ch6_init[] = {
2907 /* set line-in to input, mute it */
2908 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2909 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2910 { } /* end */
2911};
2912
2913/* 8ch mode */
2914static const struct hda_verb alc880_fivestack_ch8_init[] = {
2915 /* set line-in to output, unmute it */
2916 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2917 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2918 { } /* end */
2919};
2920
2921static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2922 { 6, alc880_fivestack_ch6_init },
2923 { 8, alc880_fivestack_ch8_init },
2924};
2925
2926
2927/*
2928 * ALC880 6-stack model
2929 *
2930 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2931 * Side = 0x05 (0x0f)
2932 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2933 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2934 */
2935
2936static const hda_nid_t alc880_6st_dac_nids[4] = {
2937 /* front, rear, clfe, rear_surr */
2938 0x02, 0x03, 0x04, 0x05
2939};
2940
2941static const struct hda_input_mux alc880_6stack_capture_source = {
2942 .num_items = 4,
2943 .items = {
2944 { "Mic", 0x0 },
2945 { "Front Mic", 0x1 },
2946 { "Line", 0x2 },
2947 { "CD", 0x4 },
2948 },
2949};
2950
2951/* fixed 8-channels */
2952static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2953 { 8, NULL },
2954};
2955
2956static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2957 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2958 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2959 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2960 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2961 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2962 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2963 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2964 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2965 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2966 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2973 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2974 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2975 {
2976 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2977 .name = "Channel Mode",
2978 .info = alc_ch_mode_info,
2979 .get = alc_ch_mode_get,
2980 .put = alc_ch_mode_put,
2981 },
2982 { } /* end */
2983};
2984
2985
2986/*
2987 * ALC880 W810 model
2988 *
2989 * W810 has rear IO for:
2990 * Front (DAC 02)
2991 * Surround (DAC 03)
2992 * Center/LFE (DAC 04)
2993 * Digital out (06)
2994 *
2995 * The system also has a pair of internal speakers, and a headphone jack.
2996 * These are both connected to Line2 on the codec, hence to DAC 02.
2997 *
2998 * There is a variable resistor to control the speaker or headphone
2999 * volume. This is a hardware-only device without a software API.
3000 *
3001 * Plugging headphones in will disable the internal speakers. This is
3002 * implemented in hardware, not via the driver using jack sense. In
3003 * a similar fashion, plugging into the rear socket marked "front" will
3004 * disable both the speakers and headphones.
3005 *
3006 * For input, there's a microphone jack, and an "audio in" jack.
3007 * These may not do anything useful with this driver yet, because I
3008 * haven't setup any initialization verbs for these yet...
3009 */
3010
3011static const hda_nid_t alc880_w810_dac_nids[3] = {
3012 /* front, rear/surround, clfe */
3013 0x02, 0x03, 0x04
3014};
3015
3016/* fixed 6 channels */
3017static const struct hda_channel_mode alc880_w810_modes[1] = {
3018 { 6, NULL }
3019};
3020
3021/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
3022static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
3023 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3024 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3025 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3026 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3027 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3028 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3029 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3030 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3032 { } /* end */
3033};
3034
3035
3036/*
3037 * Z710V model
3038 *
3039 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
3040 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
3041 * Line = 0x1a
3042 */
3043
3044static const hda_nid_t alc880_z71v_dac_nids[1] = {
3045 0x02
3046};
3047#define ALC880_Z71V_HP_DAC 0x03
3048
3049/* fixed 2 channels */
3050static const struct hda_channel_mode alc880_2_jack_modes[1] = {
3051 { 2, NULL }
3052};
3053
3054static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
3055 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3056 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3057 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3058 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
3059 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3060 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3063 { } /* end */
3064};
3065
3066
3067/*
3068 * ALC880 F1734 model
3069 *
3070 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3071 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3072 */
3073
3074static const hda_nid_t alc880_f1734_dac_nids[1] = {
3075 0x03
3076};
3077#define ALC880_F1734_HP_DAC 0x02
3078
3079static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3081 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3082 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3083 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3084 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3085 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3087 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3088 { } /* end */
3089};
3090
3091static const struct hda_input_mux alc880_f1734_capture_source = {
3092 .num_items = 2,
3093 .items = {
3094 { "Mic", 0x1 },
3095 { "CD", 0x4 },
3096 },
3097};
3098
3099
3100/*
3101 * ALC880 ASUS model
3102 *
3103 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3104 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3105 * Mic = 0x18, Line = 0x1a
3106 */
3107
3108#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3109#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3110
3111static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3113 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3114 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3115 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3116 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3117 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3118 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3119 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3120 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3121 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3122 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3123 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3126 {
3127 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3128 .name = "Channel Mode",
3129 .info = alc_ch_mode_info,
3130 .get = alc_ch_mode_get,
3131 .put = alc_ch_mode_put,
3132 },
3133 { } /* end */
3134};
3135
3136/*
3137 * ALC880 ASUS W1V model
3138 *
3139 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3140 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3141 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3142 */
3143
3144/* additional mixers to alc880_asus_mixer */
3145static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3146 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3147 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3148 { } /* end */
3149};
3150
3151/* TCL S700 */
3152static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3153 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3154 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3155 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3156 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3157 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3160 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3161 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3162 { } /* end */
3163};
3164
3165/* Uniwill */
3166static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3167 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3168 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3169 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3170 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3171 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3172 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3173 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3174 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3175 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3176 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3181 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3182 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3183 {
3184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3185 .name = "Channel Mode",
3186 .info = alc_ch_mode_info,
3187 .get = alc_ch_mode_get,
3188 .put = alc_ch_mode_put,
3189 },
3190 { } /* end */
3191};
3192
3193static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3194 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3195 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3196 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3197 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3198 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3199 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3201 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3202 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3203 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3204 { } /* end */
3205};
3206
3207static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3208 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3209 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3210 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3211 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3214 { } /* end */
3215};
3216
3217/*
3218 * virtual master controls 1752 * virtual master controls
3219 */ 1753 */
3220 1754
@@ -3425,789 +1959,6 @@ static int alc_build_controls(struct hda_codec *codec)
3425 1959
3426 1960
3427/* 1961/*
3428 * initialize the codec volumes, etc
3429 */
3430
3431/*
3432 * generic initialization of ADC, input mixers and output mixers
3433 */
3434static const struct hda_verb alc880_volume_init_verbs[] = {
3435 /*
3436 * Unmute ADC0-2 and set the default input to mic-in
3437 */
3438 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3440 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3442 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3443 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3444
3445 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3446 * mixer widget
3447 * Note: PASD motherboards uses the Line In 2 as the input for front
3448 * panel mic (mic 2)
3449 */
3450 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3458
3459 /*
3460 * Set up output mixers (0x0c - 0x0f)
3461 */
3462 /* set vol=0 to output mixers */
3463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3466 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3467 /* set up input amps for analog loopback */
3468 /* Amp Indices: DAC = 0, mixer = 1 */
3469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3472 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3474 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3475 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3476 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3477
3478 { }
3479};
3480
3481/*
3482 * 3-stack pin configuration:
3483 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3484 */
3485static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3486 /*
3487 * preset connection lists of input pins
3488 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3489 */
3490 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3491 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3492 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3493
3494 /*
3495 * Set pin mode and muting
3496 */
3497 /* set front pin widgets 0x14 for output */
3498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3500 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3501 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3502 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3503 /* Mic2 (as headphone out) for HP output */
3504 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506 /* Line In pin widget for input */
3507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3509 /* Line2 (as front mic) pin widget for input and vref at 80% */
3510 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3511 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3512 /* CD pin widget for input */
3513 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3514
3515 { }
3516};
3517
3518/*
3519 * 5-stack pin configuration:
3520 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3521 * line-in/side = 0x1a, f-mic = 0x1b
3522 */
3523static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3524 /*
3525 * preset connection lists of input pins
3526 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3527 */
3528 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3529 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3530
3531 /*
3532 * Set pin mode and muting
3533 */
3534 /* set pin widgets 0x14-0x17 for output */
3535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3536 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3538 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3539 /* unmute pins for output (no gain on this amp) */
3540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3543 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544
3545 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3548 /* Mic2 (as headphone out) for HP output */
3549 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3550 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3551 /* Line In pin widget for input */
3552 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3554 /* Line2 (as front mic) pin widget for input and vref at 80% */
3555 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3556 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557 /* CD pin widget for input */
3558 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3559
3560 { }
3561};
3562
3563/*
3564 * W810 pin configuration:
3565 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3566 */
3567static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3568 /* hphone/speaker input selector: front DAC */
3569 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3570
3571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3572 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3574 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3575 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3576 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3577
3578 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3579 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3580
3581 { }
3582};
3583
3584/*
3585 * Z71V pin configuration:
3586 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3587 */
3588static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3593
3594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3595 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3596 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3597 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3598
3599 { }
3600};
3601
3602/*
3603 * 6-stack pin configuration:
3604 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3605 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3606 */
3607static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3608 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3609
3610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3611 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3612 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3614 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3615 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3616 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3617 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3618
3619 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3620 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3621 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3622 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3623 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3624 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3626 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3627 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3628
3629 { }
3630};
3631
3632/*
3633 * Uniwill pin configuration:
3634 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3635 * line = 0x1a
3636 */
3637static const struct hda_verb alc880_uniwill_init_verbs[] = {
3638 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3639
3640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3644 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3646 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3647 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3651 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3653 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3654
3655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3661 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3662 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3664
3665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3666 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3667
3668 { }
3669};
3670
3671/*
3672* Uniwill P53
3673* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3674 */
3675static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3676 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3677
3678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3690
3691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3693 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3697
3698 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3699 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3700
3701 { }
3702};
3703
3704static const struct hda_verb alc880_beep_init_verbs[] = {
3705 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3706 { }
3707};
3708
3709/* auto-toggle front mic */
3710static void alc88x_simple_mic_automute(struct hda_codec *codec)
3711{
3712 unsigned int present;
3713 unsigned char bits;
3714
3715 present = snd_hda_jack_detect(codec, 0x18);
3716 bits = present ? HDA_AMP_MUTE : 0;
3717 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3718}
3719
3720static void alc880_uniwill_setup(struct hda_codec *codec)
3721{
3722 struct alc_spec *spec = codec->spec;
3723
3724 spec->autocfg.hp_pins[0] = 0x14;
3725 spec->autocfg.speaker_pins[0] = 0x15;
3726 spec->autocfg.speaker_pins[0] = 0x16;
3727 spec->automute = 1;
3728 spec->automute_mode = ALC_AUTOMUTE_AMP;
3729}
3730
3731static void alc880_uniwill_init_hook(struct hda_codec *codec)
3732{
3733 alc_hp_automute(codec);
3734 alc88x_simple_mic_automute(codec);
3735}
3736
3737static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3738 unsigned int res)
3739{
3740 /* Looks like the unsol event is incompatible with the standard
3741 * definition. 4bit tag is placed at 28 bit!
3742 */
3743 switch (res >> 28) {
3744 case ALC880_MIC_EVENT:
3745 alc88x_simple_mic_automute(codec);
3746 break;
3747 default:
3748 alc_sku_unsol_event(codec, res);
3749 break;
3750 }
3751}
3752
3753static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3754{
3755 struct alc_spec *spec = codec->spec;
3756
3757 spec->autocfg.hp_pins[0] = 0x14;
3758 spec->autocfg.speaker_pins[0] = 0x15;
3759 spec->automute = 1;
3760 spec->automute_mode = ALC_AUTOMUTE_AMP;
3761}
3762
3763static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3764{
3765 unsigned int present;
3766
3767 present = snd_hda_codec_read(codec, 0x21, 0,
3768 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3769 present &= HDA_AMP_VOLMASK;
3770 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3771 HDA_AMP_VOLMASK, present);
3772 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3773 HDA_AMP_VOLMASK, present);
3774}
3775
3776static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3777 unsigned int res)
3778{
3779 /* Looks like the unsol event is incompatible with the standard
3780 * definition. 4bit tag is placed at 28 bit!
3781 */
3782 if ((res >> 28) == ALC880_DCVOL_EVENT)
3783 alc880_uniwill_p53_dcvol_automute(codec);
3784 else
3785 alc_sku_unsol_event(codec, res);
3786}
3787
3788/*
3789 * F1734 pin configuration:
3790 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3791 */
3792static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3793 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3794 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3795 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3796 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3797 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3798
3799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3800 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3803
3804 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3806 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3807 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3808 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3809 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3810 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3811 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3812 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3813
3814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3815 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3816
3817 { }
3818};
3819
3820/*
3821 * ASUS pin configuration:
3822 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3823 */
3824static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3825 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3826 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3827 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3828 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3829
3830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3833 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3835 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3836 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3837 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3838
3839 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3840 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3841 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3843 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3847 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3848
3849 { }
3850};
3851
3852/* Enable GPIO mask and set output */
3853#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3854#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3855#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3856
3857/* Clevo m520g init */
3858static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3859 /* headphone output */
3860 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3861 /* line-out */
3862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3864 /* Line-in */
3865 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3866 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3867 /* CD */
3868 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3869 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3870 /* Mic1 (rear panel) */
3871 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3872 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3873 /* Mic2 (front panel) */
3874 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3875 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3876 /* headphone */
3877 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3878 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3879 /* change to EAPD mode */
3880 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3881 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3882
3883 { }
3884};
3885
3886static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3887 /* change to EAPD mode */
3888 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3889 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3890
3891 /* Headphone output */
3892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3893 /* Front output*/
3894 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3895 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3896
3897 /* Line In pin widget for input */
3898 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3899 /* CD pin widget for input */
3900 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3901 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3902 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3903
3904 /* change to EAPD mode */
3905 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3906 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3907
3908 { }
3909};
3910
3911/*
3912 * LG m1 express dual
3913 *
3914 * Pin assignment:
3915 * Rear Line-In/Out (blue): 0x14
3916 * Build-in Mic-In: 0x15
3917 * Speaker-out: 0x17
3918 * HP-Out (green): 0x1b
3919 * Mic-In/Out (red): 0x19
3920 * SPDIF-Out: 0x1e
3921 */
3922
3923/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3924static const hda_nid_t alc880_lg_dac_nids[3] = {
3925 0x05, 0x02, 0x03
3926};
3927
3928/* seems analog CD is not working */
3929static const struct hda_input_mux alc880_lg_capture_source = {
3930 .num_items = 3,
3931 .items = {
3932 { "Mic", 0x1 },
3933 { "Line", 0x5 },
3934 { "Internal Mic", 0x6 },
3935 },
3936};
3937
3938/* 2,4,6 channel modes */
3939static const struct hda_verb alc880_lg_ch2_init[] = {
3940 /* set line-in and mic-in to input */
3941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3942 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3943 { }
3944};
3945
3946static const struct hda_verb alc880_lg_ch4_init[] = {
3947 /* set line-in to out and mic-in to input */
3948 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3949 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3950 { }
3951};
3952
3953static const struct hda_verb alc880_lg_ch6_init[] = {
3954 /* set line-in and mic-in to output */
3955 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3956 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3957 { }
3958};
3959
3960static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3961 { 2, alc880_lg_ch2_init },
3962 { 4, alc880_lg_ch4_init },
3963 { 6, alc880_lg_ch6_init },
3964};
3965
3966static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3967 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3968 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3969 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3970 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3971 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3972 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3973 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3974 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3976 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3977 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3978 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3979 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3980 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3981 {
3982 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3983 .name = "Channel Mode",
3984 .info = alc_ch_mode_info,
3985 .get = alc_ch_mode_get,
3986 .put = alc_ch_mode_put,
3987 },
3988 { } /* end */
3989};
3990
3991static const struct hda_verb alc880_lg_init_verbs[] = {
3992 /* set capture source to mic-in */
3993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3994 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3995 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3996 /* mute all amp mixer inputs */
3997 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3998 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3999 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4000 /* line-in to input */
4001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4002 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4003 /* built-in mic */
4004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4005 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4006 /* speaker-out */
4007 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4009 /* mic-in to input */
4010 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
4011 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4013 /* HP-out */
4014 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
4015 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4016 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4017 /* jack sense */
4018 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4019 { }
4020};
4021
4022/* toggle speaker-output according to the hp-jack state */
4023static void alc880_lg_setup(struct hda_codec *codec)
4024{
4025 struct alc_spec *spec = codec->spec;
4026
4027 spec->autocfg.hp_pins[0] = 0x1b;
4028 spec->autocfg.speaker_pins[0] = 0x17;
4029 spec->automute = 1;
4030 spec->automute_mode = ALC_AUTOMUTE_AMP;
4031}
4032
4033/*
4034 * LG LW20
4035 *
4036 * Pin assignment:
4037 * Speaker-out: 0x14
4038 * Mic-In: 0x18
4039 * Built-in Mic-In: 0x19
4040 * Line-In: 0x1b
4041 * HP-Out: 0x1a
4042 * SPDIF-Out: 0x1e
4043 */
4044
4045static const struct hda_input_mux alc880_lg_lw_capture_source = {
4046 .num_items = 3,
4047 .items = {
4048 { "Mic", 0x0 },
4049 { "Internal Mic", 0x1 },
4050 { "Line In", 0x2 },
4051 },
4052};
4053
4054#define alc880_lg_lw_modes alc880_threestack_modes
4055
4056static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
4057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4058 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4059 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4060 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4061 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4062 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4063 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4064 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4069 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4070 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4071 {
4072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4073 .name = "Channel Mode",
4074 .info = alc_ch_mode_info,
4075 .get = alc_ch_mode_get,
4076 .put = alc_ch_mode_put,
4077 },
4078 { } /* end */
4079};
4080
4081static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4082 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4083 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4084 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4085
4086 /* set capture source to mic-in */
4087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4088 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4091 /* speaker-out */
4092 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4093 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4094 /* HP-out */
4095 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4096 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4097 /* mic-in to input */
4098 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4099 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4100 /* built-in mic */
4101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4102 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4103 /* jack sense */
4104 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4105 { }
4106};
4107
4108/* toggle speaker-output according to the hp-jack state */
4109static void alc880_lg_lw_setup(struct hda_codec *codec)
4110{
4111 struct alc_spec *spec = codec->spec;
4112
4113 spec->autocfg.hp_pins[0] = 0x1b;
4114 spec->autocfg.speaker_pins[0] = 0x14;
4115 spec->automute = 1;
4116 spec->automute_mode = ALC_AUTOMUTE_AMP;
4117}
4118
4119static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4120 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4121 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4122 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4124 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4125 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4126 { } /* end */
4127};
4128
4129static const struct hda_input_mux alc880_medion_rim_capture_source = {
4130 .num_items = 2,
4131 .items = {
4132 { "Mic", 0x0 },
4133 { "Internal Mic", 0x1 },
4134 },
4135};
4136
4137static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4138 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4139
4140 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4142
4143 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4144 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4145 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4146 /* Mic2 (as headphone out) for HP output */
4147 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4148 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4149 /* Internal Speaker */
4150 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4151 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4152
4153 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4154 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4155
4156 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4157 { }
4158};
4159
4160/* toggle speaker-output according to the hp-jack state */
4161static void alc880_medion_rim_automute(struct hda_codec *codec)
4162{
4163 struct alc_spec *spec = codec->spec;
4164 alc_hp_automute(codec);
4165 /* toggle EAPD */
4166 if (spec->jack_present)
4167 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4168 else
4169 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4170}
4171
4172static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4173 unsigned int res)
4174{
4175 /* Looks like the unsol event is incompatible with the standard
4176 * definition. 4bit tag is placed at 28 bit!
4177 */
4178 if ((res >> 28) == ALC880_HP_EVENT)
4179 alc880_medion_rim_automute(codec);
4180}
4181
4182static void alc880_medion_rim_setup(struct hda_codec *codec)
4183{
4184 struct alc_spec *spec = codec->spec;
4185
4186 spec->autocfg.hp_pins[0] = 0x14;
4187 spec->autocfg.speaker_pins[0] = 0x1b;
4188 spec->automute = 1;
4189 spec->automute_mode = ALC_AUTOMUTE_AMP;
4190}
4191
4192#ifdef CONFIG_SND_HDA_POWER_SAVE
4193static const struct hda_amp_list alc880_loopbacks[] = {
4194 { 0x0b, HDA_INPUT, 0 },
4195 { 0x0b, HDA_INPUT, 1 },
4196 { 0x0b, HDA_INPUT, 2 },
4197 { 0x0b, HDA_INPUT, 3 },
4198 { 0x0b, HDA_INPUT, 4 },
4199 { } /* end */
4200};
4201
4202static const struct hda_amp_list alc880_lg_loopbacks[] = {
4203 { 0x0b, HDA_INPUT, 1 },
4204 { 0x0b, HDA_INPUT, 6 },
4205 { 0x0b, HDA_INPUT, 7 },
4206 { } /* end */
4207};
4208#endif
4209
4210/*
4211 * Common callbacks 1962 * Common callbacks
4212 */ 1963 */
4213 1964
@@ -4662,679 +2413,6 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
4662} 2413}
4663 2414
4664/* 2415/*
4665 * Test configuration for debugging
4666 *
4667 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4668 * enum controls.
4669 */
4670#ifdef CONFIG_SND_DEBUG
4671static const hda_nid_t alc880_test_dac_nids[4] = {
4672 0x02, 0x03, 0x04, 0x05
4673};
4674
4675static const struct hda_input_mux alc880_test_capture_source = {
4676 .num_items = 7,
4677 .items = {
4678 { "In-1", 0x0 },
4679 { "In-2", 0x1 },
4680 { "In-3", 0x2 },
4681 { "In-4", 0x3 },
4682 { "CD", 0x4 },
4683 { "Front", 0x5 },
4684 { "Surround", 0x6 },
4685 },
4686};
4687
4688static const struct hda_channel_mode alc880_test_modes[4] = {
4689 { 2, NULL },
4690 { 4, NULL },
4691 { 6, NULL },
4692 { 8, NULL },
4693};
4694
4695static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4696 struct snd_ctl_elem_info *uinfo)
4697{
4698 static const char * const texts[] = {
4699 "N/A", "Line Out", "HP Out",
4700 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4701 };
4702 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4703 uinfo->count = 1;
4704 uinfo->value.enumerated.items = 8;
4705 if (uinfo->value.enumerated.item >= 8)
4706 uinfo->value.enumerated.item = 7;
4707 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4708 return 0;
4709}
4710
4711static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4712 struct snd_ctl_elem_value *ucontrol)
4713{
4714 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4715 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4716 unsigned int pin_ctl, item = 0;
4717
4718 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4719 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4720 if (pin_ctl & AC_PINCTL_OUT_EN) {
4721 if (pin_ctl & AC_PINCTL_HP_EN)
4722 item = 2;
4723 else
4724 item = 1;
4725 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4726 switch (pin_ctl & AC_PINCTL_VREFEN) {
4727 case AC_PINCTL_VREF_HIZ: item = 3; break;
4728 case AC_PINCTL_VREF_50: item = 4; break;
4729 case AC_PINCTL_VREF_GRD: item = 5; break;
4730 case AC_PINCTL_VREF_80: item = 6; break;
4731 case AC_PINCTL_VREF_100: item = 7; break;
4732 }
4733 }
4734 ucontrol->value.enumerated.item[0] = item;
4735 return 0;
4736}
4737
4738static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4739 struct snd_ctl_elem_value *ucontrol)
4740{
4741 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4742 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4743 static const unsigned int ctls[] = {
4744 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4745 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4746 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4747 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4748 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4749 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4750 };
4751 unsigned int old_ctl, new_ctl;
4752
4753 old_ctl = snd_hda_codec_read(codec, nid, 0,
4754 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4755 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4756 if (old_ctl != new_ctl) {
4757 int val;
4758 snd_hda_codec_write_cache(codec, nid, 0,
4759 AC_VERB_SET_PIN_WIDGET_CONTROL,
4760 new_ctl);
4761 val = ucontrol->value.enumerated.item[0] >= 3 ?
4762 HDA_AMP_MUTE : 0;
4763 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4764 HDA_AMP_MUTE, val);
4765 return 1;
4766 }
4767 return 0;
4768}
4769
4770static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4771 struct snd_ctl_elem_info *uinfo)
4772{
4773 static const char * const texts[] = {
4774 "Front", "Surround", "CLFE", "Side"
4775 };
4776 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4777 uinfo->count = 1;
4778 uinfo->value.enumerated.items = 4;
4779 if (uinfo->value.enumerated.item >= 4)
4780 uinfo->value.enumerated.item = 3;
4781 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4782 return 0;
4783}
4784
4785static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4786 struct snd_ctl_elem_value *ucontrol)
4787{
4788 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4789 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4790 unsigned int sel;
4791
4792 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4793 ucontrol->value.enumerated.item[0] = sel & 3;
4794 return 0;
4795}
4796
4797static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4798 struct snd_ctl_elem_value *ucontrol)
4799{
4800 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4801 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4802 unsigned int sel;
4803
4804 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4805 if (ucontrol->value.enumerated.item[0] != sel) {
4806 sel = ucontrol->value.enumerated.item[0] & 3;
4807 snd_hda_codec_write_cache(codec, nid, 0,
4808 AC_VERB_SET_CONNECT_SEL, sel);
4809 return 1;
4810 }
4811 return 0;
4812}
4813
4814#define PIN_CTL_TEST(xname,nid) { \
4815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4816 .name = xname, \
4817 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4818 .info = alc_test_pin_ctl_info, \
4819 .get = alc_test_pin_ctl_get, \
4820 .put = alc_test_pin_ctl_put, \
4821 .private_value = nid \
4822 }
4823
4824#define PIN_SRC_TEST(xname,nid) { \
4825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4826 .name = xname, \
4827 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4828 .info = alc_test_pin_src_info, \
4829 .get = alc_test_pin_src_get, \
4830 .put = alc_test_pin_src_put, \
4831 .private_value = nid \
4832 }
4833
4834static const struct snd_kcontrol_new alc880_test_mixer[] = {
4835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4836 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4837 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4838 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4839 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4840 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4841 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4842 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4843 PIN_CTL_TEST("Front Pin Mode", 0x14),
4844 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4845 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4846 PIN_CTL_TEST("Side Pin Mode", 0x17),
4847 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4848 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4849 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4850 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4851 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4852 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4853 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4854 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4855 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4856 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4857 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4858 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4859 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4860 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4861 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4862 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4863 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4864 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4865 {
4866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4867 .name = "Channel Mode",
4868 .info = alc_ch_mode_info,
4869 .get = alc_ch_mode_get,
4870 .put = alc_ch_mode_put,
4871 },
4872 { } /* end */
4873};
4874
4875static const struct hda_verb alc880_test_init_verbs[] = {
4876 /* Unmute inputs of 0x0c - 0x0f */
4877 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4878 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4880 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4881 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4883 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4884 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4885 /* Vol output for 0x0c-0x0f */
4886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4887 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4888 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4889 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4890 /* Set output pins 0x14-0x17 */
4891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4893 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4894 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4895 /* Unmute output pins 0x14-0x17 */
4896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4897 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4899 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4900 /* Set input pins 0x18-0x1c */
4901 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4905 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4906 /* Mute input pins 0x18-0x1b */
4907 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4908 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4909 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4910 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4911 /* ADC set up */
4912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4913 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4914 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4915 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4916 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4917 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4918 /* Analog input/passthru */
4919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4924 { }
4925};
4926#endif
4927
4928/*
4929 */
4930
4931static const char * const alc880_models[ALC880_MODEL_LAST] = {
4932 [ALC880_3ST] = "3stack",
4933 [ALC880_TCL_S700] = "tcl",
4934 [ALC880_3ST_DIG] = "3stack-digout",
4935 [ALC880_CLEVO] = "clevo",
4936 [ALC880_5ST] = "5stack",
4937 [ALC880_5ST_DIG] = "5stack-digout",
4938 [ALC880_W810] = "w810",
4939 [ALC880_Z71V] = "z71v",
4940 [ALC880_6ST] = "6stack",
4941 [ALC880_6ST_DIG] = "6stack-digout",
4942 [ALC880_ASUS] = "asus",
4943 [ALC880_ASUS_W1V] = "asus-w1v",
4944 [ALC880_ASUS_DIG] = "asus-dig",
4945 [ALC880_ASUS_DIG2] = "asus-dig2",
4946 [ALC880_UNIWILL_DIG] = "uniwill",
4947 [ALC880_UNIWILL_P53] = "uniwill-p53",
4948 [ALC880_FUJITSU] = "fujitsu",
4949 [ALC880_F1734] = "F1734",
4950 [ALC880_LG] = "lg",
4951 [ALC880_LG_LW] = "lg-lw",
4952 [ALC880_MEDION_RIM] = "medion",
4953#ifdef CONFIG_SND_DEBUG
4954 [ALC880_TEST] = "test",
4955#endif
4956 [ALC880_AUTO] = "auto",
4957};
4958
4959static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4960 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4961 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4962 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4963 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4964 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4965 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4966 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4967 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4968 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4969 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4970 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4971 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4972 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4973 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4974 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4975 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4976 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4977 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4978 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4979 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4980 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4981 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4982 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4983 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4984 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4985 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4986 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4987 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4988 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4989 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4990 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4991 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4992 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4993 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4994 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4995 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4996 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4997 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4998 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4999 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
5000 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
5001 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
5002 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
5003 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
5004 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
5005 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
5006 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
5007 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
5008 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
5009 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
5010 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
5011 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
5012 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
5013 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
5014 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
5015 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
5016 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
5017 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
5018 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
5019 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
5020 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
5021 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
5022 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
5023 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
5024 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
5025 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
5026 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
5027 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
5028 /* default Intel */
5029 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
5030 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
5031 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
5032 {}
5033};
5034
5035/*
5036 * ALC880 codec presets
5037 */
5038static const struct alc_config_preset alc880_presets[] = {
5039 [ALC880_3ST] = {
5040 .mixers = { alc880_three_stack_mixer },
5041 .init_verbs = { alc880_volume_init_verbs,
5042 alc880_pin_3stack_init_verbs },
5043 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5044 .dac_nids = alc880_dac_nids,
5045 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5046 .channel_mode = alc880_threestack_modes,
5047 .need_dac_fix = 1,
5048 .input_mux = &alc880_capture_source,
5049 },
5050 [ALC880_3ST_DIG] = {
5051 .mixers = { alc880_three_stack_mixer },
5052 .init_verbs = { alc880_volume_init_verbs,
5053 alc880_pin_3stack_init_verbs },
5054 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5055 .dac_nids = alc880_dac_nids,
5056 .dig_out_nid = ALC880_DIGOUT_NID,
5057 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5058 .channel_mode = alc880_threestack_modes,
5059 .need_dac_fix = 1,
5060 .input_mux = &alc880_capture_source,
5061 },
5062 [ALC880_TCL_S700] = {
5063 .mixers = { alc880_tcl_s700_mixer },
5064 .init_verbs = { alc880_volume_init_verbs,
5065 alc880_pin_tcl_S700_init_verbs,
5066 alc880_gpio2_init_verbs },
5067 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5068 .dac_nids = alc880_dac_nids,
5069 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
5070 .num_adc_nids = 1, /* single ADC */
5071 .hp_nid = 0x03,
5072 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5073 .channel_mode = alc880_2_jack_modes,
5074 .input_mux = &alc880_capture_source,
5075 },
5076 [ALC880_5ST] = {
5077 .mixers = { alc880_three_stack_mixer,
5078 alc880_five_stack_mixer},
5079 .init_verbs = { alc880_volume_init_verbs,
5080 alc880_pin_5stack_init_verbs },
5081 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5082 .dac_nids = alc880_dac_nids,
5083 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5084 .channel_mode = alc880_fivestack_modes,
5085 .input_mux = &alc880_capture_source,
5086 },
5087 [ALC880_5ST_DIG] = {
5088 .mixers = { alc880_three_stack_mixer,
5089 alc880_five_stack_mixer },
5090 .init_verbs = { alc880_volume_init_verbs,
5091 alc880_pin_5stack_init_verbs },
5092 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5093 .dac_nids = alc880_dac_nids,
5094 .dig_out_nid = ALC880_DIGOUT_NID,
5095 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5096 .channel_mode = alc880_fivestack_modes,
5097 .input_mux = &alc880_capture_source,
5098 },
5099 [ALC880_6ST] = {
5100 .mixers = { alc880_six_stack_mixer },
5101 .init_verbs = { alc880_volume_init_verbs,
5102 alc880_pin_6stack_init_verbs },
5103 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5104 .dac_nids = alc880_6st_dac_nids,
5105 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5106 .channel_mode = alc880_sixstack_modes,
5107 .input_mux = &alc880_6stack_capture_source,
5108 },
5109 [ALC880_6ST_DIG] = {
5110 .mixers = { alc880_six_stack_mixer },
5111 .init_verbs = { alc880_volume_init_verbs,
5112 alc880_pin_6stack_init_verbs },
5113 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5114 .dac_nids = alc880_6st_dac_nids,
5115 .dig_out_nid = ALC880_DIGOUT_NID,
5116 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5117 .channel_mode = alc880_sixstack_modes,
5118 .input_mux = &alc880_6stack_capture_source,
5119 },
5120 [ALC880_W810] = {
5121 .mixers = { alc880_w810_base_mixer },
5122 .init_verbs = { alc880_volume_init_verbs,
5123 alc880_pin_w810_init_verbs,
5124 alc880_gpio2_init_verbs },
5125 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5126 .dac_nids = alc880_w810_dac_nids,
5127 .dig_out_nid = ALC880_DIGOUT_NID,
5128 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5129 .channel_mode = alc880_w810_modes,
5130 .input_mux = &alc880_capture_source,
5131 },
5132 [ALC880_Z71V] = {
5133 .mixers = { alc880_z71v_mixer },
5134 .init_verbs = { alc880_volume_init_verbs,
5135 alc880_pin_z71v_init_verbs },
5136 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5137 .dac_nids = alc880_z71v_dac_nids,
5138 .dig_out_nid = ALC880_DIGOUT_NID,
5139 .hp_nid = 0x03,
5140 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5141 .channel_mode = alc880_2_jack_modes,
5142 .input_mux = &alc880_capture_source,
5143 },
5144 [ALC880_F1734] = {
5145 .mixers = { alc880_f1734_mixer },
5146 .init_verbs = { alc880_volume_init_verbs,
5147 alc880_pin_f1734_init_verbs },
5148 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5149 .dac_nids = alc880_f1734_dac_nids,
5150 .hp_nid = 0x02,
5151 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5152 .channel_mode = alc880_2_jack_modes,
5153 .input_mux = &alc880_f1734_capture_source,
5154 .unsol_event = alc880_uniwill_p53_unsol_event,
5155 .setup = alc880_uniwill_p53_setup,
5156 .init_hook = alc_hp_automute,
5157 },
5158 [ALC880_ASUS] = {
5159 .mixers = { alc880_asus_mixer },
5160 .init_verbs = { alc880_volume_init_verbs,
5161 alc880_pin_asus_init_verbs,
5162 alc880_gpio1_init_verbs },
5163 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5164 .dac_nids = alc880_asus_dac_nids,
5165 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5166 .channel_mode = alc880_asus_modes,
5167 .need_dac_fix = 1,
5168 .input_mux = &alc880_capture_source,
5169 },
5170 [ALC880_ASUS_DIG] = {
5171 .mixers = { alc880_asus_mixer },
5172 .init_verbs = { alc880_volume_init_verbs,
5173 alc880_pin_asus_init_verbs,
5174 alc880_gpio1_init_verbs },
5175 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5176 .dac_nids = alc880_asus_dac_nids,
5177 .dig_out_nid = ALC880_DIGOUT_NID,
5178 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5179 .channel_mode = alc880_asus_modes,
5180 .need_dac_fix = 1,
5181 .input_mux = &alc880_capture_source,
5182 },
5183 [ALC880_ASUS_DIG2] = {
5184 .mixers = { alc880_asus_mixer },
5185 .init_verbs = { alc880_volume_init_verbs,
5186 alc880_pin_asus_init_verbs,
5187 alc880_gpio2_init_verbs }, /* use GPIO2 */
5188 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5189 .dac_nids = alc880_asus_dac_nids,
5190 .dig_out_nid = ALC880_DIGOUT_NID,
5191 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5192 .channel_mode = alc880_asus_modes,
5193 .need_dac_fix = 1,
5194 .input_mux = &alc880_capture_source,
5195 },
5196 [ALC880_ASUS_W1V] = {
5197 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5198 .init_verbs = { alc880_volume_init_verbs,
5199 alc880_pin_asus_init_verbs,
5200 alc880_gpio1_init_verbs },
5201 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5202 .dac_nids = alc880_asus_dac_nids,
5203 .dig_out_nid = ALC880_DIGOUT_NID,
5204 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5205 .channel_mode = alc880_asus_modes,
5206 .need_dac_fix = 1,
5207 .input_mux = &alc880_capture_source,
5208 },
5209 [ALC880_UNIWILL_DIG] = {
5210 .mixers = { alc880_asus_mixer },
5211 .init_verbs = { alc880_volume_init_verbs,
5212 alc880_pin_asus_init_verbs },
5213 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5214 .dac_nids = alc880_asus_dac_nids,
5215 .dig_out_nid = ALC880_DIGOUT_NID,
5216 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5217 .channel_mode = alc880_asus_modes,
5218 .need_dac_fix = 1,
5219 .input_mux = &alc880_capture_source,
5220 },
5221 [ALC880_UNIWILL] = {
5222 .mixers = { alc880_uniwill_mixer },
5223 .init_verbs = { alc880_volume_init_verbs,
5224 alc880_uniwill_init_verbs },
5225 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5226 .dac_nids = alc880_asus_dac_nids,
5227 .dig_out_nid = ALC880_DIGOUT_NID,
5228 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5229 .channel_mode = alc880_threestack_modes,
5230 .need_dac_fix = 1,
5231 .input_mux = &alc880_capture_source,
5232 .unsol_event = alc880_uniwill_unsol_event,
5233 .setup = alc880_uniwill_setup,
5234 .init_hook = alc880_uniwill_init_hook,
5235 },
5236 [ALC880_UNIWILL_P53] = {
5237 .mixers = { alc880_uniwill_p53_mixer },
5238 .init_verbs = { alc880_volume_init_verbs,
5239 alc880_uniwill_p53_init_verbs },
5240 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5241 .dac_nids = alc880_asus_dac_nids,
5242 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5243 .channel_mode = alc880_threestack_modes,
5244 .input_mux = &alc880_capture_source,
5245 .unsol_event = alc880_uniwill_p53_unsol_event,
5246 .setup = alc880_uniwill_p53_setup,
5247 .init_hook = alc_hp_automute,
5248 },
5249 [ALC880_FUJITSU] = {
5250 .mixers = { alc880_fujitsu_mixer },
5251 .init_verbs = { alc880_volume_init_verbs,
5252 alc880_uniwill_p53_init_verbs,
5253 alc880_beep_init_verbs },
5254 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5255 .dac_nids = alc880_dac_nids,
5256 .dig_out_nid = ALC880_DIGOUT_NID,
5257 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5258 .channel_mode = alc880_2_jack_modes,
5259 .input_mux = &alc880_capture_source,
5260 .unsol_event = alc880_uniwill_p53_unsol_event,
5261 .setup = alc880_uniwill_p53_setup,
5262 .init_hook = alc_hp_automute,
5263 },
5264 [ALC880_CLEVO] = {
5265 .mixers = { alc880_three_stack_mixer },
5266 .init_verbs = { alc880_volume_init_verbs,
5267 alc880_pin_clevo_init_verbs },
5268 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5269 .dac_nids = alc880_dac_nids,
5270 .hp_nid = 0x03,
5271 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5272 .channel_mode = alc880_threestack_modes,
5273 .need_dac_fix = 1,
5274 .input_mux = &alc880_capture_source,
5275 },
5276 [ALC880_LG] = {
5277 .mixers = { alc880_lg_mixer },
5278 .init_verbs = { alc880_volume_init_verbs,
5279 alc880_lg_init_verbs },
5280 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5281 .dac_nids = alc880_lg_dac_nids,
5282 .dig_out_nid = ALC880_DIGOUT_NID,
5283 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5284 .channel_mode = alc880_lg_ch_modes,
5285 .need_dac_fix = 1,
5286 .input_mux = &alc880_lg_capture_source,
5287 .unsol_event = alc_sku_unsol_event,
5288 .setup = alc880_lg_setup,
5289 .init_hook = alc_hp_automute,
5290#ifdef CONFIG_SND_HDA_POWER_SAVE
5291 .loopbacks = alc880_lg_loopbacks,
5292#endif
5293 },
5294 [ALC880_LG_LW] = {
5295 .mixers = { alc880_lg_lw_mixer },
5296 .init_verbs = { alc880_volume_init_verbs,
5297 alc880_lg_lw_init_verbs },
5298 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5299 .dac_nids = alc880_dac_nids,
5300 .dig_out_nid = ALC880_DIGOUT_NID,
5301 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5302 .channel_mode = alc880_lg_lw_modes,
5303 .input_mux = &alc880_lg_lw_capture_source,
5304 .unsol_event = alc_sku_unsol_event,
5305 .setup = alc880_lg_lw_setup,
5306 .init_hook = alc_hp_automute,
5307 },
5308 [ALC880_MEDION_RIM] = {
5309 .mixers = { alc880_medion_rim_mixer },
5310 .init_verbs = { alc880_volume_init_verbs,
5311 alc880_medion_rim_init_verbs,
5312 alc_gpio2_init_verbs },
5313 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5314 .dac_nids = alc880_dac_nids,
5315 .dig_out_nid = ALC880_DIGOUT_NID,
5316 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5317 .channel_mode = alc880_2_jack_modes,
5318 .input_mux = &alc880_medion_rim_capture_source,
5319 .unsol_event = alc880_medion_rim_unsol_event,
5320 .setup = alc880_medion_rim_setup,
5321 .init_hook = alc880_medion_rim_automute,
5322 },
5323#ifdef CONFIG_SND_DEBUG
5324 [ALC880_TEST] = {
5325 .mixers = { alc880_test_mixer },
5326 .init_verbs = { alc880_test_init_verbs },
5327 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5328 .dac_nids = alc880_test_dac_nids,
5329 .dig_out_nid = ALC880_DIGOUT_NID,
5330 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5331 .channel_mode = alc880_test_modes,
5332 .input_mux = &alc880_test_capture_source,
5333 },
5334#endif
5335};
5336
5337/*
5338 * Automatic parse of I/O pins from the BIOS configuration 2416 * Automatic parse of I/O pins from the BIOS configuration
5339 */ 2417 */
5340 2418
@@ -5343,18 +2421,12 @@ enum {
5343 ALC_CTL_WIDGET_MUTE, 2421 ALC_CTL_WIDGET_MUTE,
5344 ALC_CTL_BIND_MUTE, 2422 ALC_CTL_BIND_MUTE,
5345}; 2423};
5346static const struct snd_kcontrol_new alc880_control_templates[] = { 2424static const struct snd_kcontrol_new alc_control_templates[] = {
5347 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2425 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5348 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2426 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5349 HDA_BIND_MUTE(NULL, 0, 0, 0), 2427 HDA_BIND_MUTE(NULL, 0, 0, 0),
5350}; 2428};
5351 2429
5352static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5353{
5354 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5355 return snd_array_new(&spec->kctls);
5356}
5357
5358/* add dynamic controls */ 2430/* add dynamic controls */
5359static int add_control(struct alc_spec *spec, int type, const char *name, 2431static int add_control(struct alc_spec *spec, int type, const char *name,
5360 int cidx, unsigned long val) 2432 int cidx, unsigned long val)
@@ -5364,7 +2436,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
5364 knew = alc_kcontrol_new(spec); 2436 knew = alc_kcontrol_new(spec);
5365 if (!knew) 2437 if (!knew)
5366 return -ENOMEM; 2438 return -ENOMEM;
5367 *knew = alc880_control_templates[type]; 2439 *knew = alc_control_templates[type];
5368 knew->name = kstrdup(name, GFP_KERNEL); 2440 knew->name = kstrdup(name, GFP_KERNEL);
5369 if (!knew->name) 2441 if (!knew->name)
5370 return -ENOMEM; 2442 return -ENOMEM;
@@ -5393,16 +2465,6 @@ static int add_control_with_pfx(struct alc_spec *spec, int type,
5393#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 2465#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5394 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 2466 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5395 2467
5396#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5397#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5398#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5399#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5400#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5401#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5402#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5403#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5404#define ALC880_PIN_CD_NID 0x1c
5405
5406static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, 2468static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5407 bool can_be_master, int *index) 2469 bool can_be_master, int *index)
5408{ 2470{
@@ -5459,6 +2521,7 @@ static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5459 return (pincap & AC_PINCAP_IN) != 0; 2521 return (pincap & AC_PINCAP_IN) != 0;
5460} 2522}
5461 2523
2524/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */
5462static int alc_auto_fill_adc_caps(struct hda_codec *codec) 2525static int alc_auto_fill_adc_caps(struct hda_codec *codec)
5463{ 2526{
5464 struct alc_spec *spec = codec->spec; 2527 struct alc_spec *spec = codec->spec;
@@ -5568,14 +2631,6 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec)
5568 return 0; 2631 return 0;
5569} 2632}
5570 2633
5571static int alc_auto_fill_dac_nids(struct hda_codec *codec);
5572static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
5573 const struct auto_pin_cfg *cfg);
5574static int alc_auto_create_hp_out(struct hda_codec *codec);
5575static int alc_auto_create_speaker_out(struct hda_codec *codec);
5576static void alc_auto_init_multi_out(struct hda_codec *codec);
5577static void alc_auto_init_extra_out(struct hda_codec *codec);
5578
5579static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 2634static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5580 unsigned int pin_type) 2635 unsigned int pin_type)
5581{ 2636{
@@ -5621,73 +2676,664 @@ static void alc_auto_init_analog_input(struct hda_codec *codec)
5621 } 2676 }
5622} 2677}
5623 2678
5624static int alc_auto_add_multi_channel_mode(struct hda_codec *codec, 2679/* convert from MIX nid to DAC */
5625 int (*fill_dac)(struct hda_codec *)); 2680static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
5626static void alc_remove_invalid_adc_nids(struct hda_codec *codec); 2681{
5627static void alc_auto_init_input_src(struct hda_codec *codec); 2682 hda_nid_t list[5];
2683 int i, num;
5628 2684
5629/* parse the BIOS configuration and set up the alc_spec */ 2685 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
5630/* return 1 if successful, 0 if the proper config is not found, 2686 for (i = 0; i < num; i++) {
5631 * or a negative error code 2687 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
2688 return list[i];
2689 }
2690 return 0;
2691}
2692
2693/* go down to the selector widget before the mixer */
2694static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
2695{
2696 hda_nid_t srcs[5];
2697 int num = snd_hda_get_connections(codec, pin, srcs,
2698 ARRAY_SIZE(srcs));
2699 if (num != 1 ||
2700 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
2701 return pin;
2702 return srcs[0];
2703}
2704
2705/* get MIX nid connected to the given pin targeted to DAC */
2706static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
2707 hda_nid_t dac)
2708{
2709 hda_nid_t mix[5];
2710 int i, num;
2711
2712 pin = alc_go_down_to_selector(codec, pin);
2713 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2714 for (i = 0; i < num; i++) {
2715 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
2716 return mix[i];
2717 }
2718 return 0;
2719}
2720
2721/* select the connection from pin to DAC if needed */
2722static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2723 hda_nid_t dac)
2724{
2725 hda_nid_t mix[5];
2726 int i, num;
2727
2728 pin = alc_go_down_to_selector(codec, pin);
2729 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2730 if (num < 2)
2731 return 0;
2732 for (i = 0; i < num; i++) {
2733 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
2734 snd_hda_codec_update_cache(codec, pin, 0,
2735 AC_VERB_SET_CONNECT_SEL, i);
2736 return 0;
2737 }
2738 }
2739 return 0;
2740}
2741
2742/* look for an empty DAC slot */
2743static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2744{
2745 struct alc_spec *spec = codec->spec;
2746 hda_nid_t srcs[5];
2747 int i, num;
2748
2749 pin = alc_go_down_to_selector(codec, pin);
2750 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
2751 for (i = 0; i < num; i++) {
2752 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
2753 if (!nid)
2754 continue;
2755 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2756 spec->multiout.num_dacs))
2757 continue;
2758 if (spec->multiout.hp_nid == nid)
2759 continue;
2760 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2761 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2762 continue;
2763 return nid;
2764 }
2765 return 0;
2766}
2767
2768static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
2769{
2770 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
2771 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
2772 return alc_auto_look_for_dac(codec, pin);
2773 return 0;
2774}
2775
2776/* fill in the dac_nids table from the parsed pin configuration */
2777static int alc_auto_fill_dac_nids(struct hda_codec *codec)
2778{
2779 struct alc_spec *spec = codec->spec;
2780 const struct auto_pin_cfg *cfg = &spec->autocfg;
2781 bool redone = false;
2782 int i;
2783
2784 again:
2785 spec->multiout.num_dacs = 0;
2786 spec->multiout.hp_nid = 0;
2787 spec->multiout.extra_out_nid[0] = 0;
2788 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
2789 spec->multiout.dac_nids = spec->private_dac_nids;
2790
2791 /* fill hard-wired DACs first */
2792 if (!redone) {
2793 for (i = 0; i < cfg->line_outs; i++)
2794 spec->private_dac_nids[i] =
2795 get_dac_if_single(codec, cfg->line_out_pins[i]);
2796 if (cfg->hp_outs)
2797 spec->multiout.hp_nid =
2798 get_dac_if_single(codec, cfg->hp_pins[0]);
2799 if (cfg->speaker_outs)
2800 spec->multiout.extra_out_nid[0] =
2801 get_dac_if_single(codec, cfg->speaker_pins[0]);
2802 }
2803
2804 for (i = 0; i < cfg->line_outs; i++) {
2805 hda_nid_t pin = cfg->line_out_pins[i];
2806 if (spec->private_dac_nids[i])
2807 continue;
2808 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
2809 if (!spec->private_dac_nids[i] && !redone) {
2810 /* if we can't find primary DACs, re-probe without
2811 * checking the hard-wired DACs
2812 */
2813 redone = true;
2814 goto again;
2815 }
2816 }
2817
2818 for (i = 0; i < cfg->line_outs; i++) {
2819 if (spec->private_dac_nids[i])
2820 spec->multiout.num_dacs++;
2821 else
2822 memmove(spec->private_dac_nids + i,
2823 spec->private_dac_nids + i + 1,
2824 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
2825 }
2826
2827 if (cfg->hp_outs && !spec->multiout.hp_nid)
2828 spec->multiout.hp_nid =
2829 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
2830 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
2831 spec->multiout.extra_out_nid[0] =
2832 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
2833
2834 return 0;
2835}
2836
2837static int alc_auto_add_vol_ctl(struct hda_codec *codec,
2838 const char *pfx, int cidx,
2839 hda_nid_t nid, unsigned int chs)
2840{
2841 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
2842 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2843}
2844
2845#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
2846 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
2847
2848/* create a mute-switch for the given mixer widget;
2849 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
5632 */ 2850 */
5633static int alc880_parse_auto_config(struct hda_codec *codec) 2851static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2852 const char *pfx, int cidx,
2853 hda_nid_t nid, unsigned int chs)
2854{
2855 int type;
2856 unsigned long val;
2857 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
2858 type = ALC_CTL_WIDGET_MUTE;
2859 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
2860 } else {
2861 type = ALC_CTL_BIND_MUTE;
2862 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
2863 }
2864 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
2865}
2866
2867#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
2868 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
2869
2870/* add playback controls from the parsed DAC table */
2871static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2872 const struct auto_pin_cfg *cfg)
5634{ 2873{
5635 struct alc_spec *spec = codec->spec; 2874 struct alc_spec *spec = codec->spec;
2875 hda_nid_t nid, mix, pin;
2876 int i, err, noutputs;
2877
2878 noutputs = cfg->line_outs;
2879 if (spec->multi_ios > 0)
2880 noutputs += spec->multi_ios;
2881
2882 for (i = 0; i < noutputs; i++) {
2883 const char *name;
2884 int index;
2885 nid = spec->multiout.dac_nids[i];
2886 if (!nid)
2887 continue;
2888 if (i >= cfg->line_outs)
2889 pin = spec->multi_io[i - 1].pin;
2890 else
2891 pin = cfg->line_out_pins[i];
2892 mix = alc_auto_dac_to_mix(codec, pin, nid);
2893 if (!mix)
2894 continue;
2895 name = alc_get_line_out_pfx(spec, i, true, &index);
2896 if (!name) {
2897 /* Center/LFE */
2898 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1);
2899 if (err < 0)
2900 return err;
2901 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2);
2902 if (err < 0)
2903 return err;
2904 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1);
2905 if (err < 0)
2906 return err;
2907 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2);
2908 if (err < 0)
2909 return err;
2910 } else {
2911 err = alc_auto_add_stereo_vol(codec, name, index, nid);
2912 if (err < 0)
2913 return err;
2914 err = alc_auto_add_stereo_sw(codec, name, index, mix);
2915 if (err < 0)
2916 return err;
2917 }
2918 }
2919 return 0;
2920}
2921
2922/* add playback controls for speaker and HP outputs */
2923static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2924 hda_nid_t dac, const char *pfx)
2925{
2926 struct alc_spec *spec = codec->spec;
2927 hda_nid_t mix;
5636 int err; 2928 int err;
5637 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5638 2929
5639 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 2930 if (!pin)
5640 alc880_ignore); 2931 return 0;
5641 if (err < 0) 2932 if (!dac) {
5642 return err; 2933 /* the corresponding DAC is already occupied */
5643 if (!spec->autocfg.line_outs) 2934 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
5644 return 0; /* can't find valid BIOS pin config */ 2935 return 0; /* no way */
2936 /* create a switch only */
2937 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
2938 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2939 }
5645 2940
5646 err = alc_auto_fill_dac_nids(codec); 2941 mix = alc_auto_dac_to_mix(codec, pin, dac);
5647 if (err < 0) 2942 if (!mix)
5648 return err; 2943 return 0;
5649 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids); 2944 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
5650 if (err < 0)
5651 return err;
5652 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
5653 if (err < 0)
5654 return err;
5655 err = alc_auto_create_hp_out(codec);
5656 if (err < 0)
5657 return err;
5658 err = alc_auto_create_speaker_out(codec);
5659 if (err < 0) 2945 if (err < 0)
5660 return err; 2946 return err;
5661 err = alc_auto_create_input_ctls(codec); 2947 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix);
5662 if (err < 0) 2948 if (err < 0)
5663 return err; 2949 return err;
2950 return 0;
2951}
5664 2952
5665 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2953static int alc_auto_create_hp_out(struct hda_codec *codec)
2954{
2955 struct alc_spec *spec = codec->spec;
2956 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
2957 spec->multiout.hp_nid,
2958 "Headphone");
2959}
5666 2960
5667 alc_auto_parse_digital(codec); 2961static int alc_auto_create_speaker_out(struct hda_codec *codec)
2962{
2963 struct alc_spec *spec = codec->spec;
2964 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
2965 spec->multiout.extra_out_nid[0],
2966 "Speaker");
2967}
5668 2968
5669 if (spec->kctls.list) 2969static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
5670 add_mixer(spec, spec->kctls.list); 2970 hda_nid_t nid, int pin_type,
2971 hda_nid_t dac)
2972{
2973 int i, num;
2974 hda_nid_t mix = 0;
2975 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
5671 2976
5672 alc_remove_invalid_adc_nids(codec); 2977 alc_set_pin_output(codec, nid, pin_type);
2978 nid = alc_go_down_to_selector(codec, nid);
2979 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
2980 for (i = 0; i < num; i++) {
2981 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
2982 continue;
2983 mix = srcs[i];
2984 break;
2985 }
2986 if (!mix)
2987 return;
5673 2988
5674 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 2989 /* need the manual connection? */
5675 alc_auto_check_switches(codec); 2990 if (num > 1)
2991 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
2992 /* unmute mixer widget inputs */
2993 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2994 AMP_IN_UNMUTE(0));
2995 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2996 AMP_IN_UNMUTE(1));
2997 /* initialize volume */
2998 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
2999 nid = dac;
3000 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
3001 nid = mix;
3002 else
3003 return;
3004 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3005 AMP_OUT_ZERO);
3006}
3007
3008static void alc_auto_init_multi_out(struct hda_codec *codec)
3009{
3010 struct alc_spec *spec = codec->spec;
3011 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3012 int i;
3013
3014 for (i = 0; i <= HDA_SIDE; i++) {
3015 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3016 if (nid)
3017 alc_auto_set_output_and_unmute(codec, nid, pin_type,
3018 spec->multiout.dac_nids[i]);
3019 }
3020}
3021
3022static void alc_auto_init_extra_out(struct hda_codec *codec)
3023{
3024 struct alc_spec *spec = codec->spec;
3025 hda_nid_t pin;
3026
3027 pin = spec->autocfg.hp_pins[0];
3028 if (pin)
3029 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
3030 spec->multiout.hp_nid);
3031 pin = spec->autocfg.speaker_pins[0];
3032 if (pin)
3033 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
3034 spec->multiout.extra_out_nid[0]);
3035}
5676 3036
3037/*
3038 * multi-io helper
3039 */
3040static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3041 unsigned int location)
3042{
3043 struct alc_spec *spec = codec->spec;
3044 struct auto_pin_cfg *cfg = &spec->autocfg;
3045 int type, i, num_pins = 0;
3046
3047 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3048 for (i = 0; i < cfg->num_inputs; i++) {
3049 hda_nid_t nid = cfg->inputs[i].pin;
3050 hda_nid_t dac;
3051 unsigned int defcfg, caps;
3052 if (cfg->inputs[i].type != type)
3053 continue;
3054 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3055 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3056 continue;
3057 if (location && get_defcfg_location(defcfg) != location)
3058 continue;
3059 caps = snd_hda_query_pin_caps(codec, nid);
3060 if (!(caps & AC_PINCAP_OUT))
3061 continue;
3062 dac = alc_auto_look_for_dac(codec, nid);
3063 if (!dac)
3064 continue;
3065 spec->multi_io[num_pins].pin = nid;
3066 spec->multi_io[num_pins].dac = dac;
3067 num_pins++;
3068 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3069 }
3070 }
3071 spec->multiout.num_dacs = 1;
3072 if (num_pins < 2)
3073 return 0;
3074 return num_pins;
3075}
3076
3077static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
3078 struct snd_ctl_elem_info *uinfo)
3079{
3080 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3081 struct alc_spec *spec = codec->spec;
3082
3083 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3084 uinfo->count = 1;
3085 uinfo->value.enumerated.items = spec->multi_ios + 1;
3086 if (uinfo->value.enumerated.item > spec->multi_ios)
3087 uinfo->value.enumerated.item = spec->multi_ios;
3088 sprintf(uinfo->value.enumerated.name, "%dch",
3089 (uinfo->value.enumerated.item + 1) * 2);
3090 return 0;
3091}
3092
3093static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
3094 struct snd_ctl_elem_value *ucontrol)
3095{
3096 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3097 struct alc_spec *spec = codec->spec;
3098 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
3099 return 0;
3100}
3101
3102static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
3103{
3104 struct alc_spec *spec = codec->spec;
3105 hda_nid_t nid = spec->multi_io[idx].pin;
3106
3107 if (!spec->multi_io[idx].ctl_in)
3108 spec->multi_io[idx].ctl_in =
3109 snd_hda_codec_read(codec, nid, 0,
3110 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3111 if (output) {
3112 snd_hda_codec_update_cache(codec, nid, 0,
3113 AC_VERB_SET_PIN_WIDGET_CONTROL,
3114 PIN_OUT);
3115 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3116 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3117 HDA_AMP_MUTE, 0);
3118 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
3119 } else {
3120 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3121 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3122 HDA_AMP_MUTE, HDA_AMP_MUTE);
3123 snd_hda_codec_update_cache(codec, nid, 0,
3124 AC_VERB_SET_PIN_WIDGET_CONTROL,
3125 spec->multi_io[idx].ctl_in);
3126 }
3127 return 0;
3128}
3129
3130static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
3131 struct snd_ctl_elem_value *ucontrol)
3132{
3133 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3134 struct alc_spec *spec = codec->spec;
3135 int i, ch;
3136
3137 ch = ucontrol->value.enumerated.item[0];
3138 if (ch < 0 || ch > spec->multi_ios)
3139 return -EINVAL;
3140 if (ch == (spec->ext_channel_count - 1) / 2)
3141 return 0;
3142 spec->ext_channel_count = (ch + 1) * 2;
3143 for (i = 0; i < spec->multi_ios; i++)
3144 alc_set_multi_io(codec, i, i < ch);
3145 spec->multiout.max_channels = spec->ext_channel_count;
5677 return 1; 3146 return 1;
5678} 3147}
5679 3148
5680/* additional initialization for auto-configuration model */ 3149static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
5681static void alc880_auto_init(struct hda_codec *codec) 3150 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3151 .name = "Channel Mode",
3152 .info = alc_auto_ch_mode_info,
3153 .get = alc_auto_ch_mode_get,
3154 .put = alc_auto_ch_mode_put,
3155};
3156
3157static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
3158 int (*fill_dac)(struct hda_codec *))
5682{ 3159{
5683 struct alc_spec *spec = codec->spec; 3160 struct alc_spec *spec = codec->spec;
5684 alc_auto_init_multi_out(codec); 3161 struct auto_pin_cfg *cfg = &spec->autocfg;
5685 alc_auto_init_extra_out(codec); 3162 unsigned int location, defcfg;
5686 alc_auto_init_analog_input(codec); 3163 int num_pins;
5687 alc_auto_init_input_src(codec); 3164
5688 alc_auto_init_digital(codec); 3165 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
5689 if (spec->unsol_event) 3166 /* use HP as primary out */
5690 alc_inithook(codec); 3167 cfg->speaker_outs = cfg->line_outs;
3168 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3169 sizeof(cfg->speaker_pins));
3170 cfg->line_outs = cfg->hp_outs;
3171 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
3172 cfg->hp_outs = 0;
3173 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3174 cfg->line_out_type = AUTO_PIN_HP_OUT;
3175 if (fill_dac)
3176 fill_dac(codec);
3177 }
3178 if (cfg->line_outs != 1 ||
3179 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
3180 return 0;
3181
3182 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
3183 location = get_defcfg_location(defcfg);
3184
3185 num_pins = alc_auto_fill_multi_ios(codec, location);
3186 if (num_pins > 0) {
3187 struct snd_kcontrol_new *knew;
3188
3189 knew = alc_kcontrol_new(spec);
3190 if (!knew)
3191 return -ENOMEM;
3192 *knew = alc_auto_channel_mode_enum;
3193 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
3194 if (!knew->name)
3195 return -ENOMEM;
3196
3197 spec->multi_ios = num_pins;
3198 spec->ext_channel_count = 2;
3199 spec->multiout.num_dacs = num_pins + 1;
3200 }
3201 return 0;
3202}
3203
3204/* filter out invalid adc_nids (and capsrc_nids) that don't give all
3205 * active input pins
3206 */
3207static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
3208{
3209 struct alc_spec *spec = codec->spec;
3210 const struct hda_input_mux *imux;
3211 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3212 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3213 int i, n, nums;
3214
3215 imux = spec->input_mux;
3216 if (!imux)
3217 return;
3218 if (spec->dyn_adc_switch)
3219 return;
3220
3221 nums = 0;
3222 for (n = 0; n < spec->num_adc_nids; n++) {
3223 hda_nid_t cap = spec->private_capsrc_nids[n];
3224 int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
3225 for (i = 0; i < imux->num_items; i++) {
3226 hda_nid_t pin = spec->imux_pins[i];
3227 if (pin) {
3228 if (get_connection_index(codec, cap, pin) < 0)
3229 break;
3230 } else if (num_conns <= imux->items[i].index)
3231 break;
3232 }
3233 if (i >= imux->num_items) {
3234 adc_nids[nums] = spec->private_adc_nids[n];
3235 capsrc_nids[nums++] = cap;
3236 }
3237 }
3238 if (!nums) {
3239 /* check whether ADC-switch is possible */
3240 if (!alc_check_dyn_adc_switch(codec)) {
3241 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
3242 " using fallback 0x%x\n",
3243 codec->chip_name, spec->private_adc_nids[0]);
3244 spec->num_adc_nids = 1;
3245 spec->auto_mic = 0;
3246 return;
3247 }
3248 } else if (nums != spec->num_adc_nids) {
3249 memcpy(spec->private_adc_nids, adc_nids,
3250 nums * sizeof(hda_nid_t));
3251 memcpy(spec->private_capsrc_nids, capsrc_nids,
3252 nums * sizeof(hda_nid_t));
3253 spec->num_adc_nids = nums;
3254 }
3255
3256 if (spec->auto_mic)
3257 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
3258 else if (spec->input_mux->num_items == 1)
3259 spec->num_adc_nids = 1; /* reduce to a single ADC */
3260}
3261
3262/*
3263 * initialize ADC paths
3264 */
3265static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
3266{
3267 struct alc_spec *spec = codec->spec;
3268 hda_nid_t nid;
3269
3270 nid = spec->adc_nids[adc_idx];
3271 /* mute ADC */
3272 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) {
3273 snd_hda_codec_write(codec, nid, 0,
3274 AC_VERB_SET_AMP_GAIN_MUTE,
3275 AMP_IN_MUTE(0));
3276 return;
3277 }
3278 if (!spec->capsrc_nids)
3279 return;
3280 nid = spec->capsrc_nids[adc_idx];
3281 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3282 snd_hda_codec_write(codec, nid, 0,
3283 AC_VERB_SET_AMP_GAIN_MUTE,
3284 AMP_OUT_MUTE);
3285}
3286
3287static void alc_auto_init_input_src(struct hda_codec *codec)
3288{
3289 struct alc_spec *spec = codec->spec;
3290 int c, nums;
3291
3292 for (c = 0; c < spec->num_adc_nids; c++)
3293 alc_auto_init_adc(codec, c);
3294 if (spec->dyn_adc_switch)
3295 nums = 1;
3296 else
3297 nums = spec->num_adc_nids;
3298 for (c = 0; c < nums; c++)
3299 alc_mux_select(codec, 0, spec->cur_mux[c], true);
3300}
3301
3302/* add mic boosts if needed */
3303static int alc_auto_add_mic_boost(struct hda_codec *codec)
3304{
3305 struct alc_spec *spec = codec->spec;
3306 struct auto_pin_cfg *cfg = &spec->autocfg;
3307 int i, err;
3308 int type_idx = 0;
3309 hda_nid_t nid;
3310 const char *prev_label = NULL;
3311
3312 for (i = 0; i < cfg->num_inputs; i++) {
3313 if (cfg->inputs[i].type > AUTO_PIN_MIC)
3314 break;
3315 nid = cfg->inputs[i].pin;
3316 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
3317 const char *label;
3318 char boost_label[32];
3319
3320 label = hda_get_autocfg_input_label(codec, cfg, i);
3321 if (prev_label && !strcmp(label, prev_label))
3322 type_idx++;
3323 else
3324 type_idx = 0;
3325 prev_label = label;
3326
3327 snprintf(boost_label, sizeof(boost_label),
3328 "%s Boost Volume", label);
3329 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3330 boost_label, type_idx,
3331 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
3332 if (err < 0)
3333 return err;
3334 }
3335 }
3336 return 0;
5691} 3337}
5692 3338
5693/* select or unmute the given capsrc route */ 3339/* select or unmute the given capsrc route */
@@ -5735,6 +3381,7 @@ static void alc_init_special_input_src(struct hda_codec *codec)
5735 init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin); 3381 init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
5736} 3382}
5737 3383
3384/* assign appropriate capture mixers */
5738static void set_capture_mixer(struct hda_codec *codec) 3385static void set_capture_mixer(struct hda_codec *codec)
5739{ 3386{
5740 struct alc_spec *spec = codec->spec; 3387 struct alc_spec *spec = codec->spec;
@@ -5780,106 +3427,9 @@ static void set_capture_mixer(struct hda_codec *codec)
5780 } 3427 }
5781} 3428}
5782 3429
5783/* check whether dynamic ADC-switching is available */ 3430/*
5784static bool alc_check_dyn_adc_switch(struct hda_codec *codec) 3431 * Digital-beep handlers
5785{
5786 struct alc_spec *spec = codec->spec;
5787 struct hda_input_mux *imux = &spec->private_imux[0];
5788 int i, n, idx;
5789 hda_nid_t cap, pin;
5790
5791 if (imux != spec->input_mux) /* no dynamic imux? */
5792 return false;
5793
5794 for (n = 0; n < spec->num_adc_nids; n++) {
5795 cap = spec->private_capsrc_nids[n];
5796 for (i = 0; i < imux->num_items; i++) {
5797 pin = spec->imux_pins[i];
5798 if (!pin)
5799 return false;
5800 if (get_connection_index(codec, cap, pin) < 0)
5801 break;
5802 }
5803 if (i >= imux->num_items)
5804 return false; /* no ADC-switch is needed */
5805 }
5806
5807 for (i = 0; i < imux->num_items; i++) {
5808 pin = spec->imux_pins[i];
5809 for (n = 0; n < spec->num_adc_nids; n++) {
5810 cap = spec->private_capsrc_nids[n];
5811 idx = get_connection_index(codec, cap, pin);
5812 if (idx >= 0) {
5813 imux->items[i].index = idx;
5814 spec->dyn_adc_idx[i] = n;
5815 break;
5816 }
5817 }
5818 }
5819
5820 snd_printdd("realtek: enabling ADC switching\n");
5821 spec->dyn_adc_switch = 1;
5822 return true;
5823}
5824
5825/* filter out invalid adc_nids (and capsrc_nids) that don't give all
5826 * active input pins
5827 */ 3432 */
5828static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
5829{
5830 struct alc_spec *spec = codec->spec;
5831 const struct hda_input_mux *imux;
5832 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5833 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5834 int i, n, nums;
5835
5836 imux = spec->input_mux;
5837 if (!imux)
5838 return;
5839 if (spec->dyn_adc_switch)
5840 return;
5841
5842 nums = 0;
5843 for (n = 0; n < spec->num_adc_nids; n++) {
5844 hda_nid_t cap = spec->private_capsrc_nids[n];
5845 int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
5846 for (i = 0; i < imux->num_items; i++) {
5847 hda_nid_t pin = spec->imux_pins[i];
5848 if (pin) {
5849 if (get_connection_index(codec, cap, pin) < 0)
5850 break;
5851 } else if (num_conns <= imux->items[i].index)
5852 break;
5853 }
5854 if (i >= imux->num_items) {
5855 adc_nids[nums] = spec->private_adc_nids[n];
5856 capsrc_nids[nums++] = cap;
5857 }
5858 }
5859 if (!nums) {
5860 /* check whether ADC-switch is possible */
5861 if (!alc_check_dyn_adc_switch(codec)) {
5862 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5863 " using fallback 0x%x\n",
5864 codec->chip_name, spec->private_adc_nids[0]);
5865 spec->num_adc_nids = 1;
5866 spec->auto_mic = 0;
5867 return;
5868 }
5869 } else if (nums != spec->num_adc_nids) {
5870 memcpy(spec->private_adc_nids, adc_nids,
5871 nums * sizeof(hda_nid_t));
5872 memcpy(spec->private_capsrc_nids, capsrc_nids,
5873 nums * sizeof(hda_nid_t));
5874 spec->num_adc_nids = nums;
5875 }
5876
5877 if (spec->auto_mic)
5878 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
5879 else if (spec->input_mux->num_items == 1)
5880 spec->num_adc_nids = 1; /* reduce to a single ADC */
5881}
5882
5883#ifdef CONFIG_SND_HDA_INPUT_BEEP 3433#ifdef CONFIG_SND_HDA_INPUT_BEEP
5884#define set_beep_amp(spec, nid, idx, dir) \ 3434#define set_beep_amp(spec, nid, idx, dir) \
5885 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 3435 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -5907,9 +3457,102 @@ static inline int has_cdefine_beep(struct hda_codec *codec)
5907#define has_cdefine_beep(codec) 0 3457#define has_cdefine_beep(codec) 0
5908#endif 3458#endif
5909 3459
3460/* parse the BIOS configuration and set up the alc_spec */
3461/* return 1 if successful, 0 if the proper config is not found,
3462 * or a negative error code
3463 */
3464static int alc880_parse_auto_config(struct hda_codec *codec)
3465{
3466 struct alc_spec *spec = codec->spec;
3467 int err;
3468 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3469
3470 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3471 alc880_ignore);
3472 if (err < 0)
3473 return err;
3474 if (!spec->autocfg.line_outs)
3475 return 0; /* can't find valid BIOS pin config */
3476
3477 err = alc_auto_fill_dac_nids(codec);
3478 if (err < 0)
3479 return err;
3480 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
3481 if (err < 0)
3482 return err;
3483 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
3484 if (err < 0)
3485 return err;
3486 err = alc_auto_create_hp_out(codec);
3487 if (err < 0)
3488 return err;
3489 err = alc_auto_create_speaker_out(codec);
3490 if (err < 0)
3491 return err;
3492 err = alc_auto_create_input_ctls(codec);
3493 if (err < 0)
3494 return err;
3495
3496 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3497
3498 alc_auto_parse_digital(codec);
3499
3500 if (spec->kctls.list)
3501 add_mixer(spec, spec->kctls.list);
3502
3503 alc_remove_invalid_adc_nids(codec);
3504
3505 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
3506 alc_auto_check_switches(codec);
3507
3508 return 1;
3509}
3510
3511/* additional initialization for auto-configuration model */
3512static void alc880_auto_init(struct hda_codec *codec)
3513{
3514 struct alc_spec *spec = codec->spec;
3515 alc_auto_init_multi_out(codec);
3516 alc_auto_init_extra_out(codec);
3517 alc_auto_init_analog_input(codec);
3518 alc_auto_init_input_src(codec);
3519 alc_auto_init_digital(codec);
3520 if (spec->unsol_event)
3521 alc_inithook(codec);
3522}
3523
3524#ifdef CONFIG_SND_HDA_POWER_SAVE
3525static const struct hda_amp_list alc880_loopbacks[] = {
3526 { 0x0b, HDA_INPUT, 0 },
3527 { 0x0b, HDA_INPUT, 1 },
3528 { 0x0b, HDA_INPUT, 2 },
3529 { 0x0b, HDA_INPUT, 3 },
3530 { 0x0b, HDA_INPUT, 4 },
3531 { } /* end */
3532};
3533#endif
3534
3535/*
3536 * board setups
3537 */
3538#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3539#define alc_board_config \
3540 snd_hda_check_board_config
3541#define alc_board_codec_sid_config \
3542 snd_hda_check_board_codec_sid_config
3543#include "alc_quirks.c"
3544#else
3545#define alc_board_config(codec, nums, models, tbl) -1
3546#define alc_board_codec_sid_config(codec, nums, models, tbl) -1
3547#define setup_preset(codec, x) /* NOP */
3548#endif
3549
5910/* 3550/*
5911 * OK, here we have finally the patch for ALC880 3551 * OK, here we have finally the patch for ALC880
5912 */ 3552 */
3553#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3554#include "alc880_quirks.c"
3555#endif
5913 3556
5914static int patch_alc880(struct hda_codec *codec) 3557static int patch_alc880(struct hda_codec *codec)
5915{ 3558{
@@ -5925,27 +3568,29 @@ static int patch_alc880(struct hda_codec *codec)
5925 3568
5926 spec->mixer_nid = 0x0b; 3569 spec->mixer_nid = 0x0b;
5927 3570
5928 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 3571 board_config = alc_board_config(codec, ALC880_MODEL_LAST,
5929 alc880_models, 3572 alc880_models, alc880_cfg_tbl);
5930 alc880_cfg_tbl);
5931 if (board_config < 0) { 3573 if (board_config < 0) {
5932 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3574 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5933 codec->chip_name); 3575 codec->chip_name);
5934 board_config = ALC880_AUTO; 3576 board_config = ALC_MODEL_AUTO;
5935 } 3577 }
5936 3578
5937 if (board_config == ALC880_AUTO) { 3579 if (board_config == ALC_MODEL_AUTO) {
5938 /* automatic parse from the BIOS config */ 3580 /* automatic parse from the BIOS config */
5939 err = alc880_parse_auto_config(codec); 3581 err = alc880_parse_auto_config(codec);
5940 if (err < 0) { 3582 if (err < 0) {
5941 alc_free(codec); 3583 alc_free(codec);
5942 return err; 3584 return err;
5943 } else if (!err) { 3585 }
3586#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3587 else if (!err) {
5944 printk(KERN_INFO 3588 printk(KERN_INFO
5945 "hda_codec: Cannot set up configuration " 3589 "hda_codec: Cannot set up configuration "
5946 "from BIOS. Using 3-stack mode...\n"); 3590 "from BIOS. Using 3-stack mode...\n");
5947 board_config = ALC880_3ST; 3591 board_config = ALC880_3ST;
5948 } 3592 }
3593#endif
5949 } 3594 }
5950 3595
5951 err = snd_hda_attach_beep_device(codec, 0x1); 3596 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -5954,7 +3599,7 @@ static int patch_alc880(struct hda_codec *codec)
5954 return err; 3599 return err;
5955 } 3600 }
5956 3601
5957 if (board_config != ALC880_AUTO) 3602 if (board_config != ALC_MODEL_AUTO)
5958 setup_preset(codec, &alc880_presets[board_config]); 3603 setup_preset(codec, &alc880_presets[board_config]);
5959 3604
5960 if (!spec->adc_nids && spec->input_mux) { 3605 if (!spec->adc_nids && spec->input_mux) {
@@ -5968,7 +3613,7 @@ static int patch_alc880(struct hda_codec *codec)
5968 spec->vmaster_nid = 0x0c; 3613 spec->vmaster_nid = 0x0c;
5969 3614
5970 codec->patch_ops = alc_patch_ops; 3615 codec->patch_ops = alc_patch_ops;
5971 if (board_config == ALC880_AUTO) 3616 if (board_config == ALC_MODEL_AUTO)
5972 spec->init_hook = alc880_auto_init; 3617 spec->init_hook = alc880_auto_init;
5973#ifdef CONFIG_SND_HDA_POWER_SAVE 3618#ifdef CONFIG_SND_HDA_POWER_SAVE
5974 if (!spec->loopback.amplist) 3619 if (!spec->loopback.amplist)
@@ -5983,1077 +3628,6 @@ static int patch_alc880(struct hda_codec *codec)
5983 * ALC260 support 3628 * ALC260 support
5984 */ 3629 */
5985 3630
5986static const hda_nid_t alc260_dac_nids[1] = {
5987 /* front */
5988 0x02,
5989};
5990
5991static const hda_nid_t alc260_adc_nids[1] = {
5992 /* ADC0 */
5993 0x04,
5994};
5995
5996static const hda_nid_t alc260_adc_nids_alt[1] = {
5997 /* ADC1 */
5998 0x05,
5999};
6000
6001/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6002 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6003 */
6004static const hda_nid_t alc260_dual_adc_nids[2] = {
6005 /* ADC0, ADC1 */
6006 0x04, 0x05
6007};
6008
6009#define ALC260_DIGOUT_NID 0x03
6010#define ALC260_DIGIN_NID 0x06
6011
6012static const struct hda_input_mux alc260_capture_source = {
6013 .num_items = 4,
6014 .items = {
6015 { "Mic", 0x0 },
6016 { "Front Mic", 0x1 },
6017 { "Line", 0x2 },
6018 { "CD", 0x4 },
6019 },
6020};
6021
6022/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6023 * headphone jack and the internal CD lines since these are the only pins at
6024 * which audio can appear. For flexibility, also allow the option of
6025 * recording the mixer output on the second ADC (ADC0 doesn't have a
6026 * connection to the mixer output).
6027 */
6028static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6029 {
6030 .num_items = 3,
6031 .items = {
6032 { "Mic/Line", 0x0 },
6033 { "CD", 0x4 },
6034 { "Headphone", 0x2 },
6035 },
6036 },
6037 {
6038 .num_items = 4,
6039 .items = {
6040 { "Mic/Line", 0x0 },
6041 { "CD", 0x4 },
6042 { "Headphone", 0x2 },
6043 { "Mixer", 0x5 },
6044 },
6045 },
6046
6047};
6048
6049/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6050 * the Fujitsu S702x, but jacks are marked differently.
6051 */
6052static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6053 {
6054 .num_items = 4,
6055 .items = {
6056 { "Mic", 0x0 },
6057 { "Line", 0x2 },
6058 { "CD", 0x4 },
6059 { "Headphone", 0x5 },
6060 },
6061 },
6062 {
6063 .num_items = 5,
6064 .items = {
6065 { "Mic", 0x0 },
6066 { "Line", 0x2 },
6067 { "CD", 0x4 },
6068 { "Headphone", 0x6 },
6069 { "Mixer", 0x5 },
6070 },
6071 },
6072};
6073
6074/* Maxdata Favorit 100XS */
6075static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6076 {
6077 .num_items = 2,
6078 .items = {
6079 { "Line/Mic", 0x0 },
6080 { "CD", 0x4 },
6081 },
6082 },
6083 {
6084 .num_items = 3,
6085 .items = {
6086 { "Line/Mic", 0x0 },
6087 { "CD", 0x4 },
6088 { "Mixer", 0x5 },
6089 },
6090 },
6091};
6092
6093/*
6094 * This is just place-holder, so there's something for alc_build_pcms to look
6095 * at when it calculates the maximum number of channels. ALC260 has no mixer
6096 * element which allows changing the channel mode, so the verb list is
6097 * never used.
6098 */
6099static const struct hda_channel_mode alc260_modes[1] = {
6100 { 2, NULL },
6101};
6102
6103
6104/* Mixer combinations
6105 *
6106 * basic: base_output + input + pc_beep + capture
6107 * HP: base_output + input + capture_alt
6108 * HP_3013: hp_3013 + input + capture
6109 * fujitsu: fujitsu + capture
6110 * acer: acer + capture
6111 */
6112
6113static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6114 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6115 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6116 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6117 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6118 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6119 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6120 { } /* end */
6121};
6122
6123static const struct snd_kcontrol_new alc260_input_mixer[] = {
6124 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6125 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6126 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6127 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6129 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6130 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6131 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6132 { } /* end */
6133};
6134
6135/* update HP, line and mono out pins according to the master switch */
6136static void alc260_hp_master_update(struct hda_codec *codec)
6137{
6138 update_speakers(codec);
6139}
6140
6141static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6142 struct snd_ctl_elem_value *ucontrol)
6143{
6144 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6145 struct alc_spec *spec = codec->spec;
6146 *ucontrol->value.integer.value = !spec->master_mute;
6147 return 0;
6148}
6149
6150static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6151 struct snd_ctl_elem_value *ucontrol)
6152{
6153 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6154 struct alc_spec *spec = codec->spec;
6155 int val = !*ucontrol->value.integer.value;
6156
6157 if (val == spec->master_mute)
6158 return 0;
6159 spec->master_mute = val;
6160 alc260_hp_master_update(codec);
6161 return 1;
6162}
6163
6164static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6165 {
6166 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6167 .name = "Master Playback Switch",
6168 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6169 .info = snd_ctl_boolean_mono_info,
6170 .get = alc260_hp_master_sw_get,
6171 .put = alc260_hp_master_sw_put,
6172 },
6173 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6174 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6176 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6177 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6178 HDA_OUTPUT),
6179 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6180 { } /* end */
6181};
6182
6183static const struct hda_verb alc260_hp_unsol_verbs[] = {
6184 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6185 {},
6186};
6187
6188static void alc260_hp_setup(struct hda_codec *codec)
6189{
6190 struct alc_spec *spec = codec->spec;
6191
6192 spec->autocfg.hp_pins[0] = 0x0f;
6193 spec->autocfg.speaker_pins[0] = 0x10;
6194 spec->autocfg.speaker_pins[1] = 0x11;
6195 spec->automute = 1;
6196 spec->automute_mode = ALC_AUTOMUTE_PIN;
6197}
6198
6199static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6200 {
6201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6202 .name = "Master Playback Switch",
6203 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6204 .info = snd_ctl_boolean_mono_info,
6205 .get = alc260_hp_master_sw_get,
6206 .put = alc260_hp_master_sw_put,
6207 },
6208 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6209 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6210 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6211 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6214 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6215 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6216 { } /* end */
6217};
6218
6219static void alc260_hp_3013_setup(struct hda_codec *codec)
6220{
6221 struct alc_spec *spec = codec->spec;
6222
6223 spec->autocfg.hp_pins[0] = 0x15;
6224 spec->autocfg.speaker_pins[0] = 0x10;
6225 spec->autocfg.speaker_pins[1] = 0x11;
6226 spec->automute = 1;
6227 spec->automute_mode = ALC_AUTOMUTE_PIN;
6228}
6229
6230static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6231 .ops = &snd_hda_bind_vol,
6232 .values = {
6233 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6234 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6235 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6236 0
6237 },
6238};
6239
6240static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6241 .ops = &snd_hda_bind_sw,
6242 .values = {
6243 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6244 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6245 0
6246 },
6247};
6248
6249static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6250 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6251 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6252 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6253 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6254 { } /* end */
6255};
6256
6257static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6258 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6259 {},
6260};
6261
6262static void alc260_hp_3012_setup(struct hda_codec *codec)
6263{
6264 struct alc_spec *spec = codec->spec;
6265
6266 spec->autocfg.hp_pins[0] = 0x10;
6267 spec->autocfg.speaker_pins[0] = 0x0f;
6268 spec->autocfg.speaker_pins[1] = 0x11;
6269 spec->autocfg.speaker_pins[2] = 0x15;
6270 spec->automute = 1;
6271 spec->automute_mode = ALC_AUTOMUTE_PIN;
6272}
6273
6274/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6275 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6276 */
6277static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6279 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6280 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6281 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6282 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6283 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6284 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6285 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6286 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6287 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6288 { } /* end */
6289};
6290
6291/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6292 * versions of the ALC260 don't act on requests to enable mic bias from NID
6293 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6294 * datasheet doesn't mention this restriction. At this stage it's not clear
6295 * whether this behaviour is intentional or is a hardware bug in chip
6296 * revisions available in early 2006. Therefore for now allow the
6297 * "Headphone Jack Mode" control to span all choices, but if it turns out
6298 * that the lack of mic bias for this NID is intentional we could change the
6299 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6300 *
6301 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6302 * don't appear to make the mic bias available from the "line" jack, even
6303 * though the NID used for this jack (0x14) can supply it. The theory is
6304 * that perhaps Acer have included blocking capacitors between the ALC260
6305 * and the output jack. If this turns out to be the case for all such
6306 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6307 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6308 *
6309 * The C20x Tablet series have a mono internal speaker which is controlled
6310 * via the chip's Mono sum widget and pin complex, so include the necessary
6311 * controls for such models. On models without a "mono speaker" the control
6312 * won't do anything.
6313 */
6314static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6315 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6316 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6317 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6318 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6319 HDA_OUTPUT),
6320 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6321 HDA_INPUT),
6322 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6323 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6325 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6326 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6327 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6328 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6329 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6330 { } /* end */
6331};
6332
6333/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6334 */
6335static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6336 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6337 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6338 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6339 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6340 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6341 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6342 { } /* end */
6343};
6344
6345/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6346 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6347 */
6348static const struct snd_kcontrol_new alc260_will_mixer[] = {
6349 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6350 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6352 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6353 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6354 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6355 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6356 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6357 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6358 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6359 { } /* end */
6360};
6361
6362/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6363 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6364 */
6365static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6366 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6367 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6369 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6370 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6371 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6372 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6373 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6374 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6375 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6376 { } /* end */
6377};
6378
6379/*
6380 * initialization verbs
6381 */
6382static const struct hda_verb alc260_init_verbs[] = {
6383 /* Line In pin widget for input */
6384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6385 /* CD pin widget for input */
6386 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6387 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6388 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6389 /* Mic2 (front panel) pin widget for input and vref at 80% */
6390 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6391 /* LINE-2 is used for line-out in rear */
6392 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6393 /* select line-out */
6394 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6395 /* LINE-OUT pin */
6396 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6397 /* enable HP */
6398 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6399 /* enable Mono */
6400 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6401 /* mute capture amp left and right */
6402 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6403 /* set connection select to line in (default select for this ADC) */
6404 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6405 /* mute capture amp left and right */
6406 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6407 /* set connection select to line in (default select for this ADC) */
6408 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6409 /* set vol=0 Line-Out mixer amp left and right */
6410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6411 /* unmute pin widget amp left and right (no gain on this amp) */
6412 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6413 /* set vol=0 HP mixer amp left and right */
6414 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6415 /* unmute pin widget amp left and right (no gain on this amp) */
6416 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6417 /* set vol=0 Mono mixer amp left and right */
6418 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6419 /* unmute pin widget amp left and right (no gain on this amp) */
6420 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6421 /* unmute LINE-2 out pin */
6422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6423 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6424 * Line In 2 = 0x03
6425 */
6426 /* mute analog inputs */
6427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6432 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6433 /* mute Front out path */
6434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6435 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6436 /* mute Headphone out path */
6437 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6439 /* mute Mono out path */
6440 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6441 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6442 { }
6443};
6444
6445#if 0 /* should be identical with alc260_init_verbs? */
6446static const struct hda_verb alc260_hp_init_verbs[] = {
6447 /* Headphone and output */
6448 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6449 /* mono output */
6450 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6451 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6453 /* Mic2 (front panel) pin widget for input and vref at 80% */
6454 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6455 /* Line In pin widget for input */
6456 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6457 /* Line-2 pin widget for output */
6458 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6459 /* CD pin widget for input */
6460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6461 /* unmute amp left and right */
6462 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6463 /* set connection select to line in (default select for this ADC) */
6464 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6465 /* unmute Line-Out mixer amp left and right (volume = 0) */
6466 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6467 /* mute pin widget amp left and right (no gain on this amp) */
6468 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6469 /* unmute HP mixer amp left and right (volume = 0) */
6470 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6471 /* mute pin widget amp left and right (no gain on this amp) */
6472 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6473 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6474 * Line In 2 = 0x03
6475 */
6476 /* mute analog inputs */
6477 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6482 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6483 /* Unmute Front out path */
6484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6486 /* Unmute Headphone out path */
6487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6489 /* Unmute Mono out path */
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6492 { }
6493};
6494#endif
6495
6496static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6497 /* Line out and output */
6498 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6499 /* mono output */
6500 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6501 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6502 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6503 /* Mic2 (front panel) pin widget for input and vref at 80% */
6504 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6505 /* Line In pin widget for input */
6506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6507 /* Headphone pin widget for output */
6508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6509 /* CD pin widget for input */
6510 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6511 /* unmute amp left and right */
6512 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6513 /* set connection select to line in (default select for this ADC) */
6514 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6515 /* unmute Line-Out mixer amp left and right (volume = 0) */
6516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6517 /* mute pin widget amp left and right (no gain on this amp) */
6518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6519 /* unmute HP mixer amp left and right (volume = 0) */
6520 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6521 /* mute pin widget amp left and right (no gain on this amp) */
6522 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6523 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6524 * Line In 2 = 0x03
6525 */
6526 /* mute analog inputs */
6527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6532 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6533 /* Unmute Front out path */
6534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6536 /* Unmute Headphone out path */
6537 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6539 /* Unmute Mono out path */
6540 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6541 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6542 { }
6543};
6544
6545/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6546 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6547 * audio = 0x16, internal speaker = 0x10.
6548 */
6549static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6550 /* Disable all GPIOs */
6551 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6552 /* Internal speaker is connected to headphone pin */
6553 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6554 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6555 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6556 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6557 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6558 /* Ensure all other unused pins are disabled and muted. */
6559 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6560 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6561 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6562 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6563 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6564 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6567
6568 /* Disable digital (SPDIF) pins */
6569 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6570 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6571
6572 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6573 * when acting as an output.
6574 */
6575 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6576
6577 /* Start with output sum widgets muted and their output gains at min */
6578 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6581 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6584 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6587
6588 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6589 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6590 /* Unmute Line1 pin widget output buffer since it starts as an output.
6591 * If the pin mode is changed by the user the pin mode control will
6592 * take care of enabling the pin's input/output buffers as needed.
6593 * Therefore there's no need to enable the input buffer at this
6594 * stage.
6595 */
6596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6597 /* Unmute input buffer of pin widget used for Line-in (no equiv
6598 * mixer ctrl)
6599 */
6600 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6601
6602 /* Mute capture amp left and right */
6603 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6604 /* Set ADC connection select to match default mixer setting - line
6605 * in (on mic1 pin)
6606 */
6607 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6608
6609 /* Do the same for the second ADC: mute capture input amp and
6610 * set ADC connection to line in (on mic1 pin)
6611 */
6612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6613 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6614
6615 /* Mute all inputs to mixer widget (even unconnected ones) */
6616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6624
6625 { }
6626};
6627
6628/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6629 * similar laptops (adapted from Fujitsu init verbs).
6630 */
6631static const struct hda_verb alc260_acer_init_verbs[] = {
6632 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6633 * the headphone jack. Turn this on and rely on the standard mute
6634 * methods whenever the user wants to turn these outputs off.
6635 */
6636 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6637 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6638 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6639 /* Internal speaker/Headphone jack is connected to Line-out pin */
6640 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6641 /* Internal microphone/Mic jack is connected to Mic1 pin */
6642 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6643 /* Line In jack is connected to Line1 pin */
6644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6645 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6646 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6647 /* Ensure all other unused pins are disabled and muted. */
6648 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6649 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6650 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6651 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6654 /* Disable digital (SPDIF) pins */
6655 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6656 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6657
6658 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6659 * bus when acting as outputs.
6660 */
6661 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6662 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6663
6664 /* Start with output sum widgets muted and their output gains at min */
6665 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6666 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6668 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6669 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6670 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6671 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6672 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6673 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6674
6675 /* Unmute Line-out pin widget amp left and right
6676 * (no equiv mixer ctrl)
6677 */
6678 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6679 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6680 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6681 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6682 * inputs. If the pin mode is changed by the user the pin mode control
6683 * will take care of enabling the pin's input/output buffers as needed.
6684 * Therefore there's no need to enable the input buffer at this
6685 * stage.
6686 */
6687 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6688 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6689
6690 /* Mute capture amp left and right */
6691 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6692 /* Set ADC connection select to match default mixer setting - mic
6693 * (on mic1 pin)
6694 */
6695 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6696
6697 /* Do similar with the second ADC: mute capture input amp and
6698 * set ADC connection to mic to match ALSA's default state.
6699 */
6700 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6701 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6702
6703 /* Mute all inputs to mixer widget (even unconnected ones) */
6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6709 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6712
6713 { }
6714};
6715
6716/* Initialisation sequence for Maxdata Favorit 100XS
6717 * (adapted from Acer init verbs).
6718 */
6719static const struct hda_verb alc260_favorit100_init_verbs[] = {
6720 /* GPIO 0 enables the output jack.
6721 * Turn this on and rely on the standard mute
6722 * methods whenever the user wants to turn these outputs off.
6723 */
6724 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6725 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6726 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6727 /* Line/Mic input jack is connected to Mic1 pin */
6728 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6729 /* Ensure all other unused pins are disabled and muted. */
6730 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6731 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6732 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6733 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6734 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6735 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6738 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6739 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6740 /* Disable digital (SPDIF) pins */
6741 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6742 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6743
6744 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6745 * bus when acting as outputs.
6746 */
6747 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6748 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6749
6750 /* Start with output sum widgets muted and their output gains at min */
6751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6753 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6754 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6756 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6757 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6758 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6759 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6760
6761 /* Unmute Line-out pin widget amp left and right
6762 * (no equiv mixer ctrl)
6763 */
6764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6765 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6766 * inputs. If the pin mode is changed by the user the pin mode control
6767 * will take care of enabling the pin's input/output buffers as needed.
6768 * Therefore there's no need to enable the input buffer at this
6769 * stage.
6770 */
6771 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772
6773 /* Mute capture amp left and right */
6774 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6775 /* Set ADC connection select to match default mixer setting - mic
6776 * (on mic1 pin)
6777 */
6778 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6779
6780 /* Do similar with the second ADC: mute capture input amp and
6781 * set ADC connection to mic to match ALSA's default state.
6782 */
6783 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6784 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6785
6786 /* Mute all inputs to mixer widget (even unconnected ones) */
6787 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6788 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6794 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6795
6796 { }
6797};
6798
6799static const struct hda_verb alc260_will_verbs[] = {
6800 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6801 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6802 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6803 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6804 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6805 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6806 {}
6807};
6808
6809static const struct hda_verb alc260_replacer_672v_verbs[] = {
6810 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6811 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6812 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6813
6814 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6815 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6816 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6817
6818 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6819 {}
6820};
6821
6822/* toggle speaker-output according to the hp-jack state */
6823static void alc260_replacer_672v_automute(struct hda_codec *codec)
6824{
6825 unsigned int present;
6826
6827 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6828 present = snd_hda_jack_detect(codec, 0x0f);
6829 if (present) {
6830 snd_hda_codec_write_cache(codec, 0x01, 0,
6831 AC_VERB_SET_GPIO_DATA, 1);
6832 snd_hda_codec_write_cache(codec, 0x0f, 0,
6833 AC_VERB_SET_PIN_WIDGET_CONTROL,
6834 PIN_HP);
6835 } else {
6836 snd_hda_codec_write_cache(codec, 0x01, 0,
6837 AC_VERB_SET_GPIO_DATA, 0);
6838 snd_hda_codec_write_cache(codec, 0x0f, 0,
6839 AC_VERB_SET_PIN_WIDGET_CONTROL,
6840 PIN_OUT);
6841 }
6842}
6843
6844static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6845 unsigned int res)
6846{
6847 if ((res >> 26) == ALC880_HP_EVENT)
6848 alc260_replacer_672v_automute(codec);
6849}
6850
6851static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6852 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6854 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6855 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6856 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6858 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6859 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6860 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6862 {}
6863};
6864
6865/* Test configuration for debugging, modelled after the ALC880 test
6866 * configuration.
6867 */
6868#ifdef CONFIG_SND_DEBUG
6869static const hda_nid_t alc260_test_dac_nids[1] = {
6870 0x02,
6871};
6872static const hda_nid_t alc260_test_adc_nids[2] = {
6873 0x04, 0x05,
6874};
6875/* For testing the ALC260, each input MUX needs its own definition since
6876 * the signal assignments are different. This assumes that the first ADC
6877 * is NID 0x04.
6878 */
6879static const struct hda_input_mux alc260_test_capture_sources[2] = {
6880 {
6881 .num_items = 7,
6882 .items = {
6883 { "MIC1 pin", 0x0 },
6884 { "MIC2 pin", 0x1 },
6885 { "LINE1 pin", 0x2 },
6886 { "LINE2 pin", 0x3 },
6887 { "CD pin", 0x4 },
6888 { "LINE-OUT pin", 0x5 },
6889 { "HP-OUT pin", 0x6 },
6890 },
6891 },
6892 {
6893 .num_items = 8,
6894 .items = {
6895 { "MIC1 pin", 0x0 },
6896 { "MIC2 pin", 0x1 },
6897 { "LINE1 pin", 0x2 },
6898 { "LINE2 pin", 0x3 },
6899 { "CD pin", 0x4 },
6900 { "Mixer", 0x5 },
6901 { "LINE-OUT pin", 0x6 },
6902 { "HP-OUT pin", 0x7 },
6903 },
6904 },
6905};
6906static const struct snd_kcontrol_new alc260_test_mixer[] = {
6907 /* Output driver widgets */
6908 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6909 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6910 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6911 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6912 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6913 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6914
6915 /* Modes for retasking pin widgets
6916 * Note: the ALC260 doesn't seem to act on requests to enable mic
6917 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6918 * mention this restriction. At this stage it's not clear whether
6919 * this behaviour is intentional or is a hardware bug in chip
6920 * revisions available at least up until early 2006. Therefore for
6921 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6922 * choices, but if it turns out that the lack of mic bias for these
6923 * NIDs is intentional we could change their modes from
6924 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6925 */
6926 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6927 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6928 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6929 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6930 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6931 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6932
6933 /* Loopback mixer controls */
6934 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6935 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6936 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6937 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6938 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6939 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6940 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6941 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6942 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6943 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6944 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6945 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6946 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6947 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6948
6949 /* Controls for GPIO pins, assuming they are configured as outputs */
6950 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6951 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6952 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6953 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6954
6955 /* Switches to allow the digital IO pins to be enabled. The datasheet
6956 * is ambigious as to which NID is which; testing on laptops which
6957 * make this output available should provide clarification.
6958 */
6959 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6960 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6961
6962 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6963 * this output to turn on an external amplifier.
6964 */
6965 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6966 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6967
6968 { } /* end */
6969};
6970static const struct hda_verb alc260_test_init_verbs[] = {
6971 /* Enable all GPIOs as outputs with an initial value of 0 */
6972 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6973 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6974 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6975
6976 /* Enable retasking pins as output, initially without power amp */
6977 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6978 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6981 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6982 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6983
6984 /* Disable digital (SPDIF) pins initially, but users can enable
6985 * them via a mixer switch. In the case of SPDIF-out, this initverb
6986 * payload also sets the generation to 0, output to be in "consumer"
6987 * PCM format, copyright asserted, no pre-emphasis and no validity
6988 * control.
6989 */
6990 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6991 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6992
6993 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6994 * OUT1 sum bus when acting as an output.
6995 */
6996 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6997 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6998 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6999 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7000
7001 /* Start with output sum widgets muted and their output gains at min */
7002 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7003 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7004 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7005 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7006 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7008 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7009 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7010 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7011
7012 /* Unmute retasking pin widget output buffers since the default
7013 * state appears to be output. As the pin mode is changed by the
7014 * user the pin mode control will take care of enabling the pin's
7015 * input/output buffers as needed.
7016 */
7017 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7018 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7020 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7021 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7022 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7023 /* Also unmute the mono-out pin widget */
7024 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7025
7026 /* Mute capture amp left and right */
7027 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7028 /* Set ADC connection select to match default mixer setting (mic1
7029 * pin)
7030 */
7031 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7032
7033 /* Do the same for the second ADC: mute capture input amp and
7034 * set ADC connection to mic1 pin
7035 */
7036 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7037 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7038
7039 /* Mute all inputs to mixer widget (even unconnected ones) */
7040 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7041 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7042 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7043 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7044 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7046 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7048
7049 { }
7050};
7051#endif
7052
7053/*
7054 * for BIOS auto-configuration
7055 */
7056
7057/* convert from pin to volume-mixer widget */ 3631/* convert from pin to volume-mixer widget */
7058static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid) 3632static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7059{ 3633{
@@ -7259,186 +3833,10 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7259}; 3833};
7260 3834
7261/* 3835/*
7262 * ALC260 configurations
7263 */ 3836 */
7264static const char * const alc260_models[ALC260_MODEL_LAST] = { 3837#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
7265 [ALC260_BASIC] = "basic", 3838#include "alc260_quirks.c"
7266 [ALC260_HP] = "hp",
7267 [ALC260_HP_3013] = "hp-3013",
7268 [ALC260_HP_DC7600] = "hp-dc7600",
7269 [ALC260_FUJITSU_S702X] = "fujitsu",
7270 [ALC260_ACER] = "acer",
7271 [ALC260_WILL] = "will",
7272 [ALC260_REPLACER_672V] = "replacer",
7273 [ALC260_FAVORIT100] = "favorit100",
7274#ifdef CONFIG_SND_DEBUG
7275 [ALC260_TEST] = "test",
7276#endif 3839#endif
7277 [ALC260_AUTO] = "auto",
7278};
7279
7280static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7281 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7282 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7283 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7284 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7285 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7286 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7287 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7288 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7289 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7290 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7291 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7292 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7293 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7294 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7295 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7296 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7297 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7298 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7299 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7300 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7301 {}
7302};
7303
7304static const struct alc_config_preset alc260_presets[] = {
7305 [ALC260_BASIC] = {
7306 .mixers = { alc260_base_output_mixer,
7307 alc260_input_mixer },
7308 .init_verbs = { alc260_init_verbs },
7309 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7310 .dac_nids = alc260_dac_nids,
7311 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7312 .adc_nids = alc260_dual_adc_nids,
7313 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7314 .channel_mode = alc260_modes,
7315 .input_mux = &alc260_capture_source,
7316 },
7317 [ALC260_HP] = {
7318 .mixers = { alc260_hp_output_mixer,
7319 alc260_input_mixer },
7320 .init_verbs = { alc260_init_verbs,
7321 alc260_hp_unsol_verbs },
7322 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7323 .dac_nids = alc260_dac_nids,
7324 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7325 .adc_nids = alc260_adc_nids_alt,
7326 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7327 .channel_mode = alc260_modes,
7328 .input_mux = &alc260_capture_source,
7329 .unsol_event = alc_sku_unsol_event,
7330 .setup = alc260_hp_setup,
7331 .init_hook = alc_inithook,
7332 },
7333 [ALC260_HP_DC7600] = {
7334 .mixers = { alc260_hp_dc7600_mixer,
7335 alc260_input_mixer },
7336 .init_verbs = { alc260_init_verbs,
7337 alc260_hp_dc7600_verbs },
7338 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7339 .dac_nids = alc260_dac_nids,
7340 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7341 .adc_nids = alc260_adc_nids_alt,
7342 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7343 .channel_mode = alc260_modes,
7344 .input_mux = &alc260_capture_source,
7345 .unsol_event = alc_sku_unsol_event,
7346 .setup = alc260_hp_3012_setup,
7347 .init_hook = alc_inithook,
7348 },
7349 [ALC260_HP_3013] = {
7350 .mixers = { alc260_hp_3013_mixer,
7351 alc260_input_mixer },
7352 .init_verbs = { alc260_hp_3013_init_verbs,
7353 alc260_hp_3013_unsol_verbs },
7354 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7355 .dac_nids = alc260_dac_nids,
7356 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7357 .adc_nids = alc260_adc_nids_alt,
7358 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7359 .channel_mode = alc260_modes,
7360 .input_mux = &alc260_capture_source,
7361 .unsol_event = alc_sku_unsol_event,
7362 .setup = alc260_hp_3013_setup,
7363 .init_hook = alc_inithook,
7364 },
7365 [ALC260_FUJITSU_S702X] = {
7366 .mixers = { alc260_fujitsu_mixer },
7367 .init_verbs = { alc260_fujitsu_init_verbs },
7368 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7369 .dac_nids = alc260_dac_nids,
7370 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7371 .adc_nids = alc260_dual_adc_nids,
7372 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7373 .channel_mode = alc260_modes,
7374 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7375 .input_mux = alc260_fujitsu_capture_sources,
7376 },
7377 [ALC260_ACER] = {
7378 .mixers = { alc260_acer_mixer },
7379 .init_verbs = { alc260_acer_init_verbs },
7380 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7381 .dac_nids = alc260_dac_nids,
7382 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7383 .adc_nids = alc260_dual_adc_nids,
7384 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7385 .channel_mode = alc260_modes,
7386 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7387 .input_mux = alc260_acer_capture_sources,
7388 },
7389 [ALC260_FAVORIT100] = {
7390 .mixers = { alc260_favorit100_mixer },
7391 .init_verbs = { alc260_favorit100_init_verbs },
7392 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7393 .dac_nids = alc260_dac_nids,
7394 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7395 .adc_nids = alc260_dual_adc_nids,
7396 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7397 .channel_mode = alc260_modes,
7398 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7399 .input_mux = alc260_favorit100_capture_sources,
7400 },
7401 [ALC260_WILL] = {
7402 .mixers = { alc260_will_mixer },
7403 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7404 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7405 .dac_nids = alc260_dac_nids,
7406 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7407 .adc_nids = alc260_adc_nids,
7408 .dig_out_nid = ALC260_DIGOUT_NID,
7409 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7410 .channel_mode = alc260_modes,
7411 .input_mux = &alc260_capture_source,
7412 },
7413 [ALC260_REPLACER_672V] = {
7414 .mixers = { alc260_replacer_672v_mixer },
7415 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7416 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7417 .dac_nids = alc260_dac_nids,
7418 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7419 .adc_nids = alc260_adc_nids,
7420 .dig_out_nid = ALC260_DIGOUT_NID,
7421 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7422 .channel_mode = alc260_modes,
7423 .input_mux = &alc260_capture_source,
7424 .unsol_event = alc260_replacer_672v_unsol_event,
7425 .init_hook = alc260_replacer_672v_automute,
7426 },
7427#ifdef CONFIG_SND_DEBUG
7428 [ALC260_TEST] = {
7429 .mixers = { alc260_test_mixer },
7430 .init_verbs = { alc260_test_init_verbs },
7431 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7432 .dac_nids = alc260_test_dac_nids,
7433 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7434 .adc_nids = alc260_test_adc_nids,
7435 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7436 .channel_mode = alc260_modes,
7437 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7438 .input_mux = alc260_test_capture_sources,
7439 },
7440#endif
7441};
7442 3840
7443static int patch_alc260(struct hda_codec *codec) 3841static int patch_alc260(struct hda_codec *codec)
7444{ 3842{
@@ -7453,32 +3851,34 @@ static int patch_alc260(struct hda_codec *codec)
7453 3851
7454 spec->mixer_nid = 0x07; 3852 spec->mixer_nid = 0x07;
7455 3853
7456 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 3854 board_config = alc_board_config(codec, ALC260_MODEL_LAST,
7457 alc260_models, 3855 alc260_models, alc260_cfg_tbl);
7458 alc260_cfg_tbl);
7459 if (board_config < 0) { 3856 if (board_config < 0) {
7460 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3857 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7461 codec->chip_name); 3858 codec->chip_name);
7462 board_config = ALC260_AUTO; 3859 board_config = ALC_MODEL_AUTO;
7463 } 3860 }
7464 3861
7465 if (board_config == ALC260_AUTO) { 3862 if (board_config == ALC_MODEL_AUTO) {
7466 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); 3863 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7467 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 3864 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7468 } 3865 }
7469 3866
7470 if (board_config == ALC260_AUTO) { 3867 if (board_config == ALC_MODEL_AUTO) {
7471 /* automatic parse from the BIOS config */ 3868 /* automatic parse from the BIOS config */
7472 err = alc260_parse_auto_config(codec); 3869 err = alc260_parse_auto_config(codec);
7473 if (err < 0) { 3870 if (err < 0) {
7474 alc_free(codec); 3871 alc_free(codec);
7475 return err; 3872 return err;
7476 } else if (!err) { 3873 }
3874#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3875 else if (!err) {
7477 printk(KERN_INFO 3876 printk(KERN_INFO
7478 "hda_codec: Cannot set up configuration " 3877 "hda_codec: Cannot set up configuration "
7479 "from BIOS. Using base mode...\n"); 3878 "from BIOS. Using base mode...\n");
7480 board_config = ALC260_BASIC; 3879 board_config = ALC260_BASIC;
7481 } 3880 }
3881#endif
7482 } 3882 }
7483 3883
7484 err = snd_hda_attach_beep_device(codec, 0x1); 3884 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -7487,7 +3887,7 @@ static int patch_alc260(struct hda_codec *codec)
7487 return err; 3887 return err;
7488 } 3888 }
7489 3889
7490 if (board_config != ALC260_AUTO) 3890 if (board_config != ALC_MODEL_AUTO)
7491 setup_preset(codec, &alc260_presets[board_config]); 3891 setup_preset(codec, &alc260_presets[board_config]);
7492 3892
7493 if (!spec->adc_nids && spec->input_mux) { 3893 if (!spec->adc_nids && spec->input_mux) {
@@ -7503,7 +3903,7 @@ static int patch_alc260(struct hda_codec *codec)
7503 spec->vmaster_nid = 0x08; 3903 spec->vmaster_nid = 0x08;
7504 3904
7505 codec->patch_ops = alc_patch_ops; 3905 codec->patch_ops = alc_patch_ops;
7506 if (board_config == ALC260_AUTO) 3906 if (board_config == ALC_MODEL_AUTO)
7507 spec->init_hook = alc260_auto_init; 3907 spec->init_hook = alc260_auto_init;
7508 spec->shutup = alc_eapd_shutup; 3908 spec->shutup = alc_eapd_shutup;
7509#ifdef CONFIG_SND_HDA_POWER_SAVE 3909#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -7526,3249 +3926,10 @@ static int patch_alc260(struct hda_codec *codec)
7526 * In addition, an independent DAC for the multi-playback (not used in this 3926 * In addition, an independent DAC for the multi-playback (not used in this
7527 * driver yet). 3927 * driver yet).
7528 */ 3928 */
7529#define ALC882_DIGOUT_NID 0x06
7530#define ALC882_DIGIN_NID 0x0a
7531#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7532#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7533#define ALC1200_DIGOUT_NID 0x10
7534
7535
7536static const struct hda_channel_mode alc882_ch_modes[1] = {
7537 { 8, NULL }
7538};
7539
7540/* DACs */
7541static const hda_nid_t alc882_dac_nids[4] = {
7542 /* front, rear, clfe, rear_surr */
7543 0x02, 0x03, 0x04, 0x05
7544};
7545#define alc883_dac_nids alc882_dac_nids
7546
7547/* ADCs */
7548#define alc882_adc_nids alc880_adc_nids
7549#define alc882_adc_nids_alt alc880_adc_nids_alt
7550#define alc883_adc_nids alc882_adc_nids_alt
7551static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7552static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7553#define alc889_adc_nids alc880_adc_nids
7554
7555static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7556static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7557#define alc883_capsrc_nids alc882_capsrc_nids_alt
7558static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7559#define alc889_capsrc_nids alc882_capsrc_nids
7560
7561/* input MUX */
7562/* FIXME: should be a matrix-type input source selection */
7563
7564static const struct hda_input_mux alc882_capture_source = {
7565 .num_items = 4,
7566 .items = {
7567 { "Mic", 0x0 },
7568 { "Front Mic", 0x1 },
7569 { "Line", 0x2 },
7570 { "CD", 0x4 },
7571 },
7572};
7573
7574#define alc883_capture_source alc882_capture_source
7575
7576static const struct hda_input_mux alc889_capture_source = {
7577 .num_items = 3,
7578 .items = {
7579 { "Front Mic", 0x0 },
7580 { "Mic", 0x3 },
7581 { "Line", 0x2 },
7582 },
7583};
7584
7585static const struct hda_input_mux mb5_capture_source = {
7586 .num_items = 3,
7587 .items = {
7588 { "Mic", 0x1 },
7589 { "Line", 0x7 },
7590 { "CD", 0x4 },
7591 },
7592};
7593
7594static const struct hda_input_mux macmini3_capture_source = {
7595 .num_items = 2,
7596 .items = {
7597 { "Line", 0x2 },
7598 { "CD", 0x4 },
7599 },
7600};
7601
7602static const struct hda_input_mux alc883_3stack_6ch_intel = {
7603 .num_items = 4,
7604 .items = {
7605 { "Mic", 0x1 },
7606 { "Front Mic", 0x0 },
7607 { "Line", 0x2 },
7608 { "CD", 0x4 },
7609 },
7610};
7611
7612static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7613 .num_items = 2,
7614 .items = {
7615 { "Mic", 0x1 },
7616 { "Line", 0x2 },
7617 },
7618};
7619
7620static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7621 .num_items = 4,
7622 .items = {
7623 { "Mic", 0x0 },
7624 { "Internal Mic", 0x1 },
7625 { "Line", 0x2 },
7626 { "CD", 0x4 },
7627 },
7628};
7629
7630static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7631 .num_items = 2,
7632 .items = {
7633 { "Mic", 0x0 },
7634 { "Internal Mic", 0x1 },
7635 },
7636};
7637
7638static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7639 .num_items = 3,
7640 .items = {
7641 { "Mic", 0x0 },
7642 { "Front Mic", 0x1 },
7643 { "Line", 0x4 },
7644 },
7645};
7646
7647static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7648 .num_items = 2,
7649 .items = {
7650 { "Mic", 0x0 },
7651 { "Line", 0x2 },
7652 },
7653};
7654
7655static const struct hda_input_mux alc889A_mb31_capture_source = {
7656 .num_items = 2,
7657 .items = {
7658 { "Mic", 0x0 },
7659 /* Front Mic (0x01) unused */
7660 { "Line", 0x2 },
7661 /* Line 2 (0x03) unused */
7662 /* CD (0x04) unused? */
7663 },
7664};
7665
7666static const struct hda_input_mux alc889A_imac91_capture_source = {
7667 .num_items = 2,
7668 .items = {
7669 { "Mic", 0x01 },
7670 { "Line", 0x2 }, /* Not sure! */
7671 },
7672};
7673
7674/*
7675 * 2ch mode
7676 */
7677static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7678 { 2, NULL }
7679};
7680
7681/*
7682 * 2ch mode
7683 */
7684static const struct hda_verb alc882_3ST_ch2_init[] = {
7685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7689 { } /* end */
7690};
7691
7692/*
7693 * 4ch mode
7694 */
7695static const struct hda_verb alc882_3ST_ch4_init[] = {
7696 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7697 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7698 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7699 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7700 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7701 { } /* end */
7702};
7703
7704/*
7705 * 6ch mode
7706 */
7707static const struct hda_verb alc882_3ST_ch6_init[] = {
7708 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7709 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7710 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7711 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7712 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7713 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7714 { } /* end */
7715};
7716
7717static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7718 { 2, alc882_3ST_ch2_init },
7719 { 4, alc882_3ST_ch4_init },
7720 { 6, alc882_3ST_ch6_init },
7721};
7722
7723#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7724
7725/*
7726 * 2ch mode
7727 */
7728static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7729 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7730 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7731 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7732 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7733 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7734 { } /* end */
7735};
7736
7737/*
7738 * 4ch mode
7739 */
7740static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7741 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7743 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7744 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7745 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7746 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7747 { } /* end */
7748};
7749
7750/*
7751 * 6ch mode
7752 */
7753static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7754 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7755 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7756 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7757 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7758 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7759 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7760 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7761 { } /* end */
7762};
7763
7764static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7765 { 2, alc883_3ST_ch2_clevo_init },
7766 { 4, alc883_3ST_ch4_clevo_init },
7767 { 6, alc883_3ST_ch6_clevo_init },
7768};
7769
7770
7771/*
7772 * 6ch mode
7773 */
7774static const struct hda_verb alc882_sixstack_ch6_init[] = {
7775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7776 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7777 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7778 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { } /* end */
7780};
7781
7782/*
7783 * 8ch mode
7784 */
7785static const struct hda_verb alc882_sixstack_ch8_init[] = {
7786 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7787 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7788 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7789 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7790 { } /* end */
7791};
7792
7793static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7794 { 6, alc882_sixstack_ch6_init },
7795 { 8, alc882_sixstack_ch8_init },
7796};
7797
7798
7799/* Macbook Air 2,1 */
7800
7801static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7802 { 2, NULL },
7803};
7804
7805/*
7806 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7807 */
7808
7809/*
7810 * 2ch mode
7811 */
7812static const struct hda_verb alc885_mbp_ch2_init[] = {
7813 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7814 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7815 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7816 { } /* end */
7817};
7818
7819/*
7820 * 4ch mode
7821 */
7822static const struct hda_verb alc885_mbp_ch4_init[] = {
7823 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7824 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7825 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7826 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7827 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7828 { } /* end */
7829};
7830
7831static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7832 { 2, alc885_mbp_ch2_init },
7833 { 4, alc885_mbp_ch4_init },
7834};
7835
7836/*
7837 * 2ch
7838 * Speakers/Woofer/HP = Front
7839 * LineIn = Input
7840 */
7841static const struct hda_verb alc885_mb5_ch2_init[] = {
7842 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7844 { } /* end */
7845};
7846
7847/*
7848 * 6ch mode
7849 * Speakers/HP = Front
7850 * Woofer = LFE
7851 * LineIn = Surround
7852 */
7853static const struct hda_verb alc885_mb5_ch6_init[] = {
7854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7857 { } /* end */
7858};
7859
7860static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7861 { 2, alc885_mb5_ch2_init },
7862 { 6, alc885_mb5_ch6_init },
7863};
7864
7865#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7866
7867/*
7868 * 2ch mode
7869 */
7870static const struct hda_verb alc883_4ST_ch2_init[] = {
7871 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7872 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7875 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7876 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7877 { } /* end */
7878};
7879
7880/*
7881 * 4ch mode
7882 */
7883static const struct hda_verb alc883_4ST_ch4_init[] = {
7884 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7885 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7886 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7887 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7888 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7890 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7891 { } /* end */
7892};
7893
7894/*
7895 * 6ch mode
7896 */
7897static const struct hda_verb alc883_4ST_ch6_init[] = {
7898 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7899 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7900 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7901 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7902 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7903 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7904 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7905 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7906 { } /* end */
7907};
7908
7909/*
7910 * 8ch mode
7911 */
7912static const struct hda_verb alc883_4ST_ch8_init[] = {
7913 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7914 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7915 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7916 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7917 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7918 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7919 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7920 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7921 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7922 { } /* end */
7923};
7924
7925static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7926 { 2, alc883_4ST_ch2_init },
7927 { 4, alc883_4ST_ch4_init },
7928 { 6, alc883_4ST_ch6_init },
7929 { 8, alc883_4ST_ch8_init },
7930};
7931
7932
7933/*
7934 * 2ch mode
7935 */
7936static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
7937 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7938 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7939 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7940 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7941 { } /* end */
7942};
7943
7944/*
7945 * 4ch mode
7946 */
7947static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
7948 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7949 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7950 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7951 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7952 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7953 { } /* end */
7954};
7955
7956/*
7957 * 6ch mode
7958 */
7959static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
7960 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7961 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7962 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7963 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7964 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7965 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7966 { } /* end */
7967};
7968
7969static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7970 { 2, alc883_3ST_ch2_intel_init },
7971 { 4, alc883_3ST_ch4_intel_init },
7972 { 6, alc883_3ST_ch6_intel_init },
7973};
7974
7975/*
7976 * 2ch mode
7977 */
7978static const struct hda_verb alc889_ch2_intel_init[] = {
7979 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7980 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7981 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7982 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7983 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7984 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7985 { } /* end */
7986};
7987
7988/*
7989 * 6ch mode
7990 */
7991static const struct hda_verb alc889_ch6_intel_init[] = {
7992 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7993 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7994 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7995 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7996 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7997 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7998 { } /* end */
7999};
8000
8001/*
8002 * 8ch mode
8003 */
8004static const struct hda_verb alc889_ch8_intel_init[] = {
8005 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8006 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8007 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8008 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8009 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8010 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8011 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8012 { } /* end */
8013};
8014
8015static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8016 { 2, alc889_ch2_intel_init },
8017 { 6, alc889_ch6_intel_init },
8018 { 8, alc889_ch8_intel_init },
8019};
8020
8021/*
8022 * 6ch mode
8023 */
8024static const struct hda_verb alc883_sixstack_ch6_init[] = {
8025 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8026 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8027 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8028 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8029 { } /* end */
8030};
8031
8032/*
8033 * 8ch mode
8034 */
8035static const struct hda_verb alc883_sixstack_ch8_init[] = {
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8038 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8039 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8040 { } /* end */
8041};
8042
8043static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8044 { 6, alc883_sixstack_ch6_init },
8045 { 8, alc883_sixstack_ch8_init },
8046};
8047
8048
8049/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8050 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8051 */
8052static const struct snd_kcontrol_new alc882_base_mixer[] = {
8053 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8055 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8056 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8057 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8058 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8059 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8060 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8061 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8062 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8064 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8065 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8066 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8067 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8069 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8070 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8071 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8072 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8073 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8074 { } /* end */
8075};
8076
8077/* Macbook Air 2,1 same control for HP and internal Speaker */
8078
8079static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8080 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8081 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8082 { }
8083};
8084
8085
8086static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8087 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8088 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8089 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8090 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8091 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8092 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8093 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8094 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8095 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8096 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8097 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8098 { } /* end */
8099};
8100
8101static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8102 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8103 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8104 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8105 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8106 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8107 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8108 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8109 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8111 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8113 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8114 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8116 { } /* end */
8117};
8118
8119static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8120 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8121 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8122 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8123 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8124 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8125 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8126 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8127 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8128 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8129 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8130 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8131 { } /* end */
8132};
8133
8134static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8135 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8136 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8137 { } /* end */
8138};
8139
8140
8141static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8142 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8143 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8144 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8145 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8149 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8151 { } /* end */
8152};
8153
8154static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8155 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8156 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8158 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8159 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8160 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8161 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8164 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8165 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8166 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8167 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8168 { } /* end */
8169};
8170
8171/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8172 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8173 */
8174static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8175 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8176 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8178 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8179 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8180 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8183 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8184 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8186 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8187 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8188 { } /* end */
8189};
8190
8191static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8195 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8196 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8197 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8198 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8200 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8201 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8202 { } /* end */
8203};
8204
8205static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8206 {
8207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8208 .name = "Channel Mode",
8209 .info = alc_ch_mode_info,
8210 .get = alc_ch_mode_get,
8211 .put = alc_ch_mode_put,
8212 },
8213 { } /* end */
8214};
8215
8216static const struct hda_verb alc882_base_init_verbs[] = {
8217 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8220 /* Rear mixer */
8221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8223 /* CLFE mixer */
8224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8226 /* Side mixer */
8227 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8228 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8229
8230 /* Front Pin: output 0 (0x0c) */
8231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8233 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8234 /* Rear Pin: output 1 (0x0d) */
8235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8236 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8237 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8238 /* CLFE Pin: output 2 (0x0e) */
8239 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8240 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8241 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8242 /* Side Pin: output 3 (0x0f) */
8243 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8244 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8245 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8246 /* Mic (rear) pin: input vref at 80% */
8247 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8248 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8249 /* Front Mic pin: input vref at 80% */
8250 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8251 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8252 /* Line In pin: input */
8253 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8255 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8256 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8257 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8258 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8259 /* CD pin widget for input */
8260 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8261
8262 /* FIXME: use matrix-type input source selection */
8263 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8264 /* Input mixer2 */
8265 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8266 /* Input mixer3 */
8267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8268 /* ADC2: mute amp left and right */
8269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8270 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8271 /* ADC3: mute amp left and right */
8272 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8273 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8274
8275 { }
8276};
8277
8278static const struct hda_verb alc882_adc1_init_verbs[] = {
8279 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8280 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8284 /* ADC1: mute amp left and right */
8285 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8286 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8287 { }
8288};
8289
8290static const struct hda_verb alc882_eapd_verbs[] = {
8291 /* change to EAPD mode */
8292 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8293 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8294 { }
8295};
8296
8297static const struct hda_verb alc889_eapd_verbs[] = {
8298 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8299 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8300 { }
8301};
8302
8303static const struct hda_verb alc_hp15_unsol_verbs[] = {
8304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8306 {}
8307};
8308
8309static const struct hda_verb alc885_init_verbs[] = {
8310 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8313 /* Rear mixer */
8314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8316 /* CLFE mixer */
8317 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8318 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8319 /* Side mixer */
8320 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8321 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8322
8323 /* Front HP Pin: output 0 (0x0c) */
8324 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8325 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8326 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8327 /* Front Pin: output 0 (0x0c) */
8328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8329 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8330 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8331 /* Rear Pin: output 1 (0x0d) */
8332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8334 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8335 /* CLFE Pin: output 2 (0x0e) */
8336 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8337 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8338 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8339 /* Side Pin: output 3 (0x0f) */
8340 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8341 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8342 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8343 /* Mic (rear) pin: input vref at 80% */
8344 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8345 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8346 /* Front Mic pin: input vref at 80% */
8347 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8348 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8349 /* Line In pin: input */
8350 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8351 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8352
8353 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8354 /* Input mixer1 */
8355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8356 /* Input mixer2 */
8357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8358 /* Input mixer3 */
8359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8360 /* ADC2: mute amp left and right */
8361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8362 /* ADC3: mute amp left and right */
8363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8364
8365 { }
8366};
8367
8368static const struct hda_verb alc885_init_input_verbs[] = {
8369 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8370 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8371 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8372 { }
8373};
8374
8375
8376/* Unmute Selector 24h and set the default input to front mic */
8377static const struct hda_verb alc889_init_input_verbs[] = {
8378 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8380 { }
8381};
8382
8383
8384#define alc883_init_verbs alc882_base_init_verbs
8385
8386/* Mac Pro test */
8387static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8388 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8389 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8391 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8392 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8393 /* FIXME: this looks suspicious...
8394 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8395 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8396 */
8397 { } /* end */
8398};
8399
8400static const struct hda_verb alc882_macpro_init_verbs[] = {
8401 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8405 /* Front Pin: output 0 (0x0c) */
8406 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8407 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8408 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 /* Front Mic pin: input vref at 80% */
8410 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8411 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8412 /* Speaker: output */
8413 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8414 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8415 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8416 /* Headphone output (output 0 - 0x0c) */
8417 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8418 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8419 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8420
8421 /* FIXME: use matrix-type input source selection */
8422 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8423 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8425 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8428 /* Input mixer2 */
8429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8430 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8431 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8433 /* Input mixer3 */
8434 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8438 /* ADC1: mute amp left and right */
8439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8440 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8441 /* ADC2: mute amp left and right */
8442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8443 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8444 /* ADC3: mute amp left and right */
8445 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8446 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8447
8448 { }
8449};
8450
8451/* Macbook 5,1 */
8452static const struct hda_verb alc885_mb5_init_verbs[] = {
8453 /* DACs */
8454 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8455 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8456 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8457 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8458 /* Front mixer */
8459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8462 /* Surround mixer */
8463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8466 /* LFE mixer */
8467 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8468 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8470 /* HP mixer */
8471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8474 /* Front Pin (0x0c) */
8475 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8476 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8477 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 /* LFE Pin (0x0e) */
8479 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8480 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8482 /* HP Pin (0x0f) */
8483 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8486 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8487 /* Front Mic pin: input vref at 80% */
8488 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8489 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8490 /* Line In pin */
8491 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8493
8494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8497 { }
8498};
8499
8500/* Macmini 3,1 */
8501static const struct hda_verb alc885_macmini3_init_verbs[] = {
8502 /* DACs */
8503 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8504 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8505 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8506 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8507 /* Front mixer */
8508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8511 /* Surround mixer */
8512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8515 /* LFE mixer */
8516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8518 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8519 /* HP mixer */
8520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8522 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8523 /* Front Pin (0x0c) */
8524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8525 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8526 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8527 /* LFE Pin (0x0e) */
8528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8529 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8530 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8531 /* HP Pin (0x0f) */
8532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8535 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8536 /* Line In pin */
8537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8539
8540 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8542 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8544 { }
8545};
8546
8547
8548static const struct hda_verb alc885_mba21_init_verbs[] = {
8549 /*Internal and HP Speaker Mixer*/
8550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8552 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8553 /*Internal Speaker Pin (0x0c)*/
8554 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8555 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8556 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8557 /* HP Pin: output 0 (0x0e) */
8558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8559 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8562 /* Line in (is hp when jack connected)*/
8563 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8564 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8565
8566 { }
8567 };
8568
8569
8570/* Macbook Pro rev3 */
8571static const struct hda_verb alc885_mbp3_init_verbs[] = {
8572 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8574 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8575 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8576 /* Rear mixer */
8577 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8578 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8579 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8580 /* HP mixer */
8581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8582 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8584 /* Front Pin: output 0 (0x0c) */
8585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8587 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8588 /* HP Pin: output 0 (0x0e) */
8589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8593 /* Mic (rear) pin: input vref at 80% */
8594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8596 /* Front Mic pin: input vref at 80% */
8597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8599 /* Line In pin: use output 1 when in LineOut mode */
8600 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8602 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8603
8604 /* FIXME: use matrix-type input source selection */
8605 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8606 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8611 /* Input mixer2 */
8612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8616 /* Input mixer3 */
8617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8621 /* ADC1: mute amp left and right */
8622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8623 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8624 /* ADC2: mute amp left and right */
8625 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8626 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8627 /* ADC3: mute amp left and right */
8628 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8629 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8630
8631 { }
8632};
8633
8634/* iMac 9,1 */
8635static const struct hda_verb alc885_imac91_init_verbs[] = {
8636 /* Internal Speaker Pin (0x0c) */
8637 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8638 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8639 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8640 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8641 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8642 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8643 /* HP Pin: Rear */
8644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8646 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8647 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8648 /* Line in Rear */
8649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8651 /* Front Mic pin: input vref at 80% */
8652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8654 /* Rear mixer */
8655 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8656 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8657 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8658 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8662 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8663 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8664 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8665 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8667 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8668 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8670 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8672 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8677 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8679 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8680 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8681 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8682 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8683 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8685 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8686 { }
8687};
8688
8689/* iMac 24 mixer. */
8690static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8691 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8692 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8693 { } /* end */
8694};
8695
8696/* iMac 24 init verbs. */
8697static const struct hda_verb alc885_imac24_init_verbs[] = {
8698 /* Internal speakers: output 0 (0x0c) */
8699 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8701 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8702 /* Internal speakers: output 0 (0x0c) */
8703 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8704 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8705 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8706 /* Headphone: output 0 (0x0c) */
8707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8709 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8710 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8711 /* Front Mic: input vref at 80% */
8712 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8714 { }
8715};
8716
8717/* Toggle speaker-output according to the hp-jack state */
8718static void alc885_imac24_setup(struct hda_codec *codec)
8719{
8720 struct alc_spec *spec = codec->spec;
8721
8722 spec->autocfg.hp_pins[0] = 0x14;
8723 spec->autocfg.speaker_pins[0] = 0x18;
8724 spec->autocfg.speaker_pins[1] = 0x1a;
8725 spec->automute = 1;
8726 spec->automute_mode = ALC_AUTOMUTE_AMP;
8727}
8728
8729#define alc885_mb5_setup alc885_imac24_setup
8730#define alc885_macmini3_setup alc885_imac24_setup
8731
8732/* Macbook Air 2,1 */
8733static void alc885_mba21_setup(struct hda_codec *codec)
8734{
8735 struct alc_spec *spec = codec->spec;
8736
8737 spec->autocfg.hp_pins[0] = 0x14;
8738 spec->autocfg.speaker_pins[0] = 0x18;
8739 spec->automute = 1;
8740 spec->automute_mode = ALC_AUTOMUTE_AMP;
8741}
8742
8743
8744
8745static void alc885_mbp3_setup(struct hda_codec *codec)
8746{
8747 struct alc_spec *spec = codec->spec;
8748
8749 spec->autocfg.hp_pins[0] = 0x15;
8750 spec->autocfg.speaker_pins[0] = 0x14;
8751 spec->automute = 1;
8752 spec->automute_mode = ALC_AUTOMUTE_AMP;
8753}
8754
8755static void alc885_imac91_setup(struct hda_codec *codec)
8756{
8757 struct alc_spec *spec = codec->spec;
8758
8759 spec->autocfg.hp_pins[0] = 0x14;
8760 spec->autocfg.speaker_pins[0] = 0x18;
8761 spec->autocfg.speaker_pins[1] = 0x1a;
8762 spec->automute = 1;
8763 spec->automute_mode = ALC_AUTOMUTE_AMP;
8764}
8765
8766static const struct hda_verb alc882_targa_verbs[] = {
8767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8768 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8769
8770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8771 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8772
8773 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8774 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8775 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8776
8777 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8778 { } /* end */
8779};
8780
8781/* toggle speaker-output according to the hp-jack state */
8782static void alc882_targa_automute(struct hda_codec *codec)
8783{
8784 struct alc_spec *spec = codec->spec;
8785 alc_hp_automute(codec);
8786 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8787 spec->jack_present ? 1 : 3);
8788}
8789
8790static void alc882_targa_setup(struct hda_codec *codec)
8791{
8792 struct alc_spec *spec = codec->spec;
8793
8794 spec->autocfg.hp_pins[0] = 0x14;
8795 spec->autocfg.speaker_pins[0] = 0x1b;
8796 spec->automute = 1;
8797 spec->automute_mode = ALC_AUTOMUTE_AMP;
8798}
8799
8800static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8801{
8802 if ((res >> 26) == ALC880_HP_EVENT)
8803 alc882_targa_automute(codec);
8804}
8805
8806static const struct hda_verb alc882_asus_a7j_verbs[] = {
8807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8809
8810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8812 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8813
8814 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8815 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8816 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8817
8818 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8819 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8820 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8821 { } /* end */
8822};
8823
8824static const struct hda_verb alc882_asus_a7m_verbs[] = {
8825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8827
8828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8829 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8830 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8831
8832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8833 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8834 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8835
8836 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8837 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8838 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8839 { } /* end */
8840};
8841
8842static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8843{
8844 unsigned int gpiostate, gpiomask, gpiodir;
8845
8846 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8847 AC_VERB_GET_GPIO_DATA, 0);
8848
8849 if (!muted)
8850 gpiostate |= (1 << pin);
8851 else
8852 gpiostate &= ~(1 << pin);
8853
8854 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8855 AC_VERB_GET_GPIO_MASK, 0);
8856 gpiomask |= (1 << pin);
8857
8858 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8859 AC_VERB_GET_GPIO_DIRECTION, 0);
8860 gpiodir |= (1 << pin);
8861
8862
8863 snd_hda_codec_write(codec, codec->afg, 0,
8864 AC_VERB_SET_GPIO_MASK, gpiomask);
8865 snd_hda_codec_write(codec, codec->afg, 0,
8866 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8867
8868 msleep(1);
8869
8870 snd_hda_codec_write(codec, codec->afg, 0,
8871 AC_VERB_SET_GPIO_DATA, gpiostate);
8872}
8873
8874/* set up GPIO at initialization */
8875static void alc885_macpro_init_hook(struct hda_codec *codec)
8876{
8877 alc882_gpio_mute(codec, 0, 0);
8878 alc882_gpio_mute(codec, 1, 0);
8879}
8880
8881/* set up GPIO and update auto-muting at initialization */
8882static void alc885_imac24_init_hook(struct hda_codec *codec)
8883{
8884 alc885_macpro_init_hook(codec);
8885 alc_hp_automute(codec);
8886}
8887
8888/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8889static const struct hda_verb alc889A_mb31_ch2_init[] = {
8890 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8892 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8894 { } /* end */
8895};
8896
8897/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8898static const struct hda_verb alc889A_mb31_ch4_init[] = {
8899 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8901 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8902 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8903 { } /* end */
8904};
8905
8906/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8907static const struct hda_verb alc889A_mb31_ch5_init[] = {
8908 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8909 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8911 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8912 { } /* end */
8913};
8914
8915/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8916static const struct hda_verb alc889A_mb31_ch6_init[] = {
8917 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8919 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8920 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8921 { } /* end */
8922};
8923
8924static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8925 { 2, alc889A_mb31_ch2_init },
8926 { 4, alc889A_mb31_ch4_init },
8927 { 5, alc889A_mb31_ch5_init },
8928 { 6, alc889A_mb31_ch6_init },
8929};
8930
8931static const struct hda_verb alc883_medion_eapd_verbs[] = {
8932 /* eanable EAPD on medion laptop */
8933 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8934 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8935 { }
8936};
8937
8938#define alc883_base_mixer alc882_base_mixer
8939
8940static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
8941 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8942 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8943 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8947 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8954 { } /* end */
8955};
8956
8957static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8958 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8959 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8960 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8961 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8962 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8963 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8964 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8965 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8966 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8967 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8968 { } /* end */
8969};
8970
8971static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8972 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8973 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8975 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8980 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8981 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8982 { } /* end */
8983};
8984
8985static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8989 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8990 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8998 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8999 { } /* end */
9000};
9001
9002static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9003 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9004 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9006 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9007 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9008 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9009 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9010 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9012 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9013 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9014 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9015 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9017 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9020 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9022 { } /* end */
9023};
9024
9025static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9026 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9027 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9028 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9029 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9030 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9031 HDA_OUTPUT),
9032 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9033 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9034 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9036 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9037 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9038 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9039 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9041 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9043 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9044 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9045 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9046 { } /* end */
9047};
9048
9049static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9050 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9051 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9052 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9053 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9054 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9055 HDA_OUTPUT),
9056 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9057 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9058 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9059 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9060 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9061 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9062 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9063 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9065 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9067 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9068 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9069 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9070 { } /* end */
9071};
9072
9073static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9074 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9075 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9076 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9077 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9078 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9080 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9081 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9083 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9084 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9085 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9086 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9087 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9088 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9089 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9090 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9091 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9092 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9093 { } /* end */
9094};
9095
9096static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9097 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9098 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9102 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9112 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9114 { } /* end */
9115};
9116
9117static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9118 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9119 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9120 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9121 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9122 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9123 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9127 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9129 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9130 { } /* end */
9131};
9132
9133static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9134 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9135 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9136 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9137 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9138 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9139 { } /* end */
9140};
9141
9142static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9143 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9144 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9146 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9149 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9151 { } /* end */
9152};
9153
9154static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9155 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9156 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9158 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9159 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9160 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9161 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9162 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9163 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9164 { } /* end */
9165};
9166
9167static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9168 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9169 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9170 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9172 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9173 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9174 { } /* end */
9175};
9176
9177static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9178 /* Unmute front mixer */
9179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9180 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9181
9182 /* Set speaker pin to front mixer */
9183 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9184
9185 /* Init headphone pin */
9186 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9187 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9188 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9189 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9190
9191 { } /* end */
9192};
9193
9194/* toggle speaker-output according to the hp-jack state */
9195static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9196{
9197 struct alc_spec *spec = codec->spec;
9198
9199 spec->autocfg.hp_pins[0] = 0x1a;
9200 spec->autocfg.speaker_pins[0] = 0x15;
9201 spec->automute = 1;
9202 spec->automute_mode = ALC_AUTOMUTE_AMP;
9203}
9204
9205static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9206 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9207 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9214 { } /* end */
9215};
9216
9217static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9219 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9220 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9221 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9222 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9223 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9225 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9227 { } /* end */
9228};
9229
9230static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9231 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9232 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9234 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9235 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9236 0x0d, 1, 0x0, HDA_OUTPUT),
9237 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9238 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9239 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9240 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9241 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9242 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9243 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9245 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9247 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9249 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9250 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9251 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9252 { } /* end */
9253};
9254
9255static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9256 /* Output mixers */
9257 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9258 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9259 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9260 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9261 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9262 HDA_OUTPUT),
9263 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9264 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9265 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9266 /* Output switches */
9267 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9268 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9269 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9270 /* Boost mixers */
9271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9272 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9273 /* Input mixers */
9274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9275 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9276 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9277 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9278 { } /* end */
9279};
9280
9281static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9282 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9283 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9288 { } /* end */
9289};
9290
9291static const struct hda_bind_ctls alc883_bind_cap_vol = {
9292 .ops = &snd_hda_bind_vol,
9293 .values = {
9294 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9295 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9296 0
9297 },
9298};
9299
9300static const struct hda_bind_ctls alc883_bind_cap_switch = {
9301 .ops = &snd_hda_bind_sw,
9302 .values = {
9303 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9304 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9305 0
9306 },
9307};
9308
9309static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9310 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9311 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9312 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9313 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9314 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9315 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9317 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9318 { } /* end */
9319};
9320
9321static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9322 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9323 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9324 {
9325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9326 /* .name = "Capture Source", */
9327 .name = "Input Source",
9328 .count = 1,
9329 .info = alc_mux_enum_info,
9330 .get = alc_mux_enum_get,
9331 .put = alc_mux_enum_put,
9332 },
9333 { } /* end */
9334};
9335
9336static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9337 {
9338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9339 .name = "Channel Mode",
9340 .info = alc_ch_mode_info,
9341 .get = alc_ch_mode_get,
9342 .put = alc_ch_mode_put,
9343 },
9344 { } /* end */
9345};
9346
9347/* toggle speaker-output according to the hp-jack state */
9348static void alc883_mitac_setup(struct hda_codec *codec)
9349{
9350 struct alc_spec *spec = codec->spec;
9351
9352 spec->autocfg.hp_pins[0] = 0x15;
9353 spec->autocfg.speaker_pins[0] = 0x14;
9354 spec->autocfg.speaker_pins[1] = 0x17;
9355 spec->automute = 1;
9356 spec->automute_mode = ALC_AUTOMUTE_AMP;
9357}
9358
9359static const struct hda_verb alc883_mitac_verbs[] = {
9360 /* HP */
9361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9362 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9363 /* Subwoofer */
9364 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9365 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9366
9367 /* enable unsolicited event */
9368 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9369 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9370
9371 { } /* end */
9372};
9373
9374static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9375 /* HP */
9376 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9377 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9378 /* Int speaker */
9379 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9380
9381 /* enable unsolicited event */
9382 /*
9383 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9385 */
9386
9387 { } /* end */
9388};
9389
9390static const struct hda_verb alc883_clevo_m720_verbs[] = {
9391 /* HP */
9392 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9394 /* Int speaker */
9395 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9397
9398 /* enable unsolicited event */
9399 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9401
9402 { } /* end */
9403};
9404
9405static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9406 /* HP */
9407 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9409 /* Subwoofer */
9410 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9412
9413 /* enable unsolicited event */
9414 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9415
9416 { } /* end */
9417};
9418
9419static const struct hda_verb alc883_targa_verbs[] = {
9420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9422
9423 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9424 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9425
9426/* Connect Line-Out side jack (SPDIF) to Side */
9427 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9428 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9429 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9430/* Connect Mic jack to CLFE */
9431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9433 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9434/* Connect Line-in jack to Surround */
9435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9437 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9438/* Connect HP out jack to Front */
9439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9440 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9441 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9442
9443 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9444
9445 { } /* end */
9446};
9447
9448static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9450 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9451 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9452 { } /* end */
9453};
9454
9455static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9456 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9458 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9460 { } /* end */
9461};
9462
9463static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9466 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9467 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9468 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9469 { } /* end */
9470};
9471
9472static const struct hda_verb alc883_haier_w66_verbs[] = {
9473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9475
9476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9477
9478 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9479 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9480 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9481 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9482 { } /* end */
9483};
9484
9485static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9488 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9490 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9491 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9492 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9493 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9494 { } /* end */
9495};
9496
9497static const struct hda_verb alc888_6st_dell_verbs[] = {
9498 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9499 { }
9500};
9501
9502static const struct hda_verb alc883_vaiott_verbs[] = {
9503 /* HP */
9504 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9505 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9506
9507 /* enable unsolicited event */
9508 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9509
9510 { } /* end */
9511};
9512
9513static void alc888_3st_hp_setup(struct hda_codec *codec)
9514{
9515 struct alc_spec *spec = codec->spec;
9516
9517 spec->autocfg.hp_pins[0] = 0x1b;
9518 spec->autocfg.speaker_pins[0] = 0x14;
9519 spec->autocfg.speaker_pins[1] = 0x16;
9520 spec->autocfg.speaker_pins[2] = 0x18;
9521 spec->automute = 1;
9522 spec->automute_mode = ALC_AUTOMUTE_AMP;
9523}
9524
9525static const struct hda_verb alc888_3st_hp_verbs[] = {
9526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9527 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9528 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9529 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9530 { } /* end */
9531};
9532
9533/*
9534 * 2ch mode
9535 */
9536static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9537 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9538 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9540 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9541 { } /* end */
9542};
9543
9544/*
9545 * 4ch mode
9546 */
9547static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9548 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9549 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9550 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9551 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9552 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9553 { } /* end */
9554};
9555
9556/*
9557 * 6ch mode
9558 */
9559static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9560 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9561 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9562 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9563 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9564 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9565 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9566 { } /* end */
9567};
9568
9569static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9570 { 2, alc888_3st_hp_2ch_init },
9571 { 4, alc888_3st_hp_4ch_init },
9572 { 6, alc888_3st_hp_6ch_init },
9573};
9574
9575static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9576{
9577 struct alc_spec *spec = codec->spec;
9578
9579 spec->autocfg.hp_pins[0] = 0x1b;
9580 spec->autocfg.line_out_pins[0] = 0x14;
9581 spec->autocfg.speaker_pins[0] = 0x15;
9582 spec->automute = 1;
9583 spec->automute_mode = ALC_AUTOMUTE_AMP;
9584}
9585
9586/* toggle speaker-output according to the hp-jack state */
9587static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9588{
9589 struct alc_spec *spec = codec->spec;
9590
9591 spec->autocfg.hp_pins[0] = 0x14;
9592 spec->autocfg.speaker_pins[0] = 0x15;
9593 spec->automute = 1;
9594 spec->automute_mode = ALC_AUTOMUTE_AMP;
9595}
9596
9597/* toggle speaker-output according to the hp-jack state */
9598#define alc883_targa_init_hook alc882_targa_init_hook
9599#define alc883_targa_unsol_event alc882_targa_unsol_event
9600
9601static void alc883_clevo_m720_setup(struct hda_codec *codec)
9602{
9603 struct alc_spec *spec = codec->spec;
9604
9605 spec->autocfg.hp_pins[0] = 0x15;
9606 spec->autocfg.speaker_pins[0] = 0x14;
9607 spec->automute = 1;
9608 spec->automute_mode = ALC_AUTOMUTE_AMP;
9609}
9610
9611static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9612{
9613 alc_hp_automute(codec);
9614 alc88x_simple_mic_automute(codec);
9615}
9616
9617static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9618 unsigned int res)
9619{
9620 switch (res >> 26) {
9621 case ALC880_MIC_EVENT:
9622 alc88x_simple_mic_automute(codec);
9623 break;
9624 default:
9625 alc_sku_unsol_event(codec, res);
9626 break;
9627 }
9628}
9629
9630/* toggle speaker-output according to the hp-jack state */
9631static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9632{
9633 struct alc_spec *spec = codec->spec;
9634
9635 spec->autocfg.hp_pins[0] = 0x14;
9636 spec->autocfg.speaker_pins[0] = 0x15;
9637 spec->automute = 1;
9638 spec->automute_mode = ALC_AUTOMUTE_AMP;
9639}
9640
9641static void alc883_haier_w66_setup(struct hda_codec *codec)
9642{
9643 struct alc_spec *spec = codec->spec;
9644
9645 spec->autocfg.hp_pins[0] = 0x1b;
9646 spec->autocfg.speaker_pins[0] = 0x14;
9647 spec->automute = 1;
9648 spec->automute_mode = ALC_AUTOMUTE_AMP;
9649}
9650
9651static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9652{
9653 struct alc_spec *spec = codec->spec;
9654
9655 spec->autocfg.hp_pins[0] = 0x1b;
9656 spec->autocfg.line_out_pins[0] = 0x14;
9657 spec->autocfg.speaker_pins[0] = 0x15;
9658 spec->automute = 1;
9659 spec->detect_line = 1;
9660 spec->automute_lines = 1;
9661 spec->automute_mode = ALC_AUTOMUTE_AMP;
9662}
9663
9664/* toggle speaker-output according to the hp-jack state */
9665static void alc883_acer_aspire_setup(struct hda_codec *codec)
9666{
9667 struct alc_spec *spec = codec->spec;
9668
9669 spec->autocfg.hp_pins[0] = 0x14;
9670 spec->autocfg.speaker_pins[0] = 0x15;
9671 spec->autocfg.speaker_pins[1] = 0x16;
9672 spec->automute = 1;
9673 spec->automute_mode = ALC_AUTOMUTE_AMP;
9674}
9675
9676static const struct hda_verb alc883_acer_eapd_verbs[] = {
9677 /* HP Pin: output 0 (0x0c) */
9678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9680 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9681 /* Front Pin: output 0 (0x0c) */
9682 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9683 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9684 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9685 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9686 /* eanable EAPD on medion laptop */
9687 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9688 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9689 /* enable unsolicited event */
9690 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9691 { }
9692};
9693
9694static void alc888_6st_dell_setup(struct hda_codec *codec)
9695{
9696 struct alc_spec *spec = codec->spec;
9697
9698 spec->autocfg.hp_pins[0] = 0x1b;
9699 spec->autocfg.speaker_pins[0] = 0x14;
9700 spec->autocfg.speaker_pins[1] = 0x15;
9701 spec->autocfg.speaker_pins[2] = 0x16;
9702 spec->autocfg.speaker_pins[3] = 0x17;
9703 spec->automute = 1;
9704 spec->automute_mode = ALC_AUTOMUTE_AMP;
9705}
9706
9707static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9708{
9709 struct alc_spec *spec = codec->spec;
9710
9711 spec->autocfg.hp_pins[0] = 0x1b;
9712 spec->autocfg.speaker_pins[0] = 0x14;
9713 spec->autocfg.speaker_pins[1] = 0x15;
9714 spec->autocfg.speaker_pins[2] = 0x16;
9715 spec->autocfg.speaker_pins[3] = 0x17;
9716 spec->autocfg.speaker_pins[4] = 0x1a;
9717 spec->automute = 1;
9718 spec->automute_mode = ALC_AUTOMUTE_AMP;
9719}
9720
9721static void alc883_vaiott_setup(struct hda_codec *codec)
9722{
9723 struct alc_spec *spec = codec->spec;
9724
9725 spec->autocfg.hp_pins[0] = 0x15;
9726 spec->autocfg.speaker_pins[0] = 0x14;
9727 spec->autocfg.speaker_pins[1] = 0x17;
9728 spec->automute = 1;
9729 spec->automute_mode = ALC_AUTOMUTE_AMP;
9730}
9731
9732static const struct hda_verb alc888_asus_m90v_verbs[] = {
9733 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9734 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9735 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9736 /* enable unsolicited event */
9737 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9738 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9739 { } /* end */
9740};
9741
9742static void alc883_mode2_setup(struct hda_codec *codec)
9743{
9744 struct alc_spec *spec = codec->spec;
9745
9746 spec->autocfg.hp_pins[0] = 0x1b;
9747 spec->autocfg.speaker_pins[0] = 0x14;
9748 spec->autocfg.speaker_pins[1] = 0x15;
9749 spec->autocfg.speaker_pins[2] = 0x16;
9750 spec->ext_mic_pin = 0x18;
9751 spec->int_mic_pin = 0x19;
9752 spec->auto_mic = 1;
9753 spec->automute = 1;
9754 spec->automute_mode = ALC_AUTOMUTE_AMP;
9755}
9756
9757static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9759 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9761 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9763 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9764 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9765 /* enable unsolicited event */
9766 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9767 { } /* end */
9768};
9769
9770static void alc883_eee1601_inithook(struct hda_codec *codec)
9771{
9772 struct alc_spec *spec = codec->spec;
9773
9774 spec->autocfg.hp_pins[0] = 0x14;
9775 spec->autocfg.speaker_pins[0] = 0x1b;
9776 alc_hp_automute(codec);
9777}
9778
9779static const struct hda_verb alc889A_mb31_verbs[] = {
9780 /* Init rear pin (used as headphone output) */
9781 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9782 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9783 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9784 /* Init line pin (used as output in 4ch and 6ch mode) */
9785 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9786 /* Init line 2 pin (used as headphone out by default) */
9787 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9789 { } /* end */
9790};
9791
9792/* Mute speakers according to the headphone jack state */
9793static void alc889A_mb31_automute(struct hda_codec *codec)
9794{
9795 unsigned int present;
9796
9797 /* Mute only in 2ch or 4ch mode */
9798 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9799 == 0x00) {
9800 present = snd_hda_jack_detect(codec, 0x15);
9801 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9802 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9803 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9804 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9805 }
9806}
9807
9808static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9809{
9810 if ((res >> 26) == ALC880_HP_EVENT)
9811 alc889A_mb31_automute(codec);
9812}
9813
9814
9815#ifdef CONFIG_SND_HDA_POWER_SAVE 3929#ifdef CONFIG_SND_HDA_POWER_SAVE
9816#define alc882_loopbacks alc880_loopbacks 3930#define alc882_loopbacks alc880_loopbacks
9817#endif 3931#endif
9818 3932
9819static const hda_nid_t alc883_slave_dig_outs[] = {
9820 ALC1200_DIGOUT_NID, 0,
9821};
9822
9823static const hda_nid_t alc1200_slave_dig_outs[] = {
9824 ALC883_DIGOUT_NID, 0,
9825};
9826
9827/*
9828 * configuration and preset
9829 */
9830static const char * const alc882_models[ALC882_MODEL_LAST] = {
9831 [ALC882_3ST_DIG] = "3stack-dig",
9832 [ALC882_6ST_DIG] = "6stack-dig",
9833 [ALC882_ARIMA] = "arima",
9834 [ALC882_W2JC] = "w2jc",
9835 [ALC882_TARGA] = "targa",
9836 [ALC882_ASUS_A7J] = "asus-a7j",
9837 [ALC882_ASUS_A7M] = "asus-a7m",
9838 [ALC885_MACPRO] = "macpro",
9839 [ALC885_MB5] = "mb5",
9840 [ALC885_MACMINI3] = "macmini3",
9841 [ALC885_MBA21] = "mba21",
9842 [ALC885_MBP3] = "mbp3",
9843 [ALC885_IMAC24] = "imac24",
9844 [ALC885_IMAC91] = "imac91",
9845 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9846 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9847 [ALC883_3ST_6ch] = "3stack-6ch",
9848 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9849 [ALC883_TARGA_DIG] = "targa-dig",
9850 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9851 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9852 [ALC883_ACER] = "acer",
9853 [ALC883_ACER_ASPIRE] = "acer-aspire",
9854 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9855 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9856 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9857 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9858 [ALC883_MEDION] = "medion",
9859 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9860 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9861 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9862 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9863 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9864 [ALC888_LENOVO_SKY] = "lenovo-sky",
9865 [ALC883_HAIER_W66] = "haier-w66",
9866 [ALC888_3ST_HP] = "3stack-hp",
9867 [ALC888_6ST_DELL] = "6stack-dell",
9868 [ALC883_MITAC] = "mitac",
9869 [ALC883_CLEVO_M540R] = "clevo-m540r",
9870 [ALC883_CLEVO_M720] = "clevo-m720",
9871 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9872 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9873 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9874 [ALC889A_INTEL] = "intel-alc889a",
9875 [ALC889_INTEL] = "intel-x58",
9876 [ALC1200_ASUS_P5Q] = "asus-p5q",
9877 [ALC889A_MB31] = "mb31",
9878 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9879 [ALC882_AUTO] = "auto",
9880};
9881
9882static const struct snd_pci_quirk alc882_cfg_tbl[] = {
9883 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9884
9885 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9886 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9887 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9888 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9889 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9890 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9891 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9892 ALC888_ACER_ASPIRE_4930G),
9893 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9894 ALC888_ACER_ASPIRE_4930G),
9895 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9896 ALC888_ACER_ASPIRE_8930G),
9897 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9898 ALC888_ACER_ASPIRE_8930G),
9899 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9900 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9901 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9902 ALC888_ACER_ASPIRE_6530G),
9903 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9904 ALC888_ACER_ASPIRE_6530G),
9905 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9906 ALC888_ACER_ASPIRE_7730G),
9907 /* default Acer -- disabled as it causes more problems.
9908 * model=auto should work fine now
9909 */
9910 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9911
9912 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9913
9914 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
9915 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9916 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9917 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9918 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9919 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9920
9921 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9922 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9923 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9924 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9925 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9926 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9927 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9928 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9929 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9930 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9931 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9932
9933 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9934 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9935 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9936 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9937 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9938 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9939 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9940 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9941 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9942
9943 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9944 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9945 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9946 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9947 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9948 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9949 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9950 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9951 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9952 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9953 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9954 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9955 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9956 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9957 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9958 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9959 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9960 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9961 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9962 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9963 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9964 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9965 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9966 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9967 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9968 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9969 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9970 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9971 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9972 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9973 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9974
9975 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9976 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9977 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9978 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9979 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9980 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9981 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9982 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9983 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9984 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9985 ALC883_FUJITSU_PI2515),
9986 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9987 ALC888_FUJITSU_XA3530),
9988 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9989 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9990 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9991 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9992 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9993 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9994 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9995 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9996
9997 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9998 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9999 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10000 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10001 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10002 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10003 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10004
10005 {}
10006};
10007
10008/* codec SSID table for Intel Mac */
10009static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10010 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10011 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10012 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10013 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10014 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10015 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10016 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10017 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10018 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10019 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10020 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10021 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10022 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10023 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10024 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10025 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10026 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10027 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10028 * so apparently no perfect solution yet
10029 */
10030 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10031 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10032 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10033 {} /* terminator */
10034};
10035
10036static const struct alc_config_preset alc882_presets[] = {
10037 [ALC882_3ST_DIG] = {
10038 .mixers = { alc882_base_mixer },
10039 .init_verbs = { alc882_base_init_verbs,
10040 alc882_adc1_init_verbs },
10041 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10042 .dac_nids = alc882_dac_nids,
10043 .dig_out_nid = ALC882_DIGOUT_NID,
10044 .dig_in_nid = ALC882_DIGIN_NID,
10045 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10046 .channel_mode = alc882_ch_modes,
10047 .need_dac_fix = 1,
10048 .input_mux = &alc882_capture_source,
10049 },
10050 [ALC882_6ST_DIG] = {
10051 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10052 .init_verbs = { alc882_base_init_verbs,
10053 alc882_adc1_init_verbs },
10054 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10055 .dac_nids = alc882_dac_nids,
10056 .dig_out_nid = ALC882_DIGOUT_NID,
10057 .dig_in_nid = ALC882_DIGIN_NID,
10058 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10059 .channel_mode = alc882_sixstack_modes,
10060 .input_mux = &alc882_capture_source,
10061 },
10062 [ALC882_ARIMA] = {
10063 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10064 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10065 alc882_eapd_verbs },
10066 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10067 .dac_nids = alc882_dac_nids,
10068 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10069 .channel_mode = alc882_sixstack_modes,
10070 .input_mux = &alc882_capture_source,
10071 },
10072 [ALC882_W2JC] = {
10073 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10074 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10075 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10076 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10077 .dac_nids = alc882_dac_nids,
10078 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10079 .channel_mode = alc880_threestack_modes,
10080 .need_dac_fix = 1,
10081 .input_mux = &alc882_capture_source,
10082 .dig_out_nid = ALC882_DIGOUT_NID,
10083 },
10084 [ALC885_MBA21] = {
10085 .mixers = { alc885_mba21_mixer },
10086 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10087 .num_dacs = 2,
10088 .dac_nids = alc882_dac_nids,
10089 .channel_mode = alc885_mba21_ch_modes,
10090 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10091 .input_mux = &alc882_capture_source,
10092 .unsol_event = alc_sku_unsol_event,
10093 .setup = alc885_mba21_setup,
10094 .init_hook = alc_hp_automute,
10095 },
10096 [ALC885_MBP3] = {
10097 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10098 .init_verbs = { alc885_mbp3_init_verbs,
10099 alc880_gpio1_init_verbs },
10100 .num_dacs = 2,
10101 .dac_nids = alc882_dac_nids,
10102 .hp_nid = 0x04,
10103 .channel_mode = alc885_mbp_4ch_modes,
10104 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10105 .input_mux = &alc882_capture_source,
10106 .dig_out_nid = ALC882_DIGOUT_NID,
10107 .dig_in_nid = ALC882_DIGIN_NID,
10108 .unsol_event = alc_sku_unsol_event,
10109 .setup = alc885_mbp3_setup,
10110 .init_hook = alc_hp_automute,
10111 },
10112 [ALC885_MB5] = {
10113 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10114 .init_verbs = { alc885_mb5_init_verbs,
10115 alc880_gpio1_init_verbs },
10116 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10117 .dac_nids = alc882_dac_nids,
10118 .channel_mode = alc885_mb5_6ch_modes,
10119 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10120 .input_mux = &mb5_capture_source,
10121 .dig_out_nid = ALC882_DIGOUT_NID,
10122 .dig_in_nid = ALC882_DIGIN_NID,
10123 .unsol_event = alc_sku_unsol_event,
10124 .setup = alc885_mb5_setup,
10125 .init_hook = alc_hp_automute,
10126 },
10127 [ALC885_MACMINI3] = {
10128 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10129 .init_verbs = { alc885_macmini3_init_verbs,
10130 alc880_gpio1_init_verbs },
10131 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10132 .dac_nids = alc882_dac_nids,
10133 .channel_mode = alc885_macmini3_6ch_modes,
10134 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10135 .input_mux = &macmini3_capture_source,
10136 .dig_out_nid = ALC882_DIGOUT_NID,
10137 .dig_in_nid = ALC882_DIGIN_NID,
10138 .unsol_event = alc_sku_unsol_event,
10139 .setup = alc885_macmini3_setup,
10140 .init_hook = alc_hp_automute,
10141 },
10142 [ALC885_MACPRO] = {
10143 .mixers = { alc882_macpro_mixer },
10144 .init_verbs = { alc882_macpro_init_verbs },
10145 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10146 .dac_nids = alc882_dac_nids,
10147 .dig_out_nid = ALC882_DIGOUT_NID,
10148 .dig_in_nid = ALC882_DIGIN_NID,
10149 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10150 .channel_mode = alc882_ch_modes,
10151 .input_mux = &alc882_capture_source,
10152 .init_hook = alc885_macpro_init_hook,
10153 },
10154 [ALC885_IMAC24] = {
10155 .mixers = { alc885_imac24_mixer },
10156 .init_verbs = { alc885_imac24_init_verbs },
10157 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10158 .dac_nids = alc882_dac_nids,
10159 .dig_out_nid = ALC882_DIGOUT_NID,
10160 .dig_in_nid = ALC882_DIGIN_NID,
10161 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10162 .channel_mode = alc882_ch_modes,
10163 .input_mux = &alc882_capture_source,
10164 .unsol_event = alc_sku_unsol_event,
10165 .setup = alc885_imac24_setup,
10166 .init_hook = alc885_imac24_init_hook,
10167 },
10168 [ALC885_IMAC91] = {
10169 .mixers = {alc885_imac91_mixer},
10170 .init_verbs = { alc885_imac91_init_verbs,
10171 alc880_gpio1_init_verbs },
10172 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10173 .dac_nids = alc882_dac_nids,
10174 .channel_mode = alc885_mba21_ch_modes,
10175 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10176 .input_mux = &alc889A_imac91_capture_source,
10177 .dig_out_nid = ALC882_DIGOUT_NID,
10178 .dig_in_nid = ALC882_DIGIN_NID,
10179 .unsol_event = alc_sku_unsol_event,
10180 .setup = alc885_imac91_setup,
10181 .init_hook = alc_hp_automute,
10182 },
10183 [ALC882_TARGA] = {
10184 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10185 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10186 alc880_gpio3_init_verbs, alc882_targa_verbs},
10187 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10188 .dac_nids = alc882_dac_nids,
10189 .dig_out_nid = ALC882_DIGOUT_NID,
10190 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10191 .adc_nids = alc882_adc_nids,
10192 .capsrc_nids = alc882_capsrc_nids,
10193 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10194 .channel_mode = alc882_3ST_6ch_modes,
10195 .need_dac_fix = 1,
10196 .input_mux = &alc882_capture_source,
10197 .unsol_event = alc_sku_unsol_event,
10198 .setup = alc882_targa_setup,
10199 .init_hook = alc882_targa_automute,
10200 },
10201 [ALC882_ASUS_A7J] = {
10202 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10203 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10204 alc882_asus_a7j_verbs},
10205 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10206 .dac_nids = alc882_dac_nids,
10207 .dig_out_nid = ALC882_DIGOUT_NID,
10208 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10209 .adc_nids = alc882_adc_nids,
10210 .capsrc_nids = alc882_capsrc_nids,
10211 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10212 .channel_mode = alc882_3ST_6ch_modes,
10213 .need_dac_fix = 1,
10214 .input_mux = &alc882_capture_source,
10215 },
10216 [ALC882_ASUS_A7M] = {
10217 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10218 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10219 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10220 alc882_asus_a7m_verbs },
10221 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10222 .dac_nids = alc882_dac_nids,
10223 .dig_out_nid = ALC882_DIGOUT_NID,
10224 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10225 .channel_mode = alc880_threestack_modes,
10226 .need_dac_fix = 1,
10227 .input_mux = &alc882_capture_source,
10228 },
10229 [ALC883_3ST_2ch_DIG] = {
10230 .mixers = { alc883_3ST_2ch_mixer },
10231 .init_verbs = { alc883_init_verbs },
10232 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10233 .dac_nids = alc883_dac_nids,
10234 .dig_out_nid = ALC883_DIGOUT_NID,
10235 .dig_in_nid = ALC883_DIGIN_NID,
10236 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10237 .channel_mode = alc883_3ST_2ch_modes,
10238 .input_mux = &alc883_capture_source,
10239 },
10240 [ALC883_3ST_6ch_DIG] = {
10241 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10242 .init_verbs = { alc883_init_verbs },
10243 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10244 .dac_nids = alc883_dac_nids,
10245 .dig_out_nid = ALC883_DIGOUT_NID,
10246 .dig_in_nid = ALC883_DIGIN_NID,
10247 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10248 .channel_mode = alc883_3ST_6ch_modes,
10249 .need_dac_fix = 1,
10250 .input_mux = &alc883_capture_source,
10251 },
10252 [ALC883_3ST_6ch] = {
10253 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10254 .init_verbs = { alc883_init_verbs },
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
10257 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10258 .channel_mode = alc883_3ST_6ch_modes,
10259 .need_dac_fix = 1,
10260 .input_mux = &alc883_capture_source,
10261 },
10262 [ALC883_3ST_6ch_INTEL] = {
10263 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10264 .init_verbs = { alc883_init_verbs },
10265 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10266 .dac_nids = alc883_dac_nids,
10267 .dig_out_nid = ALC883_DIGOUT_NID,
10268 .dig_in_nid = ALC883_DIGIN_NID,
10269 .slave_dig_outs = alc883_slave_dig_outs,
10270 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10271 .channel_mode = alc883_3ST_6ch_intel_modes,
10272 .need_dac_fix = 1,
10273 .input_mux = &alc883_3stack_6ch_intel,
10274 },
10275 [ALC889A_INTEL] = {
10276 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10277 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10278 alc_hp15_unsol_verbs },
10279 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10280 .dac_nids = alc883_dac_nids,
10281 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10282 .adc_nids = alc889_adc_nids,
10283 .dig_out_nid = ALC883_DIGOUT_NID,
10284 .dig_in_nid = ALC883_DIGIN_NID,
10285 .slave_dig_outs = alc883_slave_dig_outs,
10286 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10287 .channel_mode = alc889_8ch_intel_modes,
10288 .capsrc_nids = alc889_capsrc_nids,
10289 .input_mux = &alc889_capture_source,
10290 .setup = alc889_automute_setup,
10291 .init_hook = alc_hp_automute,
10292 .unsol_event = alc_sku_unsol_event,
10293 .need_dac_fix = 1,
10294 },
10295 [ALC889_INTEL] = {
10296 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10297 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10298 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10299 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10300 .dac_nids = alc883_dac_nids,
10301 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10302 .adc_nids = alc889_adc_nids,
10303 .dig_out_nid = ALC883_DIGOUT_NID,
10304 .dig_in_nid = ALC883_DIGIN_NID,
10305 .slave_dig_outs = alc883_slave_dig_outs,
10306 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10307 .channel_mode = alc889_8ch_intel_modes,
10308 .capsrc_nids = alc889_capsrc_nids,
10309 .input_mux = &alc889_capture_source,
10310 .setup = alc889_automute_setup,
10311 .init_hook = alc889_intel_init_hook,
10312 .unsol_event = alc_sku_unsol_event,
10313 .need_dac_fix = 1,
10314 },
10315 [ALC883_6ST_DIG] = {
10316 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10317 .init_verbs = { alc883_init_verbs },
10318 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10319 .dac_nids = alc883_dac_nids,
10320 .dig_out_nid = ALC883_DIGOUT_NID,
10321 .dig_in_nid = ALC883_DIGIN_NID,
10322 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10323 .channel_mode = alc883_sixstack_modes,
10324 .input_mux = &alc883_capture_source,
10325 },
10326 [ALC883_TARGA_DIG] = {
10327 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10328 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10329 alc883_targa_verbs},
10330 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10331 .dac_nids = alc883_dac_nids,
10332 .dig_out_nid = ALC883_DIGOUT_NID,
10333 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10334 .channel_mode = alc883_3ST_6ch_modes,
10335 .need_dac_fix = 1,
10336 .input_mux = &alc883_capture_source,
10337 .unsol_event = alc883_targa_unsol_event,
10338 .setup = alc882_targa_setup,
10339 .init_hook = alc882_targa_automute,
10340 },
10341 [ALC883_TARGA_2ch_DIG] = {
10342 .mixers = { alc883_targa_2ch_mixer},
10343 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10344 alc883_targa_verbs},
10345 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10346 .dac_nids = alc883_dac_nids,
10347 .adc_nids = alc883_adc_nids_alt,
10348 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10349 .capsrc_nids = alc883_capsrc_nids,
10350 .dig_out_nid = ALC883_DIGOUT_NID,
10351 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10352 .channel_mode = alc883_3ST_2ch_modes,
10353 .input_mux = &alc883_capture_source,
10354 .unsol_event = alc883_targa_unsol_event,
10355 .setup = alc882_targa_setup,
10356 .init_hook = alc882_targa_automute,
10357 },
10358 [ALC883_TARGA_8ch_DIG] = {
10359 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10360 alc883_chmode_mixer },
10361 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10362 alc883_targa_verbs },
10363 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10364 .dac_nids = alc883_dac_nids,
10365 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10366 .adc_nids = alc883_adc_nids_rev,
10367 .capsrc_nids = alc883_capsrc_nids_rev,
10368 .dig_out_nid = ALC883_DIGOUT_NID,
10369 .dig_in_nid = ALC883_DIGIN_NID,
10370 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10371 .channel_mode = alc883_4ST_8ch_modes,
10372 .need_dac_fix = 1,
10373 .input_mux = &alc883_capture_source,
10374 .unsol_event = alc883_targa_unsol_event,
10375 .setup = alc882_targa_setup,
10376 .init_hook = alc882_targa_automute,
10377 },
10378 [ALC883_ACER] = {
10379 .mixers = { alc883_base_mixer },
10380 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10381 * and the headphone jack. Turn this on and rely on the
10382 * standard mute methods whenever the user wants to turn
10383 * these outputs off.
10384 */
10385 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .dac_nids = alc883_dac_nids,
10388 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10389 .channel_mode = alc883_3ST_2ch_modes,
10390 .input_mux = &alc883_capture_source,
10391 },
10392 [ALC883_ACER_ASPIRE] = {
10393 .mixers = { alc883_acer_aspire_mixer },
10394 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10395 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10396 .dac_nids = alc883_dac_nids,
10397 .dig_out_nid = ALC883_DIGOUT_NID,
10398 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10399 .channel_mode = alc883_3ST_2ch_modes,
10400 .input_mux = &alc883_capture_source,
10401 .unsol_event = alc_sku_unsol_event,
10402 .setup = alc883_acer_aspire_setup,
10403 .init_hook = alc_hp_automute,
10404 },
10405 [ALC888_ACER_ASPIRE_4930G] = {
10406 .mixers = { alc888_acer_aspire_4930g_mixer,
10407 alc883_chmode_mixer },
10408 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10409 alc888_acer_aspire_4930g_verbs },
10410 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10411 .dac_nids = alc883_dac_nids,
10412 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10413 .adc_nids = alc883_adc_nids_rev,
10414 .capsrc_nids = alc883_capsrc_nids_rev,
10415 .dig_out_nid = ALC883_DIGOUT_NID,
10416 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10417 .channel_mode = alc883_3ST_6ch_modes,
10418 .need_dac_fix = 1,
10419 .const_channel_count = 6,
10420 .num_mux_defs =
10421 ARRAY_SIZE(alc888_2_capture_sources),
10422 .input_mux = alc888_2_capture_sources,
10423 .unsol_event = alc_sku_unsol_event,
10424 .setup = alc888_acer_aspire_4930g_setup,
10425 .init_hook = alc_hp_automute,
10426 },
10427 [ALC888_ACER_ASPIRE_6530G] = {
10428 .mixers = { alc888_acer_aspire_6530_mixer },
10429 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10430 alc888_acer_aspire_6530g_verbs },
10431 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10432 .dac_nids = alc883_dac_nids,
10433 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10434 .adc_nids = alc883_adc_nids_rev,
10435 .capsrc_nids = alc883_capsrc_nids_rev,
10436 .dig_out_nid = ALC883_DIGOUT_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10438 .channel_mode = alc883_3ST_2ch_modes,
10439 .num_mux_defs =
10440 ARRAY_SIZE(alc888_2_capture_sources),
10441 .input_mux = alc888_acer_aspire_6530_sources,
10442 .unsol_event = alc_sku_unsol_event,
10443 .setup = alc888_acer_aspire_6530g_setup,
10444 .init_hook = alc_hp_automute,
10445 },
10446 [ALC888_ACER_ASPIRE_8930G] = {
10447 .mixers = { alc889_acer_aspire_8930g_mixer,
10448 alc883_chmode_mixer },
10449 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10450 alc889_acer_aspire_8930g_verbs,
10451 alc889_eapd_verbs},
10452 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10453 .dac_nids = alc883_dac_nids,
10454 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10455 .adc_nids = alc889_adc_nids,
10456 .capsrc_nids = alc889_capsrc_nids,
10457 .dig_out_nid = ALC883_DIGOUT_NID,
10458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10459 .channel_mode = alc883_3ST_6ch_modes,
10460 .need_dac_fix = 1,
10461 .const_channel_count = 6,
10462 .num_mux_defs =
10463 ARRAY_SIZE(alc889_capture_sources),
10464 .input_mux = alc889_capture_sources,
10465 .unsol_event = alc_sku_unsol_event,
10466 .setup = alc889_acer_aspire_8930g_setup,
10467 .init_hook = alc_hp_automute,
10468#ifdef CONFIG_SND_HDA_POWER_SAVE
10469 .power_hook = alc_power_eapd,
10470#endif
10471 },
10472 [ALC888_ACER_ASPIRE_7730G] = {
10473 .mixers = { alc883_3ST_6ch_mixer,
10474 alc883_chmode_mixer },
10475 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10476 alc888_acer_aspire_7730G_verbs },
10477 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10478 .dac_nids = alc883_dac_nids,
10479 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10480 .adc_nids = alc883_adc_nids_rev,
10481 .capsrc_nids = alc883_capsrc_nids_rev,
10482 .dig_out_nid = ALC883_DIGOUT_NID,
10483 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10484 .channel_mode = alc883_3ST_6ch_modes,
10485 .need_dac_fix = 1,
10486 .const_channel_count = 6,
10487 .input_mux = &alc883_capture_source,
10488 .unsol_event = alc_sku_unsol_event,
10489 .setup = alc888_acer_aspire_7730g_setup,
10490 .init_hook = alc_hp_automute,
10491 },
10492 [ALC883_MEDION] = {
10493 .mixers = { alc883_fivestack_mixer,
10494 alc883_chmode_mixer },
10495 .init_verbs = { alc883_init_verbs,
10496 alc883_medion_eapd_verbs },
10497 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10498 .dac_nids = alc883_dac_nids,
10499 .adc_nids = alc883_adc_nids_alt,
10500 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10501 .capsrc_nids = alc883_capsrc_nids,
10502 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10503 .channel_mode = alc883_sixstack_modes,
10504 .input_mux = &alc883_capture_source,
10505 },
10506 [ALC883_MEDION_WIM2160] = {
10507 .mixers = { alc883_medion_wim2160_mixer },
10508 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10509 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10510 .dac_nids = alc883_dac_nids,
10511 .dig_out_nid = ALC883_DIGOUT_NID,
10512 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10513 .adc_nids = alc883_adc_nids,
10514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10515 .channel_mode = alc883_3ST_2ch_modes,
10516 .input_mux = &alc883_capture_source,
10517 .unsol_event = alc_sku_unsol_event,
10518 .setup = alc883_medion_wim2160_setup,
10519 .init_hook = alc_hp_automute,
10520 },
10521 [ALC883_LAPTOP_EAPD] = {
10522 .mixers = { alc883_base_mixer },
10523 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
10526 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10527 .channel_mode = alc883_3ST_2ch_modes,
10528 .input_mux = &alc883_capture_source,
10529 },
10530 [ALC883_CLEVO_M540R] = {
10531 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10532 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10533 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10534 .dac_nids = alc883_dac_nids,
10535 .dig_out_nid = ALC883_DIGOUT_NID,
10536 .dig_in_nid = ALC883_DIGIN_NID,
10537 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10538 .channel_mode = alc883_3ST_6ch_clevo_modes,
10539 .need_dac_fix = 1,
10540 .input_mux = &alc883_capture_source,
10541 /* This machine has the hardware HP auto-muting, thus
10542 * we need no software mute via unsol event
10543 */
10544 },
10545 [ALC883_CLEVO_M720] = {
10546 .mixers = { alc883_clevo_m720_mixer },
10547 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10548 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10549 .dac_nids = alc883_dac_nids,
10550 .dig_out_nid = ALC883_DIGOUT_NID,
10551 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10552 .channel_mode = alc883_3ST_2ch_modes,
10553 .input_mux = &alc883_capture_source,
10554 .unsol_event = alc883_clevo_m720_unsol_event,
10555 .setup = alc883_clevo_m720_setup,
10556 .init_hook = alc883_clevo_m720_init_hook,
10557 },
10558 [ALC883_LENOVO_101E_2ch] = {
10559 .mixers = { alc883_lenovo_101e_2ch_mixer},
10560 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10561 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10562 .dac_nids = alc883_dac_nids,
10563 .adc_nids = alc883_adc_nids_alt,
10564 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10565 .capsrc_nids = alc883_capsrc_nids,
10566 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10567 .channel_mode = alc883_3ST_2ch_modes,
10568 .input_mux = &alc883_lenovo_101e_capture_source,
10569 .setup = alc883_lenovo_101e_setup,
10570 .unsol_event = alc_sku_unsol_event,
10571 .init_hook = alc_inithook,
10572 },
10573 [ALC883_LENOVO_NB0763] = {
10574 .mixers = { alc883_lenovo_nb0763_mixer },
10575 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10576 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10577 .dac_nids = alc883_dac_nids,
10578 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10579 .channel_mode = alc883_3ST_2ch_modes,
10580 .need_dac_fix = 1,
10581 .input_mux = &alc883_lenovo_nb0763_capture_source,
10582 .unsol_event = alc_sku_unsol_event,
10583 .setup = alc883_lenovo_nb0763_setup,
10584 .init_hook = alc_hp_automute,
10585 },
10586 [ALC888_LENOVO_MS7195_DIG] = {
10587 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10588 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10589 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10590 .dac_nids = alc883_dac_nids,
10591 .dig_out_nid = ALC883_DIGOUT_NID,
10592 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10593 .channel_mode = alc883_3ST_6ch_modes,
10594 .need_dac_fix = 1,
10595 .input_mux = &alc883_capture_source,
10596 .unsol_event = alc_sku_unsol_event,
10597 .setup = alc888_lenovo_ms7195_setup,
10598 .init_hook = alc_inithook,
10599 },
10600 [ALC883_HAIER_W66] = {
10601 .mixers = { alc883_targa_2ch_mixer},
10602 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10603 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10604 .dac_nids = alc883_dac_nids,
10605 .dig_out_nid = ALC883_DIGOUT_NID,
10606 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10607 .channel_mode = alc883_3ST_2ch_modes,
10608 .input_mux = &alc883_capture_source,
10609 .unsol_event = alc_sku_unsol_event,
10610 .setup = alc883_haier_w66_setup,
10611 .init_hook = alc_hp_automute,
10612 },
10613 [ALC888_3ST_HP] = {
10614 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10615 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10616 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10617 .dac_nids = alc883_dac_nids,
10618 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10619 .channel_mode = alc888_3st_hp_modes,
10620 .need_dac_fix = 1,
10621 .input_mux = &alc883_capture_source,
10622 .unsol_event = alc_sku_unsol_event,
10623 .setup = alc888_3st_hp_setup,
10624 .init_hook = alc_hp_automute,
10625 },
10626 [ALC888_6ST_DELL] = {
10627 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10628 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10629 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10630 .dac_nids = alc883_dac_nids,
10631 .dig_out_nid = ALC883_DIGOUT_NID,
10632 .dig_in_nid = ALC883_DIGIN_NID,
10633 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10634 .channel_mode = alc883_sixstack_modes,
10635 .input_mux = &alc883_capture_source,
10636 .unsol_event = alc_sku_unsol_event,
10637 .setup = alc888_6st_dell_setup,
10638 .init_hook = alc_hp_automute,
10639 },
10640 [ALC883_MITAC] = {
10641 .mixers = { alc883_mitac_mixer },
10642 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10643 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10644 .dac_nids = alc883_dac_nids,
10645 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10646 .channel_mode = alc883_3ST_2ch_modes,
10647 .input_mux = &alc883_capture_source,
10648 .unsol_event = alc_sku_unsol_event,
10649 .setup = alc883_mitac_setup,
10650 .init_hook = alc_hp_automute,
10651 },
10652 [ALC883_FUJITSU_PI2515] = {
10653 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10654 .init_verbs = { alc883_init_verbs,
10655 alc883_2ch_fujitsu_pi2515_verbs},
10656 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10657 .dac_nids = alc883_dac_nids,
10658 .dig_out_nid = ALC883_DIGOUT_NID,
10659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10660 .channel_mode = alc883_3ST_2ch_modes,
10661 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10662 .unsol_event = alc_sku_unsol_event,
10663 .setup = alc883_2ch_fujitsu_pi2515_setup,
10664 .init_hook = alc_hp_automute,
10665 },
10666 [ALC888_FUJITSU_XA3530] = {
10667 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10668 .init_verbs = { alc883_init_verbs,
10669 alc888_fujitsu_xa3530_verbs },
10670 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10671 .dac_nids = alc883_dac_nids,
10672 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10673 .adc_nids = alc883_adc_nids_rev,
10674 .capsrc_nids = alc883_capsrc_nids_rev,
10675 .dig_out_nid = ALC883_DIGOUT_NID,
10676 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10677 .channel_mode = alc888_4ST_8ch_intel_modes,
10678 .num_mux_defs =
10679 ARRAY_SIZE(alc888_2_capture_sources),
10680 .input_mux = alc888_2_capture_sources,
10681 .unsol_event = alc_sku_unsol_event,
10682 .setup = alc888_fujitsu_xa3530_setup,
10683 .init_hook = alc_hp_automute,
10684 },
10685 [ALC888_LENOVO_SKY] = {
10686 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10687 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10688 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10689 .dac_nids = alc883_dac_nids,
10690 .dig_out_nid = ALC883_DIGOUT_NID,
10691 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10692 .channel_mode = alc883_sixstack_modes,
10693 .need_dac_fix = 1,
10694 .input_mux = &alc883_lenovo_sky_capture_source,
10695 .unsol_event = alc_sku_unsol_event,
10696 .setup = alc888_lenovo_sky_setup,
10697 .init_hook = alc_hp_automute,
10698 },
10699 [ALC888_ASUS_M90V] = {
10700 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10701 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10702 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10703 .dac_nids = alc883_dac_nids,
10704 .dig_out_nid = ALC883_DIGOUT_NID,
10705 .dig_in_nid = ALC883_DIGIN_NID,
10706 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10707 .channel_mode = alc883_3ST_6ch_modes,
10708 .need_dac_fix = 1,
10709 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10710 .unsol_event = alc_sku_unsol_event,
10711 .setup = alc883_mode2_setup,
10712 .init_hook = alc_inithook,
10713 },
10714 [ALC888_ASUS_EEE1601] = {
10715 .mixers = { alc883_asus_eee1601_mixer },
10716 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10717 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10718 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10719 .dac_nids = alc883_dac_nids,
10720 .dig_out_nid = ALC883_DIGOUT_NID,
10721 .dig_in_nid = ALC883_DIGIN_NID,
10722 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10723 .channel_mode = alc883_3ST_2ch_modes,
10724 .need_dac_fix = 1,
10725 .input_mux = &alc883_asus_eee1601_capture_source,
10726 .unsol_event = alc_sku_unsol_event,
10727 .init_hook = alc883_eee1601_inithook,
10728 },
10729 [ALC1200_ASUS_P5Q] = {
10730 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10731 .init_verbs = { alc883_init_verbs },
10732 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10733 .dac_nids = alc883_dac_nids,
10734 .dig_out_nid = ALC1200_DIGOUT_NID,
10735 .dig_in_nid = ALC883_DIGIN_NID,
10736 .slave_dig_outs = alc1200_slave_dig_outs,
10737 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10738 .channel_mode = alc883_sixstack_modes,
10739 .input_mux = &alc883_capture_source,
10740 },
10741 [ALC889A_MB31] = {
10742 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10743 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10744 alc880_gpio1_init_verbs },
10745 .adc_nids = alc883_adc_nids,
10746 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10747 .capsrc_nids = alc883_capsrc_nids,
10748 .dac_nids = alc883_dac_nids,
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .channel_mode = alc889A_mb31_6ch_modes,
10751 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10752 .input_mux = &alc889A_mb31_capture_source,
10753 .dig_out_nid = ALC883_DIGOUT_NID,
10754 .unsol_event = alc889A_mb31_unsol_event,
10755 .init_hook = alc889A_mb31_automute,
10756 },
10757 [ALC883_SONY_VAIO_TT] = {
10758 .mixers = { alc883_vaiott_mixer },
10759 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10760 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10761 .dac_nids = alc883_dac_nids,
10762 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10763 .channel_mode = alc883_3ST_2ch_modes,
10764 .input_mux = &alc883_capture_source,
10765 .unsol_event = alc_sku_unsol_event,
10766 .setup = alc883_vaiott_setup,
10767 .init_hook = alc_hp_automute,
10768 },
10769};
10770
10771
10772/* 3933/*
10773 * Pin config fixes 3934 * Pin config fixes
10774 */ 3935 */
@@ -10821,80 +3982,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
10821/* 3982/*
10822 * BIOS auto configuration 3983 * BIOS auto configuration
10823 */ 3984 */
10824static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
10825{
10826 struct alc_spec *spec = codec->spec;
10827 hda_nid_t nid;
10828
10829 nid = spec->adc_nids[adc_idx];
10830 /* mute ADC */
10831 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) {
10832 snd_hda_codec_write(codec, nid, 0,
10833 AC_VERB_SET_AMP_GAIN_MUTE,
10834 AMP_IN_MUTE(0));
10835 return;
10836 }
10837 if (!spec->capsrc_nids)
10838 return;
10839 nid = spec->capsrc_nids[adc_idx];
10840 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
10841 snd_hda_codec_write(codec, nid, 0,
10842 AC_VERB_SET_AMP_GAIN_MUTE,
10843 AMP_OUT_MUTE);
10844}
10845
10846static void alc_auto_init_input_src(struct hda_codec *codec)
10847{
10848 struct alc_spec *spec = codec->spec;
10849 int c, nums;
10850
10851 for (c = 0; c < spec->num_adc_nids; c++)
10852 alc_auto_init_adc(codec, c);
10853 if (spec->dyn_adc_switch)
10854 nums = 1;
10855 else
10856 nums = spec->num_adc_nids;
10857 for (c = 0; c < nums; c++)
10858 alc_mux_select(codec, 0, spec->cur_mux[c], true);
10859}
10860
10861/* add mic boosts if needed */
10862static int alc_auto_add_mic_boost(struct hda_codec *codec)
10863{
10864 struct alc_spec *spec = codec->spec;
10865 struct auto_pin_cfg *cfg = &spec->autocfg;
10866 int i, err;
10867 int type_idx = 0;
10868 hda_nid_t nid;
10869 const char *prev_label = NULL;
10870
10871 for (i = 0; i < cfg->num_inputs; i++) {
10872 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10873 break;
10874 nid = cfg->inputs[i].pin;
10875 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10876 const char *label;
10877 char boost_label[32];
10878
10879 label = hda_get_autocfg_input_label(codec, cfg, i);
10880 if (prev_label && !strcmp(label, prev_label))
10881 type_idx++;
10882 else
10883 type_idx = 0;
10884 prev_label = label;
10885
10886 snprintf(boost_label, sizeof(boost_label),
10887 "%s Boost Volume", label);
10888 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10889 boost_label, type_idx,
10890 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10891 if (err < 0)
10892 return err;
10893 }
10894 }
10895 return 0;
10896}
10897
10898/* almost identical with ALC880 parser... */ 3985/* almost identical with ALC880 parser... */
10899static int alc882_parse_auto_config(struct hda_codec *codec) 3986static int alc882_parse_auto_config(struct hda_codec *codec)
10900{ 3987{
@@ -10960,6 +4047,12 @@ static void alc882_auto_init(struct hda_codec *codec)
10960 alc_inithook(codec); 4047 alc_inithook(codec);
10961} 4048}
10962 4049
4050/*
4051 */
4052#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4053#include "alc882_quirks.c"
4054#endif
4055
10963static int patch_alc882(struct hda_codec *codec) 4056static int patch_alc882(struct hda_codec *codec)
10964{ 4057{
10965 struct alc_spec *spec; 4058 struct alc_spec *spec;
@@ -10983,39 +4076,41 @@ static int patch_alc882(struct hda_codec *codec)
10983 break; 4076 break;
10984 } 4077 }
10985 4078
10986 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 4079 board_config = alc_board_config(codec, ALC882_MODEL_LAST,
10987 alc882_models, 4080 alc882_models, alc882_cfg_tbl);
10988 alc882_cfg_tbl);
10989 4081
10990 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 4082 if (board_config < 0)
10991 board_config = snd_hda_check_board_codec_sid_config(codec, 4083 board_config = alc_board_codec_sid_config(codec,
10992 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 4084 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10993 4085
10994 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 4086 if (board_config < 0) {
10995 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4087 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10996 codec->chip_name); 4088 codec->chip_name);
10997 board_config = ALC882_AUTO; 4089 board_config = ALC_MODEL_AUTO;
10998 } 4090 }
10999 4091
11000 if (board_config == ALC882_AUTO) { 4092 if (board_config == ALC_MODEL_AUTO) {
11001 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); 4093 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11002 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4094 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11003 } 4095 }
11004 4096
11005 alc_auto_parse_customize_define(codec); 4097 alc_auto_parse_customize_define(codec);
11006 4098
11007 if (board_config == ALC882_AUTO) { 4099 if (board_config == ALC_MODEL_AUTO) {
11008 /* automatic parse from the BIOS config */ 4100 /* automatic parse from the BIOS config */
11009 err = alc882_parse_auto_config(codec); 4101 err = alc882_parse_auto_config(codec);
11010 if (err < 0) { 4102 if (err < 0) {
11011 alc_free(codec); 4103 alc_free(codec);
11012 return err; 4104 return err;
11013 } else if (!err) { 4105 }
4106#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4107 else if (!err) {
11014 printk(KERN_INFO 4108 printk(KERN_INFO
11015 "hda_codec: Cannot set up configuration " 4109 "hda_codec: Cannot set up configuration "
11016 "from BIOS. Using base mode...\n"); 4110 "from BIOS. Using base mode...\n");
11017 board_config = ALC882_3ST_DIG; 4111 board_config = ALC882_3ST_DIG;
11018 } 4112 }
4113#endif
11019 } 4114 }
11020 4115
11021 if (has_cdefine_beep(codec)) { 4116 if (has_cdefine_beep(codec)) {
@@ -11026,7 +4121,7 @@ static int patch_alc882(struct hda_codec *codec)
11026 } 4121 }
11027 } 4122 }
11028 4123
11029 if (board_config != ALC882_AUTO) 4124 if (board_config != ALC_MODEL_AUTO)
11030 setup_preset(codec, &alc882_presets[board_config]); 4125 setup_preset(codec, &alc882_presets[board_config]);
11031 4126
11032 if (!spec->adc_nids && spec->input_mux) { 4127 if (!spec->adc_nids && spec->input_mux) {
@@ -11045,7 +4140,7 @@ static int patch_alc882(struct hda_codec *codec)
11045 spec->vmaster_nid = 0x0c; 4140 spec->vmaster_nid = 0x0c;
11046 4141
11047 codec->patch_ops = alc_patch_ops; 4142 codec->patch_ops = alc_patch_ops;
11048 if (board_config == ALC882_AUTO) 4143 if (board_config == ALC_MODEL_AUTO)
11049 spec->init_hook = alc882_auto_init; 4144 spec->init_hook = alc882_auto_init;
11050 4145
11051 alc_init_jacks(codec); 4146 alc_init_jacks(codec);
@@ -11062,798 +4157,6 @@ static int patch_alc882(struct hda_codec *codec)
11062 * ALC262 support 4157 * ALC262 support
11063 */ 4158 */
11064 4159
11065#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11066#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11067
11068#define alc262_dac_nids alc260_dac_nids
11069#define alc262_adc_nids alc882_adc_nids
11070#define alc262_adc_nids_alt alc882_adc_nids_alt
11071#define alc262_capsrc_nids alc882_capsrc_nids
11072#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11073
11074#define alc262_modes alc260_modes
11075#define alc262_capture_source alc882_capture_source
11076
11077static const hda_nid_t alc262_dmic_adc_nids[1] = {
11078 /* ADC0 */
11079 0x09
11080};
11081
11082static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11083
11084static const struct snd_kcontrol_new alc262_base_mixer[] = {
11085 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11086 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11087 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11088 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11089 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11090 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11094 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11095 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11096 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11099 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11100 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11101 { } /* end */
11102};
11103
11104/* update HP, line and mono-out pins according to the master switch */
11105#define alc262_hp_master_update alc260_hp_master_update
11106
11107static void alc262_hp_bpc_setup(struct hda_codec *codec)
11108{
11109 struct alc_spec *spec = codec->spec;
11110
11111 spec->autocfg.hp_pins[0] = 0x1b;
11112 spec->autocfg.speaker_pins[0] = 0x16;
11113 spec->automute = 1;
11114 spec->automute_mode = ALC_AUTOMUTE_PIN;
11115}
11116
11117static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11118{
11119 struct alc_spec *spec = codec->spec;
11120
11121 spec->autocfg.hp_pins[0] = 0x15;
11122 spec->autocfg.speaker_pins[0] = 0x16;
11123 spec->automute = 1;
11124 spec->automute_mode = ALC_AUTOMUTE_PIN;
11125}
11126
11127#define alc262_hp_master_sw_get alc260_hp_master_sw_get
11128#define alc262_hp_master_sw_put alc260_hp_master_sw_put
11129
11130#define ALC262_HP_MASTER_SWITCH \
11131 { \
11132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11133 .name = "Master Playback Switch", \
11134 .info = snd_ctl_boolean_mono_info, \
11135 .get = alc262_hp_master_sw_get, \
11136 .put = alc262_hp_master_sw_put, \
11137 }, \
11138 { \
11139 .iface = NID_MAPPING, \
11140 .name = "Master Playback Switch", \
11141 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11142 }
11143
11144
11145static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11146 ALC262_HP_MASTER_SWITCH,
11147 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11148 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11149 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11150 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11151 HDA_OUTPUT),
11152 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11153 HDA_OUTPUT),
11154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11155 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11156 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11157 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11158 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11159 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11160 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11161 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11162 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11163 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11164 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11165 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11166 { } /* end */
11167};
11168
11169static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11170 ALC262_HP_MASTER_SWITCH,
11171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11172 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11175 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11176 HDA_OUTPUT),
11177 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11178 HDA_OUTPUT),
11179 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11180 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11181 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11182 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11183 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11184 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11185 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11186 { } /* end */
11187};
11188
11189static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11190 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11191 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11192 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11193 { } /* end */
11194};
11195
11196/* mute/unmute internal speaker according to the hp jack and mute state */
11197static void alc262_hp_t5735_setup(struct hda_codec *codec)
11198{
11199 struct alc_spec *spec = codec->spec;
11200
11201 spec->autocfg.hp_pins[0] = 0x15;
11202 spec->autocfg.speaker_pins[0] = 0x14;
11203 spec->automute = 1;
11204 spec->automute_mode = ALC_AUTOMUTE_PIN;
11205}
11206
11207static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11208 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11209 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11210 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11215 { } /* end */
11216};
11217
11218static const struct hda_verb alc262_hp_t5735_verbs[] = {
11219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11221
11222 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11223 { }
11224};
11225
11226static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11227 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11229 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11230 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11233 { } /* end */
11234};
11235
11236static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11237 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11238 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11239 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11240 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11241 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11242 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11244 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11245 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11247 {}
11248};
11249
11250static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11251 .num_items = 1,
11252 .items = {
11253 { "Line", 0x1 },
11254 },
11255};
11256
11257/* bind hp and internal speaker mute (with plug check) as master switch */
11258#define alc262_hippo_master_update alc262_hp_master_update
11259#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11260#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11261
11262#define ALC262_HIPPO_MASTER_SWITCH \
11263 { \
11264 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11265 .name = "Master Playback Switch", \
11266 .info = snd_ctl_boolean_mono_info, \
11267 .get = alc262_hippo_master_sw_get, \
11268 .put = alc262_hippo_master_sw_put, \
11269 }, \
11270 { \
11271 .iface = NID_MAPPING, \
11272 .name = "Master Playback Switch", \
11273 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11274 (SUBDEV_SPEAKER(0) << 16), \
11275 }
11276
11277static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11278 ALC262_HIPPO_MASTER_SWITCH,
11279 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11280 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11281 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11287 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11288 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11289 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11291 { } /* end */
11292};
11293
11294static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11295 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11296 ALC262_HIPPO_MASTER_SWITCH,
11297 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11298 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11299 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11300 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11303 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11304 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11305 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11306 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11307 { } /* end */
11308};
11309
11310/* mute/unmute internal speaker according to the hp jack and mute state */
11311static void alc262_hippo_setup(struct hda_codec *codec)
11312{
11313 struct alc_spec *spec = codec->spec;
11314
11315 spec->autocfg.hp_pins[0] = 0x15;
11316 spec->autocfg.speaker_pins[0] = 0x14;
11317 spec->automute = 1;
11318 spec->automute_mode = ALC_AUTOMUTE_AMP;
11319}
11320
11321static void alc262_hippo1_setup(struct hda_codec *codec)
11322{
11323 struct alc_spec *spec = codec->spec;
11324
11325 spec->autocfg.hp_pins[0] = 0x1b;
11326 spec->autocfg.speaker_pins[0] = 0x14;
11327 spec->automute = 1;
11328 spec->automute_mode = ALC_AUTOMUTE_AMP;
11329}
11330
11331
11332static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11333 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11334 ALC262_HIPPO_MASTER_SWITCH,
11335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11336 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11337 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11338 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11339 { } /* end */
11340};
11341
11342static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11343 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11344 ALC262_HIPPO_MASTER_SWITCH,
11345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11348 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11349 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11350 { } /* end */
11351};
11352
11353static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11354 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11355 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11356 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11357 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11362 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11363 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11364 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11365 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11366 { } /* end */
11367};
11368
11369static const struct hda_verb alc262_tyan_verbs[] = {
11370 /* Headphone automute */
11371 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11372 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11374
11375 /* P11 AUX_IN, white 4-pin connector */
11376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11377 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11378 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11379 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11380
11381 {}
11382};
11383
11384/* unsolicited event for HP jack sensing */
11385static void alc262_tyan_setup(struct hda_codec *codec)
11386{
11387 struct alc_spec *spec = codec->spec;
11388
11389 spec->autocfg.hp_pins[0] = 0x1b;
11390 spec->autocfg.speaker_pins[0] = 0x15;
11391 spec->automute = 1;
11392 spec->automute_mode = ALC_AUTOMUTE_AMP;
11393}
11394
11395
11396#define alc262_capture_mixer alc882_capture_mixer
11397#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11398
11399/*
11400 * generic initialization of ADC, input mixers and output mixers
11401 */
11402static const struct hda_verb alc262_init_verbs[] = {
11403 /*
11404 * Unmute ADC0-2 and set the default input to mic-in
11405 */
11406 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11408 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11410 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11411 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11412
11413 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11414 * mixer widget
11415 * Note: PASD motherboards uses the Line In 2 as the input for
11416 * front panel mic (mic 2)
11417 */
11418 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11419 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11420 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11421 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11422 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11423 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11424
11425 /*
11426 * Set up output mixers (0x0c - 0x0e)
11427 */
11428 /* set vol=0 to output mixers */
11429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11432 /* set up input amps for analog loopback */
11433 /* Amp Indices: DAC = 0, mixer = 1 */
11434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11436 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11437 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11438 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11439 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11440
11441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11443 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11444 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11445 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11446 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11447
11448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11449 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11453
11454 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11456
11457 /* FIXME: use matrix-type input source selection */
11458 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11459 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11462 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11463 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11464 /* Input mixer2 */
11465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11469 /* Input mixer3 */
11470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11474
11475 { }
11476};
11477
11478static const struct hda_verb alc262_eapd_verbs[] = {
11479 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11480 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11481 { }
11482};
11483
11484static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11485 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11486 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11487 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11488
11489 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11490 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11491 {}
11492};
11493
11494static const struct hda_verb alc262_sony_unsol_verbs[] = {
11495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11496 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11497 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11498
11499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11500 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11501 {}
11502};
11503
11504static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11505 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11506 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11510 { } /* end */
11511};
11512
11513static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11514 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11518 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11519 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11520 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11521 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11522 {}
11523};
11524
11525static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11526{
11527 struct alc_spec *spec = codec->spec;
11528
11529 spec->autocfg.hp_pins[0] = 0x15;
11530 spec->autocfg.speaker_pins[0] = 0x14;
11531 spec->ext_mic_pin = 0x18;
11532 spec->int_mic_pin = 0x12;
11533 spec->auto_mic = 1;
11534 spec->automute = 1;
11535 spec->automute_mode = ALC_AUTOMUTE_PIN;
11536}
11537
11538/*
11539 * nec model
11540 * 0x15 = headphone
11541 * 0x16 = internal speaker
11542 * 0x18 = external mic
11543 */
11544
11545static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11546 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11547 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11548
11549 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11550 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11551 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11552
11553 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11555 { } /* end */
11556};
11557
11558static const struct hda_verb alc262_nec_verbs[] = {
11559 /* Unmute Speaker */
11560 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11561
11562 /* Headphone */
11563 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11565
11566 /* External mic to headphone */
11567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11568 /* External mic to speaker */
11569 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11570 {}
11571};
11572
11573/*
11574 * fujitsu model
11575 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11576 * 0x1b = port replicator headphone out
11577 */
11578
11579#define ALC_HP_EVENT ALC880_HP_EVENT
11580
11581static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11582 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11584 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11586 {}
11587};
11588
11589static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11590 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11592 {}
11593};
11594
11595static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11596 /* Front Mic pin: input vref at 50% */
11597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11599 {}
11600};
11601
11602static const struct hda_input_mux alc262_fujitsu_capture_source = {
11603 .num_items = 3,
11604 .items = {
11605 { "Mic", 0x0 },
11606 { "Internal Mic", 0x1 },
11607 { "CD", 0x4 },
11608 },
11609};
11610
11611static const struct hda_input_mux alc262_HP_capture_source = {
11612 .num_items = 5,
11613 .items = {
11614 { "Mic", 0x0 },
11615 { "Front Mic", 0x1 },
11616 { "Line", 0x2 },
11617 { "CD", 0x4 },
11618 { "AUX IN", 0x6 },
11619 },
11620};
11621
11622static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11623 .num_items = 4,
11624 .items = {
11625 { "Mic", 0x0 },
11626 { "Front Mic", 0x2 },
11627 { "Line", 0x1 },
11628 { "CD", 0x4 },
11629 },
11630};
11631
11632static void alc262_fujitsu_setup(struct hda_codec *codec)
11633{
11634 struct alc_spec *spec = codec->spec;
11635
11636 spec->autocfg.hp_pins[0] = 0x14;
11637 spec->autocfg.hp_pins[1] = 0x1b;
11638 spec->autocfg.speaker_pins[0] = 0x15;
11639 spec->automute = 1;
11640 spec->automute_mode = ALC_AUTOMUTE_AMP;
11641}
11642
11643/* bind volumes of both NID 0x0c and 0x0d */
11644static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11645 .ops = &snd_hda_bind_vol,
11646 .values = {
11647 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11648 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11649 0
11650 },
11651};
11652
11653static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11654 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11655 {
11656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11657 .name = "Master Playback Switch",
11658 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11659 .info = snd_ctl_boolean_mono_info,
11660 .get = alc262_hp_master_sw_get,
11661 .put = alc262_hp_master_sw_put,
11662 },
11663 {
11664 .iface = NID_MAPPING,
11665 .name = "Master Playback Switch",
11666 .private_value = 0x1b,
11667 },
11668 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11669 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11670 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11673 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11674 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11675 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11676 { } /* end */
11677};
11678
11679static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11680{
11681 struct alc_spec *spec = codec->spec;
11682
11683 spec->autocfg.hp_pins[0] = 0x1b;
11684 spec->autocfg.speaker_pins[0] = 0x14;
11685 spec->autocfg.speaker_pins[1] = 0x16;
11686 spec->automute = 1;
11687 spec->automute_mode = ALC_AUTOMUTE_AMP;
11688}
11689
11690static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11691 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11692 {
11693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11694 .name = "Master Playback Switch",
11695 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11696 .info = snd_ctl_boolean_mono_info,
11697 .get = alc262_hp_master_sw_get,
11698 .put = alc262_hp_master_sw_put,
11699 },
11700 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11701 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11702 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11705 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11706 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11707 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11708 { } /* end */
11709};
11710
11711static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11712 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11713 ALC262_HIPPO_MASTER_SWITCH,
11714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11716 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11717 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11718 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11719 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11720 { } /* end */
11721};
11722
11723/* additional init verbs for Benq laptops */
11724static const struct hda_verb alc262_EAPD_verbs[] = {
11725 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11726 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11727 {}
11728};
11729
11730static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11731 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11732 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11733
11734 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11735 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11736 {}
11737};
11738
11739/* Samsung Q1 Ultra Vista model setup */
11740static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
11741 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11742 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11745 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11746 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11747 { } /* end */
11748};
11749
11750static const struct hda_verb alc262_ultra_verbs[] = {
11751 /* output mixer */
11752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11755 /* speaker */
11756 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11757 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11759 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11760 /* HP */
11761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11765 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11766 /* internal mic */
11767 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11769 /* ADC, choose mic */
11770 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11771 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11773 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11774 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11775 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11776 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11777 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11780 {}
11781};
11782
11783/* mute/unmute internal speaker according to the hp jack and mute state */
11784static void alc262_ultra_automute(struct hda_codec *codec)
11785{
11786 struct alc_spec *spec = codec->spec;
11787 unsigned int mute;
11788
11789 mute = 0;
11790 /* auto-mute only when HP is used as HP */
11791 if (!spec->cur_mux[0]) {
11792 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11793 if (spec->jack_present)
11794 mute = HDA_AMP_MUTE;
11795 }
11796 /* mute/unmute internal speaker */
11797 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11798 HDA_AMP_MUTE, mute);
11799 /* mute/unmute HP */
11800 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11801 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11802}
11803
11804/* unsolicited event for HP jack sensing */
11805static void alc262_ultra_unsol_event(struct hda_codec *codec,
11806 unsigned int res)
11807{
11808 if ((res >> 26) != ALC880_HP_EVENT)
11809 return;
11810 alc262_ultra_automute(codec);
11811}
11812
11813static const struct hda_input_mux alc262_ultra_capture_source = {
11814 .num_items = 2,
11815 .items = {
11816 { "Mic", 0x1 },
11817 { "Headphone", 0x7 },
11818 },
11819};
11820
11821static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11822 struct snd_ctl_elem_value *ucontrol)
11823{
11824 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11825 struct alc_spec *spec = codec->spec;
11826 int ret;
11827
11828 ret = alc_mux_enum_put(kcontrol, ucontrol);
11829 if (!ret)
11830 return 0;
11831 /* reprogram the HP pin as mic or HP according to the input source */
11832 snd_hda_codec_write_cache(codec, 0x15, 0,
11833 AC_VERB_SET_PIN_WIDGET_CONTROL,
11834 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11835 alc262_ultra_automute(codec); /* mute/unmute HP */
11836 return ret;
11837}
11838
11839static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11840 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11841 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11842 {
11843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11844 .name = "Capture Source",
11845 .info = alc_mux_enum_info,
11846 .get = alc_mux_enum_get,
11847 .put = alc262_ultra_mux_enum_put,
11848 },
11849 {
11850 .iface = NID_MAPPING,
11851 .name = "Capture Source",
11852 .private_value = 0x15,
11853 },
11854 { } /* end */
11855};
11856
11857/* We use two mixers depending on the output pin; 0x16 is a mono output 4160/* We use two mixers depending on the output pin; 0x16 is a mono output
11858 * and thus it's bound with a different mixer. 4161 * and thus it's bound with a different mixer.
11859 * This function returns which mixer amp should be used. 4162 * This function returns which mixer amp should be used.
@@ -11963,261 +4266,6 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11963 return 0; 4266 return 0;
11964} 4267}
11965 4268
11966static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
11967 /*
11968 * Unmute ADC0-2 and set the default input to mic-in
11969 */
11970 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11972 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11974 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11976
11977 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11978 * mixer widget
11979 * Note: PASD motherboards uses the Line In 2 as the input for
11980 * front panel mic (mic 2)
11981 */
11982 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11983 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11986 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11990
11991 /*
11992 * Set up output mixers (0x0c - 0x0e)
11993 */
11994 /* set vol=0 to output mixers */
11995 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11996 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11997 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11998
11999 /* set up input amps for analog loopback */
12000 /* Amp Indices: DAC = 0, mixer = 1 */
12001 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12002 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12003 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12004 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12005 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12006 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12007
12008 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12010 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12011
12012 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12014
12015 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12016 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12017
12018 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12019 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12020 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12021 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12022 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12023
12024 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12025 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12026 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12027 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12028 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12029 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12030
12031
12032 /* FIXME: use matrix-type input source selection */
12033 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12034 /* Input mixer1: only unmute Mic */
12035 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12036 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12037 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12038 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12039 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12040 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12041 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12042 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12043 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12044 /* Input mixer2 */
12045 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12046 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12047 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12048 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12049 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12050 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12051 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12053 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12054 /* Input mixer3 */
12055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12060 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12061 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12064
12065 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12066
12067 { }
12068};
12069
12070static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12071 /*
12072 * Unmute ADC0-2 and set the default input to mic-in
12073 */
12074 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12076 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12077 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12079 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12080
12081 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12082 * mixer widget
12083 * Note: PASD motherboards uses the Line In 2 as the input for front
12084 * panel mic (mic 2)
12085 */
12086 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12095 /*
12096 * Set up output mixers (0x0c - 0x0e)
12097 */
12098 /* set vol=0 to output mixers */
12099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12102
12103 /* set up input amps for analog loopback */
12104 /* Amp Indices: DAC = 0, mixer = 1 */
12105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12111
12112
12113 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12114 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12115 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12116 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12117 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12118 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12119 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12120
12121 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12123
12124 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12125 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12126
12127 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12129 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12130 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12131 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12132 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12133
12134 /* FIXME: use matrix-type input source selection */
12135 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12136 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12140 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12141 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12142 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12144 /* Input mixer2 */
12145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12146 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12147 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12148 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12149 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12150 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12152 /* Input mixer3 */
12153 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12158 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12160
12161 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12162
12163 { }
12164};
12165
12166static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12167
12168 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12169 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12170 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12171
12172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12173 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12174 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12175 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12176
12177 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12178 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12179 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12180 {}
12181};
12182
12183/*
12184 * Pin config fixes
12185 */
12186enum {
12187 PINFIX_FSC_H270,
12188 PINFIX_HP_Z200,
12189};
12190
12191static const struct alc_fixup alc262_fixups[] = {
12192 [PINFIX_FSC_H270] = {
12193 .type = ALC_FIXUP_PINS,
12194 .v.pins = (const struct alc_pincfg[]) {
12195 { 0x14, 0x99130110 }, /* speaker */
12196 { 0x15, 0x0221142f }, /* front HP */
12197 { 0x1b, 0x0121141f }, /* rear HP */
12198 { }
12199 }
12200 },
12201 [PINFIX_HP_Z200] = {
12202 .type = ALC_FIXUP_PINS,
12203 .v.pins = (const struct alc_pincfg[]) {
12204 { 0x16, 0x99130120 }, /* internal speaker */
12205 { }
12206 }
12207 },
12208};
12209
12210static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12211 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12212 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12213 {}
12214};
12215
12216
12217#ifdef CONFIG_SND_HDA_POWER_SAVE
12218#define alc262_loopbacks alc880_loopbacks
12219#endif
12220
12221/* 4269/*
12222 * BIOS auto configuration 4270 * BIOS auto configuration
12223 */ 4271 */
@@ -12266,6 +4314,43 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
12266 return 1; 4314 return 1;
12267} 4315}
12268 4316
4317/*
4318 * Pin config fixes
4319 */
4320enum {
4321 PINFIX_FSC_H270,
4322 PINFIX_HP_Z200,
4323};
4324
4325static const struct alc_fixup alc262_fixups[] = {
4326 [PINFIX_FSC_H270] = {
4327 .type = ALC_FIXUP_PINS,
4328 .v.pins = (const struct alc_pincfg[]) {
4329 { 0x14, 0x99130110 }, /* speaker */
4330 { 0x15, 0x0221142f }, /* front HP */
4331 { 0x1b, 0x0121141f }, /* rear HP */
4332 { }
4333 }
4334 },
4335 [PINFIX_HP_Z200] = {
4336 .type = ALC_FIXUP_PINS,
4337 .v.pins = (const struct alc_pincfg[]) {
4338 { 0x16, 0x99130120 }, /* internal speaker */
4339 { }
4340 }
4341 },
4342};
4343
4344static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4345 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
4346 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
4347 {}
4348};
4349
4350
4351#ifdef CONFIG_SND_HDA_POWER_SAVE
4352#define alc262_loopbacks alc880_loopbacks
4353#endif
12269 4354
12270/* init callback for auto-configuration model -- overriding the default init */ 4355/* init callback for auto-configuration model -- overriding the default init */
12271static void alc262_auto_init(struct hda_codec *codec) 4356static void alc262_auto_init(struct hda_codec *codec)
@@ -12281,321 +4366,10 @@ static void alc262_auto_init(struct hda_codec *codec)
12281} 4366}
12282 4367
12283/* 4368/*
12284 * configuration and preset
12285 */ 4369 */
12286static const char * const alc262_models[ALC262_MODEL_LAST] = { 4370#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
12287 [ALC262_BASIC] = "basic", 4371#include "alc262_quirks.c"
12288 [ALC262_HIPPO] = "hippo",
12289 [ALC262_HIPPO_1] = "hippo_1",
12290 [ALC262_FUJITSU] = "fujitsu",
12291 [ALC262_HP_BPC] = "hp-bpc",
12292 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12293 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12294 [ALC262_HP_RP5700] = "hp-rp5700",
12295 [ALC262_BENQ_ED8] = "benq",
12296 [ALC262_BENQ_T31] = "benq-t31",
12297 [ALC262_SONY_ASSAMD] = "sony-assamd",
12298 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12299 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12300 [ALC262_ULTRA] = "ultra",
12301 [ALC262_LENOVO_3000] = "lenovo-3000",
12302 [ALC262_NEC] = "nec",
12303 [ALC262_TYAN] = "tyan",
12304 [ALC262_AUTO] = "auto",
12305};
12306
12307static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12308 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12309 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12310 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12311 ALC262_HP_BPC),
12312 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12313 ALC262_HP_BPC),
12314 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12315 ALC262_HP_BPC),
12316 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12317 ALC262_AUTO),
12318 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12319 ALC262_HP_BPC),
12320 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12321 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12322 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12323 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12324 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12325 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12326 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12327 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12328 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12329 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12330 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12331 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12332 ALC262_HP_TC_T5735),
12333 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12334 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12335 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12336 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12337 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12338 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12339 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12340 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12341#if 0 /* disable the quirk since model=auto works better in recent versions */
12342 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12343 ALC262_SONY_ASSAMD),
12344#endif 4372#endif
12345 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12346 ALC262_TOSHIBA_RX1),
12347 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12348 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12349 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12350 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12351 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12352 ALC262_ULTRA),
12353 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12354 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12355 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12356 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12357 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12358 {}
12359};
12360
12361static const struct alc_config_preset alc262_presets[] = {
12362 [ALC262_BASIC] = {
12363 .mixers = { alc262_base_mixer },
12364 .init_verbs = { alc262_init_verbs },
12365 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12366 .dac_nids = alc262_dac_nids,
12367 .hp_nid = 0x03,
12368 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12369 .channel_mode = alc262_modes,
12370 .input_mux = &alc262_capture_source,
12371 },
12372 [ALC262_HIPPO] = {
12373 .mixers = { alc262_hippo_mixer },
12374 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12375 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12376 .dac_nids = alc262_dac_nids,
12377 .hp_nid = 0x03,
12378 .dig_out_nid = ALC262_DIGOUT_NID,
12379 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12380 .channel_mode = alc262_modes,
12381 .input_mux = &alc262_capture_source,
12382 .unsol_event = alc_sku_unsol_event,
12383 .setup = alc262_hippo_setup,
12384 .init_hook = alc_inithook,
12385 },
12386 [ALC262_HIPPO_1] = {
12387 .mixers = { alc262_hippo1_mixer },
12388 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12389 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12390 .dac_nids = alc262_dac_nids,
12391 .hp_nid = 0x02,
12392 .dig_out_nid = ALC262_DIGOUT_NID,
12393 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12394 .channel_mode = alc262_modes,
12395 .input_mux = &alc262_capture_source,
12396 .unsol_event = alc_sku_unsol_event,
12397 .setup = alc262_hippo1_setup,
12398 .init_hook = alc_inithook,
12399 },
12400 [ALC262_FUJITSU] = {
12401 .mixers = { alc262_fujitsu_mixer },
12402 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12403 alc262_fujitsu_unsol_verbs },
12404 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12405 .dac_nids = alc262_dac_nids,
12406 .hp_nid = 0x03,
12407 .dig_out_nid = ALC262_DIGOUT_NID,
12408 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12409 .channel_mode = alc262_modes,
12410 .input_mux = &alc262_fujitsu_capture_source,
12411 .unsol_event = alc_sku_unsol_event,
12412 .setup = alc262_fujitsu_setup,
12413 .init_hook = alc_inithook,
12414 },
12415 [ALC262_HP_BPC] = {
12416 .mixers = { alc262_HP_BPC_mixer },
12417 .init_verbs = { alc262_HP_BPC_init_verbs },
12418 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12419 .dac_nids = alc262_dac_nids,
12420 .hp_nid = 0x03,
12421 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12422 .channel_mode = alc262_modes,
12423 .input_mux = &alc262_HP_capture_source,
12424 .unsol_event = alc_sku_unsol_event,
12425 .setup = alc262_hp_bpc_setup,
12426 .init_hook = alc_inithook,
12427 },
12428 [ALC262_HP_BPC_D7000_WF] = {
12429 .mixers = { alc262_HP_BPC_WildWest_mixer },
12430 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12431 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12432 .dac_nids = alc262_dac_nids,
12433 .hp_nid = 0x03,
12434 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12435 .channel_mode = alc262_modes,
12436 .input_mux = &alc262_HP_D7000_capture_source,
12437 .unsol_event = alc_sku_unsol_event,
12438 .setup = alc262_hp_wildwest_setup,
12439 .init_hook = alc_inithook,
12440 },
12441 [ALC262_HP_BPC_D7000_WL] = {
12442 .mixers = { alc262_HP_BPC_WildWest_mixer,
12443 alc262_HP_BPC_WildWest_option_mixer },
12444 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12446 .dac_nids = alc262_dac_nids,
12447 .hp_nid = 0x03,
12448 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12449 .channel_mode = alc262_modes,
12450 .input_mux = &alc262_HP_D7000_capture_source,
12451 .unsol_event = alc_sku_unsol_event,
12452 .setup = alc262_hp_wildwest_setup,
12453 .init_hook = alc_inithook,
12454 },
12455 [ALC262_HP_TC_T5735] = {
12456 .mixers = { alc262_hp_t5735_mixer },
12457 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12458 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12459 .dac_nids = alc262_dac_nids,
12460 .hp_nid = 0x03,
12461 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12462 .channel_mode = alc262_modes,
12463 .input_mux = &alc262_capture_source,
12464 .unsol_event = alc_sku_unsol_event,
12465 .setup = alc262_hp_t5735_setup,
12466 .init_hook = alc_inithook,
12467 },
12468 [ALC262_HP_RP5700] = {
12469 .mixers = { alc262_hp_rp5700_mixer },
12470 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12471 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12472 .dac_nids = alc262_dac_nids,
12473 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12474 .channel_mode = alc262_modes,
12475 .input_mux = &alc262_hp_rp5700_capture_source,
12476 },
12477 [ALC262_BENQ_ED8] = {
12478 .mixers = { alc262_base_mixer },
12479 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12480 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12481 .dac_nids = alc262_dac_nids,
12482 .hp_nid = 0x03,
12483 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12484 .channel_mode = alc262_modes,
12485 .input_mux = &alc262_capture_source,
12486 },
12487 [ALC262_SONY_ASSAMD] = {
12488 .mixers = { alc262_sony_mixer },
12489 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12490 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12491 .dac_nids = alc262_dac_nids,
12492 .hp_nid = 0x02,
12493 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12494 .channel_mode = alc262_modes,
12495 .input_mux = &alc262_capture_source,
12496 .unsol_event = alc_sku_unsol_event,
12497 .setup = alc262_hippo_setup,
12498 .init_hook = alc_inithook,
12499 },
12500 [ALC262_BENQ_T31] = {
12501 .mixers = { alc262_benq_t31_mixer },
12502 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12503 alc_hp15_unsol_verbs },
12504 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12505 .dac_nids = alc262_dac_nids,
12506 .hp_nid = 0x03,
12507 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12508 .channel_mode = alc262_modes,
12509 .input_mux = &alc262_capture_source,
12510 .unsol_event = alc_sku_unsol_event,
12511 .setup = alc262_hippo_setup,
12512 .init_hook = alc_inithook,
12513 },
12514 [ALC262_ULTRA] = {
12515 .mixers = { alc262_ultra_mixer },
12516 .cap_mixer = alc262_ultra_capture_mixer,
12517 .init_verbs = { alc262_ultra_verbs },
12518 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12519 .dac_nids = alc262_dac_nids,
12520 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12521 .channel_mode = alc262_modes,
12522 .input_mux = &alc262_ultra_capture_source,
12523 .adc_nids = alc262_adc_nids, /* ADC0 */
12524 .capsrc_nids = alc262_capsrc_nids,
12525 .num_adc_nids = 1, /* single ADC */
12526 .unsol_event = alc262_ultra_unsol_event,
12527 .init_hook = alc262_ultra_automute,
12528 },
12529 [ALC262_LENOVO_3000] = {
12530 .mixers = { alc262_lenovo_3000_mixer },
12531 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12532 alc262_lenovo_3000_unsol_verbs,
12533 alc262_lenovo_3000_init_verbs },
12534 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12535 .dac_nids = alc262_dac_nids,
12536 .hp_nid = 0x03,
12537 .dig_out_nid = ALC262_DIGOUT_NID,
12538 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12539 .channel_mode = alc262_modes,
12540 .input_mux = &alc262_fujitsu_capture_source,
12541 .unsol_event = alc_sku_unsol_event,
12542 .setup = alc262_lenovo_3000_setup,
12543 .init_hook = alc_inithook,
12544 },
12545 [ALC262_NEC] = {
12546 .mixers = { alc262_nec_mixer },
12547 .init_verbs = { alc262_nec_verbs },
12548 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12549 .dac_nids = alc262_dac_nids,
12550 .hp_nid = 0x03,
12551 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12552 .channel_mode = alc262_modes,
12553 .input_mux = &alc262_capture_source,
12554 },
12555 [ALC262_TOSHIBA_S06] = {
12556 .mixers = { alc262_toshiba_s06_mixer },
12557 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12558 alc262_eapd_verbs },
12559 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12560 .capsrc_nids = alc262_dmic_capsrc_nids,
12561 .dac_nids = alc262_dac_nids,
12562 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12563 .num_adc_nids = 1, /* single ADC */
12564 .dig_out_nid = ALC262_DIGOUT_NID,
12565 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12566 .channel_mode = alc262_modes,
12567 .unsol_event = alc_sku_unsol_event,
12568 .setup = alc262_toshiba_s06_setup,
12569 .init_hook = alc_inithook,
12570 },
12571 [ALC262_TOSHIBA_RX1] = {
12572 .mixers = { alc262_toshiba_rx1_mixer },
12573 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12574 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12575 .dac_nids = alc262_dac_nids,
12576 .hp_nid = 0x03,
12577 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12578 .channel_mode = alc262_modes,
12579 .input_mux = &alc262_capture_source,
12580 .unsol_event = alc_sku_unsol_event,
12581 .setup = alc262_hippo_setup,
12582 .init_hook = alc_inithook,
12583 },
12584 [ALC262_TYAN] = {
12585 .mixers = { alc262_tyan_mixer },
12586 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12587 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12588 .dac_nids = alc262_dac_nids,
12589 .hp_nid = 0x02,
12590 .dig_out_nid = ALC262_DIGOUT_NID,
12591 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12592 .channel_mode = alc262_modes,
12593 .input_mux = &alc262_capture_source,
12594 .unsol_event = alc_sku_unsol_event,
12595 .setup = alc262_tyan_setup,
12596 .init_hook = alc_hp_automute,
12597 },
12598};
12599 4373
12600static int patch_alc262(struct hda_codec *codec) 4374static int patch_alc262(struct hda_codec *codec)
12601{ 4375{
@@ -12627,33 +4401,35 @@ static int patch_alc262(struct hda_codec *codec)
12627 4401
12628 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 4402 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12629 4403
12630 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 4404 board_config = alc_board_config(codec, ALC262_MODEL_LAST,
12631 alc262_models, 4405 alc262_models, alc262_cfg_tbl);
12632 alc262_cfg_tbl);
12633 4406
12634 if (board_config < 0) { 4407 if (board_config < 0) {
12635 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4408 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12636 codec->chip_name); 4409 codec->chip_name);
12637 board_config = ALC262_AUTO; 4410 board_config = ALC_MODEL_AUTO;
12638 } 4411 }
12639 4412
12640 if (board_config == ALC262_AUTO) { 4413 if (board_config == ALC_MODEL_AUTO) {
12641 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 4414 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12642 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4415 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12643 } 4416 }
12644 4417
12645 if (board_config == ALC262_AUTO) { 4418 if (board_config == ALC_MODEL_AUTO) {
12646 /* automatic parse from the BIOS config */ 4419 /* automatic parse from the BIOS config */
12647 err = alc262_parse_auto_config(codec); 4420 err = alc262_parse_auto_config(codec);
12648 if (err < 0) { 4421 if (err < 0) {
12649 alc_free(codec); 4422 alc_free(codec);
12650 return err; 4423 return err;
12651 } else if (!err) { 4424 }
4425#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4426 else if (!err) {
12652 printk(KERN_INFO 4427 printk(KERN_INFO
12653 "hda_codec: Cannot set up configuration " 4428 "hda_codec: Cannot set up configuration "
12654 "from BIOS. Using base mode...\n"); 4429 "from BIOS. Using base mode...\n");
12655 board_config = ALC262_BASIC; 4430 board_config = ALC262_BASIC;
12656 } 4431 }
4432#endif
12657 } 4433 }
12658 4434
12659 if (!spec->no_analog && has_cdefine_beep(codec)) { 4435 if (!spec->no_analog && has_cdefine_beep(codec)) {
@@ -12664,7 +4440,7 @@ static int patch_alc262(struct hda_codec *codec)
12664 } 4440 }
12665 } 4441 }
12666 4442
12667 if (board_config != ALC262_AUTO) 4443 if (board_config != ALC_MODEL_AUTO)
12668 setup_preset(codec, &alc262_presets[board_config]); 4444 setup_preset(codec, &alc262_presets[board_config]);
12669 4445
12670 if (!spec->adc_nids && spec->input_mux) { 4446 if (!spec->adc_nids && spec->input_mux) {
@@ -12682,7 +4458,7 @@ static int patch_alc262(struct hda_codec *codec)
12682 spec->vmaster_nid = 0x0c; 4458 spec->vmaster_nid = 0x0c;
12683 4459
12684 codec->patch_ops = alc_patch_ops; 4460 codec->patch_ops = alc_patch_ops;
12685 if (board_config == ALC262_AUTO) 4461 if (board_config == ALC_MODEL_AUTO)
12686 spec->init_hook = alc262_auto_init; 4462 spec->init_hook = alc262_auto_init;
12687 spec->shutup = alc_eapd_shutup; 4463 spec->shutup = alc_eapd_shutup;
12688 4464
@@ -12696,432 +4472,8 @@ static int patch_alc262(struct hda_codec *codec)
12696} 4472}
12697 4473
12698/* 4474/*
12699 * ALC268 channel source setting (2 channel) 4475 * ALC268
12700 */
12701#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12702#define alc268_modes alc260_modes
12703
12704static const hda_nid_t alc268_dac_nids[2] = {
12705 /* front, hp */
12706 0x02, 0x03
12707};
12708
12709static const hda_nid_t alc268_adc_nids[2] = {
12710 /* ADC0-1 */
12711 0x08, 0x07
12712};
12713
12714static const hda_nid_t alc268_adc_nids_alt[1] = {
12715 /* ADC0 */
12716 0x08
12717};
12718
12719static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12720
12721static const struct snd_kcontrol_new alc268_base_mixer[] = {
12722 /* output mixer control */
12723 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12724 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12727 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12728 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12729 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12730 { }
12731};
12732
12733static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12734 /* output mixer control */
12735 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12736 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12737 ALC262_HIPPO_MASTER_SWITCH,
12738 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12739 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12740 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12741 { }
12742};
12743
12744/* bind Beep switches of both NID 0x0f and 0x10 */
12745static const struct hda_bind_ctls alc268_bind_beep_sw = {
12746 .ops = &snd_hda_bind_sw,
12747 .values = {
12748 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12749 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12750 0
12751 },
12752};
12753
12754static const struct snd_kcontrol_new alc268_beep_mixer[] = {
12755 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12756 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12757 { }
12758};
12759
12760static const struct hda_verb alc268_eapd_verbs[] = {
12761 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12762 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12763 { }
12764};
12765
12766/* Toshiba specific */
12767static const struct hda_verb alc268_toshiba_verbs[] = {
12768 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12769 { } /* end */
12770};
12771
12772/* Acer specific */
12773/* bind volumes of both NID 0x02 and 0x03 */
12774static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
12775 .ops = &snd_hda_bind_vol,
12776 .values = {
12777 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12778 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12779 0
12780 },
12781};
12782
12783static void alc268_acer_setup(struct hda_codec *codec)
12784{
12785 struct alc_spec *spec = codec->spec;
12786
12787 spec->autocfg.hp_pins[0] = 0x14;
12788 spec->autocfg.speaker_pins[0] = 0x15;
12789 spec->automute = 1;
12790 spec->automute_mode = ALC_AUTOMUTE_AMP;
12791}
12792
12793#define alc268_acer_master_sw_get alc262_hp_master_sw_get
12794#define alc268_acer_master_sw_put alc262_hp_master_sw_put
12795
12796static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12797 /* output mixer control */
12798 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12799 {
12800 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12801 .name = "Master Playback Switch",
12802 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
12803 .info = snd_ctl_boolean_mono_info,
12804 .get = alc268_acer_master_sw_get,
12805 .put = alc268_acer_master_sw_put,
12806 },
12807 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12808 { }
12809};
12810
12811static const struct snd_kcontrol_new alc268_acer_mixer[] = {
12812 /* output mixer control */
12813 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12814 {
12815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12816 .name = "Master Playback Switch",
12817 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12818 .info = snd_ctl_boolean_mono_info,
12819 .get = alc268_acer_master_sw_get,
12820 .put = alc268_acer_master_sw_put,
12821 },
12822 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12823 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12824 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12825 { }
12826};
12827
12828static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12829 /* output mixer control */
12830 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12831 {
12832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12833 .name = "Master Playback Switch",
12834 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12835 .info = snd_ctl_boolean_mono_info,
12836 .get = alc268_acer_master_sw_get,
12837 .put = alc268_acer_master_sw_put,
12838 },
12839 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12840 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12841 { }
12842};
12843
12844static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
12845 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12847 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12848 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12849 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12850 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12851 { }
12852};
12853
12854static const struct hda_verb alc268_acer_verbs[] = {
12855 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12856 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12857 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12858 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12859 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12860 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12861 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12862 { }
12863};
12864
12865/* unsolicited event for HP jack sensing */
12866#define alc268_toshiba_setup alc262_hippo_setup
12867
12868static void alc268_acer_lc_setup(struct hda_codec *codec)
12869{
12870 struct alc_spec *spec = codec->spec;
12871 spec->autocfg.hp_pins[0] = 0x15;
12872 spec->autocfg.speaker_pins[0] = 0x14;
12873 spec->automute = 1;
12874 spec->automute_mode = ALC_AUTOMUTE_AMP;
12875 spec->ext_mic_pin = 0x18;
12876 spec->int_mic_pin = 0x12;
12877 spec->auto_mic = 1;
12878}
12879
12880static const struct snd_kcontrol_new alc268_dell_mixer[] = {
12881 /* output mixer control */
12882 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12883 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12885 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12886 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12887 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12888 { }
12889};
12890
12891static const struct hda_verb alc268_dell_verbs[] = {
12892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12893 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12894 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12895 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12896 { }
12897};
12898
12899/* mute/unmute internal speaker according to the hp jack and mute state */
12900static void alc268_dell_setup(struct hda_codec *codec)
12901{
12902 struct alc_spec *spec = codec->spec;
12903
12904 spec->autocfg.hp_pins[0] = 0x15;
12905 spec->autocfg.speaker_pins[0] = 0x14;
12906 spec->ext_mic_pin = 0x18;
12907 spec->int_mic_pin = 0x19;
12908 spec->auto_mic = 1;
12909 spec->automute = 1;
12910 spec->automute_mode = ALC_AUTOMUTE_PIN;
12911}
12912
12913static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12914 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12915 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12918 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12919 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12920 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12922 { }
12923};
12924
12925static const struct hda_verb alc267_quanta_il1_verbs[] = {
12926 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12927 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12928 { }
12929};
12930
12931static void alc267_quanta_il1_setup(struct hda_codec *codec)
12932{
12933 struct alc_spec *spec = codec->spec;
12934 spec->autocfg.hp_pins[0] = 0x15;
12935 spec->autocfg.speaker_pins[0] = 0x14;
12936 spec->ext_mic_pin = 0x18;
12937 spec->int_mic_pin = 0x19;
12938 spec->auto_mic = 1;
12939 spec->automute = 1;
12940 spec->automute_mode = ALC_AUTOMUTE_PIN;
12941}
12942
12943/*
12944 * generic initialization of ADC, input mixers and output mixers
12945 */ 4476 */
12946static const struct hda_verb alc268_base_init_verbs[] = {
12947 /* Unmute DAC0-1 and set vol = 0 */
12948 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12949 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12950
12951 /*
12952 * Set up output mixers (0x0c - 0x0e)
12953 */
12954 /* set vol=0 to output mixers */
12955 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12956 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12957
12958 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12959 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12960
12961 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12964 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12965 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12966 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12967 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12968 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12969
12970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12971 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12972 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12974 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12975
12976 /* set PCBEEP vol = 0, mute connections */
12977 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12978 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12979 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12980
12981 /* Unmute Selector 23h,24h and set the default input to mic-in */
12982
12983 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12984 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12985 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12986 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12987
12988 { }
12989};
12990
12991/* only for model=test */
12992#ifdef CONFIG_SND_DEBUG
12993/*
12994 * generic initialization of ADC, input mixers and output mixers
12995 */
12996static const struct hda_verb alc268_volume_init_verbs[] = {
12997 /* set output DAC */
12998 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12999 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13000
13001 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13002 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13003 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13004 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13005 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13006
13007 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13008 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13009 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13010
13011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13012 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13013 { }
13014};
13015#endif /* CONFIG_SND_DEBUG */
13016
13017/* set PCBEEP vol = 0, mute connections */
13018static const struct hda_verb alc268_beep_init_verbs[] = {
13019 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13021 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13022 { }
13023};
13024
13025static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13026 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13027 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13028 { } /* end */
13029};
13030
13031static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13032 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13033 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13034 _DEFINE_CAPSRC(1),
13035 { } /* end */
13036};
13037
13038static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13039 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13040 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13041 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13042 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13043 _DEFINE_CAPSRC(2),
13044 { } /* end */
13045};
13046
13047static const struct hda_input_mux alc268_capture_source = {
13048 .num_items = 4,
13049 .items = {
13050 { "Mic", 0x0 },
13051 { "Front Mic", 0x1 },
13052 { "Line", 0x2 },
13053 { "CD", 0x3 },
13054 },
13055};
13056
13057static const struct hda_input_mux alc268_acer_capture_source = {
13058 .num_items = 3,
13059 .items = {
13060 { "Mic", 0x0 },
13061 { "Internal Mic", 0x1 },
13062 { "Line", 0x2 },
13063 },
13064};
13065
13066static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13067 .num_items = 3,
13068 .items = {
13069 { "Mic", 0x0 },
13070 { "Internal Mic", 0x6 },
13071 { "Line", 0x2 },
13072 },
13073};
13074
13075#ifdef CONFIG_SND_DEBUG
13076static const struct snd_kcontrol_new alc268_test_mixer[] = {
13077 /* Volume widgets */
13078 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13079 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13080 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13081 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13082 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13083 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13084 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13085 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13086 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13087 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13088 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13089 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13090 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13091 /* The below appears problematic on some hardwares */
13092 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13093 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13094 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13095 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13096 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13097
13098 /* Modes for retasking pin widgets */
13099 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13100 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13101 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13102 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13103
13104 /* Controls for GPIO pins, assuming they are configured as outputs */
13105 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13106 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13107 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13108 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13109
13110 /* Switches to allow the digital SPDIF output pin to be enabled.
13111 * The ALC268 does not have an SPDIF input.
13112 */
13113 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13114
13115 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13116 * this output to turn on an external amplifier.
13117 */
13118 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13119 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13120
13121 { } /* end */
13122};
13123#endif
13124
13125/* create input playback/capture controls for the given pin */ 4477/* create input playback/capture controls for the given pin */
13126static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 4478static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13127 const char *ctlname, int idx) 4479 const char *ctlname, int idx)
@@ -13320,6 +4672,30 @@ static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13320 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 4672 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13321} 4673}
13322 4674
4675/* bind Beep switches of both NID 0x0f and 0x10 */
4676static const struct hda_bind_ctls alc268_bind_beep_sw = {
4677 .ops = &snd_hda_bind_sw,
4678 .values = {
4679 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
4680 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
4681 0
4682 },
4683};
4684
4685static const struct snd_kcontrol_new alc268_beep_mixer[] = {
4686 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
4687 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
4688 { }
4689};
4690
4691/* set PCBEEP vol = 0, mute connections */
4692static const struct hda_verb alc268_beep_init_verbs[] = {
4693 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4694 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4695 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4696 { }
4697};
4698
13323/* 4699/*
13324 * BIOS auto configuration 4700 * BIOS auto configuration
13325 */ 4701 */
@@ -13388,215 +4764,10 @@ static void alc268_auto_init(struct hda_codec *codec)
13388} 4764}
13389 4765
13390/* 4766/*
13391 * configuration and preset
13392 */ 4767 */
13393static const char * const alc268_models[ALC268_MODEL_LAST] = { 4768#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
13394 [ALC267_QUANTA_IL1] = "quanta-il1", 4769#include "alc268_quirks.c"
13395 [ALC268_3ST] = "3stack",
13396 [ALC268_TOSHIBA] = "toshiba",
13397 [ALC268_ACER] = "acer",
13398 [ALC268_ACER_DMIC] = "acer-dmic",
13399 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13400 [ALC268_DELL] = "dell",
13401 [ALC268_ZEPTO] = "zepto",
13402#ifdef CONFIG_SND_DEBUG
13403 [ALC268_TEST] = "test",
13404#endif
13405 [ALC268_AUTO] = "auto",
13406};
13407
13408static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13409 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13410 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13411 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13412 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13413 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13414 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13415 ALC268_ACER_ASPIRE_ONE),
13416 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13417 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13418 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13419 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13420 /* almost compatible with toshiba but with optional digital outs;
13421 * auto-probing seems working fine
13422 */
13423 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13424 ALC268_AUTO),
13425 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13426 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13427 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13428 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13429 {}
13430};
13431
13432/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13433static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13434 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13435 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13436 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13437 ALC268_TOSHIBA),
13438 {}
13439};
13440
13441static const struct alc_config_preset alc268_presets[] = {
13442 [ALC267_QUANTA_IL1] = {
13443 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13444 alc268_capture_nosrc_mixer },
13445 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13446 alc267_quanta_il1_verbs },
13447 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13448 .dac_nids = alc268_dac_nids,
13449 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13450 .adc_nids = alc268_adc_nids_alt,
13451 .hp_nid = 0x03,
13452 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13453 .channel_mode = alc268_modes,
13454 .unsol_event = alc_sku_unsol_event,
13455 .setup = alc267_quanta_il1_setup,
13456 .init_hook = alc_inithook,
13457 },
13458 [ALC268_3ST] = {
13459 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13460 alc268_beep_mixer },
13461 .init_verbs = { alc268_base_init_verbs },
13462 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13463 .dac_nids = alc268_dac_nids,
13464 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13465 .adc_nids = alc268_adc_nids_alt,
13466 .capsrc_nids = alc268_capsrc_nids,
13467 .hp_nid = 0x03,
13468 .dig_out_nid = ALC268_DIGOUT_NID,
13469 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13470 .channel_mode = alc268_modes,
13471 .input_mux = &alc268_capture_source,
13472 },
13473 [ALC268_TOSHIBA] = {
13474 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13475 alc268_beep_mixer },
13476 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13477 alc268_toshiba_verbs },
13478 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13479 .dac_nids = alc268_dac_nids,
13480 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13481 .adc_nids = alc268_adc_nids_alt,
13482 .capsrc_nids = alc268_capsrc_nids,
13483 .hp_nid = 0x03,
13484 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13485 .channel_mode = alc268_modes,
13486 .input_mux = &alc268_capture_source,
13487 .unsol_event = alc_sku_unsol_event,
13488 .setup = alc268_toshiba_setup,
13489 .init_hook = alc_inithook,
13490 },
13491 [ALC268_ACER] = {
13492 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13493 alc268_beep_mixer },
13494 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13495 alc268_acer_verbs },
13496 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13497 .dac_nids = alc268_dac_nids,
13498 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13499 .adc_nids = alc268_adc_nids_alt,
13500 .capsrc_nids = alc268_capsrc_nids,
13501 .hp_nid = 0x02,
13502 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13503 .channel_mode = alc268_modes,
13504 .input_mux = &alc268_acer_capture_source,
13505 .unsol_event = alc_sku_unsol_event,
13506 .setup = alc268_acer_setup,
13507 .init_hook = alc_inithook,
13508 },
13509 [ALC268_ACER_DMIC] = {
13510 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13511 alc268_beep_mixer },
13512 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13513 alc268_acer_verbs },
13514 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13515 .dac_nids = alc268_dac_nids,
13516 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13517 .adc_nids = alc268_adc_nids_alt,
13518 .capsrc_nids = alc268_capsrc_nids,
13519 .hp_nid = 0x02,
13520 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13521 .channel_mode = alc268_modes,
13522 .input_mux = &alc268_acer_dmic_capture_source,
13523 .unsol_event = alc_sku_unsol_event,
13524 .setup = alc268_acer_setup,
13525 .init_hook = alc_inithook,
13526 },
13527 [ALC268_ACER_ASPIRE_ONE] = {
13528 .mixers = { alc268_acer_aspire_one_mixer,
13529 alc268_beep_mixer,
13530 alc268_capture_nosrc_mixer },
13531 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13532 alc268_acer_aspire_one_verbs },
13533 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13534 .dac_nids = alc268_dac_nids,
13535 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13536 .adc_nids = alc268_adc_nids_alt,
13537 .capsrc_nids = alc268_capsrc_nids,
13538 .hp_nid = 0x03,
13539 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13540 .channel_mode = alc268_modes,
13541 .unsol_event = alc_sku_unsol_event,
13542 .setup = alc268_acer_lc_setup,
13543 .init_hook = alc_inithook,
13544 },
13545 [ALC268_DELL] = {
13546 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13547 alc268_capture_nosrc_mixer },
13548 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13549 alc268_dell_verbs },
13550 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13551 .dac_nids = alc268_dac_nids,
13552 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13553 .adc_nids = alc268_adc_nids_alt,
13554 .capsrc_nids = alc268_capsrc_nids,
13555 .hp_nid = 0x02,
13556 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13557 .channel_mode = alc268_modes,
13558 .unsol_event = alc_sku_unsol_event,
13559 .setup = alc268_dell_setup,
13560 .init_hook = alc_inithook,
13561 },
13562 [ALC268_ZEPTO] = {
13563 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13564 alc268_beep_mixer },
13565 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13566 alc268_toshiba_verbs },
13567 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13568 .dac_nids = alc268_dac_nids,
13569 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13570 .adc_nids = alc268_adc_nids_alt,
13571 .capsrc_nids = alc268_capsrc_nids,
13572 .hp_nid = 0x03,
13573 .dig_out_nid = ALC268_DIGOUT_NID,
13574 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13575 .channel_mode = alc268_modes,
13576 .input_mux = &alc268_capture_source,
13577 .unsol_event = alc_sku_unsol_event,
13578 .setup = alc268_toshiba_setup,
13579 .init_hook = alc_inithook,
13580 },
13581#ifdef CONFIG_SND_DEBUG
13582 [ALC268_TEST] = {
13583 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13584 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13585 alc268_volume_init_verbs,
13586 alc268_beep_init_verbs },
13587 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13588 .dac_nids = alc268_dac_nids,
13589 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13590 .adc_nids = alc268_adc_nids_alt,
13591 .capsrc_nids = alc268_capsrc_nids,
13592 .hp_nid = 0x03,
13593 .dig_out_nid = ALC268_DIGOUT_NID,
13594 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13595 .channel_mode = alc268_modes,
13596 .input_mux = &alc268_capture_source,
13597 },
13598#endif 4770#endif
13599};
13600 4771
13601static int patch_alc268(struct hda_codec *codec) 4772static int patch_alc268(struct hda_codec *codec)
13602{ 4773{
@@ -13612,35 +4783,37 @@ static int patch_alc268(struct hda_codec *codec)
13612 4783
13613 /* ALC268 has no aa-loopback mixer */ 4784 /* ALC268 has no aa-loopback mixer */
13614 4785
13615 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 4786 board_config = alc_board_config(codec, ALC268_MODEL_LAST,
13616 alc268_models, 4787 alc268_models, alc268_cfg_tbl);
13617 alc268_cfg_tbl);
13618 4788
13619 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 4789 if (board_config < 0)
13620 board_config = snd_hda_check_board_codec_sid_config(codec, 4790 board_config = alc_board_codec_sid_config(codec,
13621 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 4791 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13622 4792
13623 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 4793 if (board_config < 0) {
13624 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4794 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13625 codec->chip_name); 4795 codec->chip_name);
13626 board_config = ALC268_AUTO; 4796 board_config = ALC_MODEL_AUTO;
13627 } 4797 }
13628 4798
13629 if (board_config == ALC268_AUTO) { 4799 if (board_config == ALC_MODEL_AUTO) {
13630 /* automatic parse from the BIOS config */ 4800 /* automatic parse from the BIOS config */
13631 err = alc268_parse_auto_config(codec); 4801 err = alc268_parse_auto_config(codec);
13632 if (err < 0) { 4802 if (err < 0) {
13633 alc_free(codec); 4803 alc_free(codec);
13634 return err; 4804 return err;
13635 } else if (!err) { 4805 }
4806#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4807 else if (!err) {
13636 printk(KERN_INFO 4808 printk(KERN_INFO
13637 "hda_codec: Cannot set up configuration " 4809 "hda_codec: Cannot set up configuration "
13638 "from BIOS. Using base mode...\n"); 4810 "from BIOS. Using base mode...\n");
13639 board_config = ALC268_3ST; 4811 board_config = ALC268_3ST;
13640 } 4812 }
4813#endif
13641 } 4814 }
13642 4815
13643 if (board_config != ALC268_AUTO) 4816 if (board_config != ALC_MODEL_AUTO)
13644 setup_preset(codec, &alc268_presets[board_config]); 4817 setup_preset(codec, &alc268_presets[board_config]);
13645 4818
13646 has_beep = 0; 4819 has_beep = 0;
@@ -13678,7 +4851,7 @@ static int patch_alc268(struct hda_codec *codec)
13678 spec->vmaster_nid = 0x02; 4851 spec->vmaster_nid = 0x02;
13679 4852
13680 codec->patch_ops = alc_patch_ops; 4853 codec->patch_ops = alc_patch_ops;
13681 if (board_config == ALC268_AUTO) 4854 if (board_config == ALC_MODEL_AUTO)
13682 spec->init_hook = alc268_auto_init; 4855 spec->init_hook = alc268_auto_init;
13683 spec->shutup = alc_eapd_shutup; 4856 spec->shutup = alc_eapd_shutup;
13684 4857
@@ -13688,469 +4861,8 @@ static int patch_alc268(struct hda_codec *codec)
13688} 4861}
13689 4862
13690/* 4863/*
13691 * ALC269 channel source setting (2 channel) 4864 * ALC269
13692 */ 4865 */
13693#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13694
13695#define alc269_dac_nids alc260_dac_nids
13696
13697static const hda_nid_t alc269_adc_nids[1] = {
13698 /* ADC1 */
13699 0x08,
13700};
13701
13702static const hda_nid_t alc269_capsrc_nids[1] = {
13703 0x23,
13704};
13705
13706static const hda_nid_t alc269vb_adc_nids[1] = {
13707 /* ADC1 */
13708 0x09,
13709};
13710
13711static const hda_nid_t alc269vb_capsrc_nids[1] = {
13712 0x22,
13713};
13714
13715#define alc269_modes alc260_modes
13716#define alc269_capture_source alc880_lg_lw_capture_source
13717
13718static const struct snd_kcontrol_new alc269_base_mixer[] = {
13719 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13720 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13721 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13722 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13723 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13724 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13725 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13726 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13727 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13728 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13729 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13730 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13731 { } /* end */
13732};
13733
13734static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13735 /* output mixer control */
13736 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13737 {
13738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13739 .name = "Master Playback Switch",
13740 .subdevice = HDA_SUBDEV_AMP_FLAG,
13741 .info = snd_hda_mixer_amp_switch_info,
13742 .get = snd_hda_mixer_amp_switch_get,
13743 .put = alc268_acer_master_sw_put,
13744 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13745 },
13746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13748 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13749 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13750 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13751 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13752 { }
13753};
13754
13755static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13756 /* output mixer control */
13757 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13758 {
13759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13760 .name = "Master Playback Switch",
13761 .subdevice = HDA_SUBDEV_AMP_FLAG,
13762 .info = snd_hda_mixer_amp_switch_info,
13763 .get = snd_hda_mixer_amp_switch_get,
13764 .put = alc268_acer_master_sw_put,
13765 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13766 },
13767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13769 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13770 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13771 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13772 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13773 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13774 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13775 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
13776 { }
13777};
13778
13779static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
13780 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13781 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13783 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13784 { } /* end */
13785};
13786
13787static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13788 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13789 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13791 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13792 { } /* end */
13793};
13794
13795static const struct snd_kcontrol_new alc269_asus_mixer[] = {
13796 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13797 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
13798 { } /* end */
13799};
13800
13801/* capture mixer elements */
13802static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13803 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13804 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13805 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13806 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13807 { } /* end */
13808};
13809
13810static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13811 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13812 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13813 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13814 { } /* end */
13815};
13816
13817static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13818 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13819 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13820 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13821 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13822 { } /* end */
13823};
13824
13825static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13826 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13827 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13828 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13829 { } /* end */
13830};
13831
13832/* FSC amilo */
13833#define alc269_fujitsu_mixer alc269_laptop_mixer
13834
13835static const struct hda_verb alc269_quanta_fl1_verbs[] = {
13836 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13837 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13838 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13839 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13840 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13841 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13842 { }
13843};
13844
13845static const struct hda_verb alc269_lifebook_verbs[] = {
13846 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13847 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13848 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13850 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13851 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13852 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13853 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13854 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13855 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13856 { }
13857};
13858
13859/* toggle speaker-output according to the hp-jack state */
13860static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13861{
13862 alc_hp_automute(codec);
13863
13864 snd_hda_codec_write(codec, 0x20, 0,
13865 AC_VERB_SET_COEF_INDEX, 0x0c);
13866 snd_hda_codec_write(codec, 0x20, 0,
13867 AC_VERB_SET_PROC_COEF, 0x680);
13868
13869 snd_hda_codec_write(codec, 0x20, 0,
13870 AC_VERB_SET_COEF_INDEX, 0x0c);
13871 snd_hda_codec_write(codec, 0x20, 0,
13872 AC_VERB_SET_PROC_COEF, 0x480);
13873}
13874
13875#define alc269_lifebook_speaker_automute \
13876 alc269_quanta_fl1_speaker_automute
13877
13878static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13879{
13880 unsigned int present_laptop;
13881 unsigned int present_dock;
13882
13883 present_laptop = snd_hda_jack_detect(codec, 0x18);
13884 present_dock = snd_hda_jack_detect(codec, 0x1b);
13885
13886 /* Laptop mic port overrides dock mic port, design decision */
13887 if (present_dock)
13888 snd_hda_codec_write(codec, 0x23, 0,
13889 AC_VERB_SET_CONNECT_SEL, 0x3);
13890 if (present_laptop)
13891 snd_hda_codec_write(codec, 0x23, 0,
13892 AC_VERB_SET_CONNECT_SEL, 0x0);
13893 if (!present_dock && !present_laptop)
13894 snd_hda_codec_write(codec, 0x23, 0,
13895 AC_VERB_SET_CONNECT_SEL, 0x1);
13896}
13897
13898static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13899 unsigned int res)
13900{
13901 switch (res >> 26) {
13902 case ALC880_HP_EVENT:
13903 alc269_quanta_fl1_speaker_automute(codec);
13904 break;
13905 case ALC880_MIC_EVENT:
13906 alc_mic_automute(codec);
13907 break;
13908 }
13909}
13910
13911static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13912 unsigned int res)
13913{
13914 if ((res >> 26) == ALC880_HP_EVENT)
13915 alc269_lifebook_speaker_automute(codec);
13916 if ((res >> 26) == ALC880_MIC_EVENT)
13917 alc269_lifebook_mic_autoswitch(codec);
13918}
13919
13920static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13921{
13922 struct alc_spec *spec = codec->spec;
13923 spec->autocfg.hp_pins[0] = 0x15;
13924 spec->autocfg.speaker_pins[0] = 0x14;
13925 spec->automute_mixer_nid[0] = 0x0c;
13926 spec->automute = 1;
13927 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13928 spec->ext_mic_pin = 0x18;
13929 spec->int_mic_pin = 0x19;
13930 spec->auto_mic = 1;
13931}
13932
13933static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13934{
13935 alc269_quanta_fl1_speaker_automute(codec);
13936 alc_mic_automute(codec);
13937}
13938
13939static void alc269_lifebook_setup(struct hda_codec *codec)
13940{
13941 struct alc_spec *spec = codec->spec;
13942 spec->autocfg.hp_pins[0] = 0x15;
13943 spec->autocfg.hp_pins[1] = 0x1a;
13944 spec->autocfg.speaker_pins[0] = 0x14;
13945 spec->automute_mixer_nid[0] = 0x0c;
13946 spec->automute = 1;
13947 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13948}
13949
13950static void alc269_lifebook_init_hook(struct hda_codec *codec)
13951{
13952 alc269_lifebook_speaker_automute(codec);
13953 alc269_lifebook_mic_autoswitch(codec);
13954}
13955
13956static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13957 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13958 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13959 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13960 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13961 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13963 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13964 {}
13965};
13966
13967static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
13968 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13969 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13970 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13971 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13972 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13973 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13974 {}
13975};
13976
13977static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13978 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13979 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13980 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13981 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13982 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13983 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13984 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13985 {}
13986};
13987
13988static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13989 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13990 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13991 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13992 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13993 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13994 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13995 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13996 {}
13997};
13998
13999static const struct hda_verb alc271_acer_dmic_verbs[] = {
14000 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14001 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14002 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14004 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14005 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14006 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14007 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14008 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14009 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14010 { }
14011};
14012
14013static void alc269_laptop_amic_setup(struct hda_codec *codec)
14014{
14015 struct alc_spec *spec = codec->spec;
14016 spec->autocfg.hp_pins[0] = 0x15;
14017 spec->autocfg.speaker_pins[0] = 0x14;
14018 spec->automute_mixer_nid[0] = 0x0c;
14019 spec->automute = 1;
14020 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14021 spec->ext_mic_pin = 0x18;
14022 spec->int_mic_pin = 0x19;
14023 spec->auto_mic = 1;
14024}
14025
14026static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14027{
14028 struct alc_spec *spec = codec->spec;
14029 spec->autocfg.hp_pins[0] = 0x15;
14030 spec->autocfg.speaker_pins[0] = 0x14;
14031 spec->automute_mixer_nid[0] = 0x0c;
14032 spec->automute = 1;
14033 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14034 spec->ext_mic_pin = 0x18;
14035 spec->int_mic_pin = 0x12;
14036 spec->auto_mic = 1;
14037}
14038
14039static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14040{
14041 struct alc_spec *spec = codec->spec;
14042 spec->autocfg.hp_pins[0] = 0x21;
14043 spec->autocfg.speaker_pins[0] = 0x14;
14044 spec->automute_mixer_nid[0] = 0x0c;
14045 spec->automute = 1;
14046 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14047 spec->ext_mic_pin = 0x18;
14048 spec->int_mic_pin = 0x19;
14049 spec->auto_mic = 1;
14050}
14051
14052static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14053{
14054 struct alc_spec *spec = codec->spec;
14055 spec->autocfg.hp_pins[0] = 0x21;
14056 spec->autocfg.speaker_pins[0] = 0x14;
14057 spec->automute_mixer_nid[0] = 0x0c;
14058 spec->automute = 1;
14059 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14060 spec->ext_mic_pin = 0x18;
14061 spec->int_mic_pin = 0x12;
14062 spec->auto_mic = 1;
14063}
14064
14065/*
14066 * generic initialization of ADC, input mixers and output mixers
14067 */
14068static const struct hda_verb alc269_init_verbs[] = {
14069 /*
14070 * Unmute ADC0 and set the default input to mic-in
14071 */
14072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14073
14074 /*
14075 * Set up output mixers (0x02 - 0x03)
14076 */
14077 /* set vol=0 to output mixers */
14078 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14079 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14080
14081 /* set up input amps for analog loopback */
14082 /* Amp Indices: DAC = 0, mixer = 1 */
14083 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14084 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14085 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14086 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14087 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14088 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14089
14090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14091 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14092 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14093 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14094 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14097
14098 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14100
14101 /* FIXME: use Mux-type input source selection */
14102 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14103 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14104 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14105
14106 /* set EAPD */
14107 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14108 { }
14109};
14110
14111static const struct hda_verb alc269vb_init_verbs[] = {
14112 /*
14113 * Unmute ADC0 and set the default input to mic-in
14114 */
14115 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14116
14117 /*
14118 * Set up output mixers (0x02 - 0x03)
14119 */
14120 /* set vol=0 to output mixers */
14121 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14122 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14123
14124 /* set up input amps for analog loopback */
14125 /* Amp Indices: DAC = 0, mixer = 1 */
14126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14127 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14128 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14129 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14130 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14131 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14132
14133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14134 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14135 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14136 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14137 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14138 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14139 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14140
14141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14142 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14143
14144 /* FIXME: use Mux-type input source selection */
14145 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14146 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14147 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14148
14149 /* set EAPD */
14150 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14151 { }
14152};
14153
14154#define alc269_auto_create_multi_out_ctls \ 4866#define alc269_auto_create_multi_out_ctls \
14155 alc268_auto_create_multi_out_ctls 4867 alc268_auto_create_multi_out_ctls
14156 4868
@@ -14438,203 +5150,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14438}; 5150};
14439 5151
14440 5152
14441/*
14442 * configuration and preset
14443 */
14444static const char * const alc269_models[ALC269_MODEL_LAST] = {
14445 [ALC269_BASIC] = "basic",
14446 [ALC269_QUANTA_FL1] = "quanta",
14447 [ALC269_AMIC] = "laptop-amic",
14448 [ALC269_DMIC] = "laptop-dmic",
14449 [ALC269_FUJITSU] = "fujitsu",
14450 [ALC269_LIFEBOOK] = "lifebook",
14451 [ALC269_AUTO] = "auto",
14452};
14453
14454static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14455 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14456 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14457 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14458 ALC269_AMIC),
14459 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14460 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14461 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14462 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14463 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14464 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14465 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14466 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14467 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14468 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
14469 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14470 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14471 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14472 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14473 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14474 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14475 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14476 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14477 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14478 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14479 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14480 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14481 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14482 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14483 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14484 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14485 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14486 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14487 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14488 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14489 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14490 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14491 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14492 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14493 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14494 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14495 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14496 ALC269_DMIC),
14497 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14498 ALC269_DMIC),
14499 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14500 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14501 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14502 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14503 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14504 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14505 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14506 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14507 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14508 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14509 {}
14510};
14511
14512static const struct alc_config_preset alc269_presets[] = {
14513 [ALC269_BASIC] = {
14514 .mixers = { alc269_base_mixer },
14515 .init_verbs = { alc269_init_verbs },
14516 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14517 .dac_nids = alc269_dac_nids,
14518 .hp_nid = 0x03,
14519 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14520 .channel_mode = alc269_modes,
14521 .input_mux = &alc269_capture_source,
14522 },
14523 [ALC269_QUANTA_FL1] = {
14524 .mixers = { alc269_quanta_fl1_mixer },
14525 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14526 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14527 .dac_nids = alc269_dac_nids,
14528 .hp_nid = 0x03,
14529 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14530 .channel_mode = alc269_modes,
14531 .input_mux = &alc269_capture_source,
14532 .unsol_event = alc269_quanta_fl1_unsol_event,
14533 .setup = alc269_quanta_fl1_setup,
14534 .init_hook = alc269_quanta_fl1_init_hook,
14535 },
14536 [ALC269_AMIC] = {
14537 .mixers = { alc269_laptop_mixer },
14538 .cap_mixer = alc269_laptop_analog_capture_mixer,
14539 .init_verbs = { alc269_init_verbs,
14540 alc269_laptop_amic_init_verbs },
14541 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14542 .dac_nids = alc269_dac_nids,
14543 .hp_nid = 0x03,
14544 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14545 .channel_mode = alc269_modes,
14546 .unsol_event = alc_sku_unsol_event,
14547 .setup = alc269_laptop_amic_setup,
14548 .init_hook = alc_inithook,
14549 },
14550 [ALC269_DMIC] = {
14551 .mixers = { alc269_laptop_mixer },
14552 .cap_mixer = alc269_laptop_digital_capture_mixer,
14553 .init_verbs = { alc269_init_verbs,
14554 alc269_laptop_dmic_init_verbs },
14555 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14556 .dac_nids = alc269_dac_nids,
14557 .hp_nid = 0x03,
14558 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14559 .channel_mode = alc269_modes,
14560 .unsol_event = alc_sku_unsol_event,
14561 .setup = alc269_laptop_dmic_setup,
14562 .init_hook = alc_inithook,
14563 },
14564 [ALC269VB_AMIC] = {
14565 .mixers = { alc269vb_laptop_mixer },
14566 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14567 .init_verbs = { alc269vb_init_verbs,
14568 alc269vb_laptop_amic_init_verbs },
14569 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14570 .dac_nids = alc269_dac_nids,
14571 .hp_nid = 0x03,
14572 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14573 .channel_mode = alc269_modes,
14574 .unsol_event = alc_sku_unsol_event,
14575 .setup = alc269vb_laptop_amic_setup,
14576 .init_hook = alc_inithook,
14577 },
14578 [ALC269VB_DMIC] = {
14579 .mixers = { alc269vb_laptop_mixer },
14580 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14581 .init_verbs = { alc269vb_init_verbs,
14582 alc269vb_laptop_dmic_init_verbs },
14583 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14584 .dac_nids = alc269_dac_nids,
14585 .hp_nid = 0x03,
14586 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14587 .channel_mode = alc269_modes,
14588 .unsol_event = alc_sku_unsol_event,
14589 .setup = alc269vb_laptop_dmic_setup,
14590 .init_hook = alc_inithook,
14591 },
14592 [ALC269_FUJITSU] = {
14593 .mixers = { alc269_fujitsu_mixer },
14594 .cap_mixer = alc269_laptop_digital_capture_mixer,
14595 .init_verbs = { alc269_init_verbs,
14596 alc269_laptop_dmic_init_verbs },
14597 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14598 .dac_nids = alc269_dac_nids,
14599 .hp_nid = 0x03,
14600 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14601 .channel_mode = alc269_modes,
14602 .unsol_event = alc_sku_unsol_event,
14603 .setup = alc269_laptop_dmic_setup,
14604 .init_hook = alc_inithook,
14605 },
14606 [ALC269_LIFEBOOK] = {
14607 .mixers = { alc269_lifebook_mixer },
14608 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14609 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14610 .dac_nids = alc269_dac_nids,
14611 .hp_nid = 0x03,
14612 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14613 .channel_mode = alc269_modes,
14614 .input_mux = &alc269_capture_source,
14615 .unsol_event = alc269_lifebook_unsol_event,
14616 .setup = alc269_lifebook_setup,
14617 .init_hook = alc269_lifebook_init_hook,
14618 },
14619 [ALC271_ACER] = {
14620 .mixers = { alc269_asus_mixer },
14621 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14622 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14623 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14624 .dac_nids = alc269_dac_nids,
14625 .adc_nids = alc262_dmic_adc_nids,
14626 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14627 .capsrc_nids = alc262_dmic_capsrc_nids,
14628 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14629 .channel_mode = alc269_modes,
14630 .input_mux = &alc269_capture_source,
14631 .dig_out_nid = ALC880_DIGOUT_NID,
14632 .unsol_event = alc_sku_unsol_event,
14633 .setup = alc269vb_laptop_dmic_setup,
14634 .init_hook = alc_inithook,
14635 },
14636};
14637
14638static int alc269_fill_coef(struct hda_codec *codec) 5153static int alc269_fill_coef(struct hda_codec *codec)
14639{ 5154{
14640 int val; 5155 int val;
@@ -14677,6 +5192,12 @@ static int alc269_fill_coef(struct hda_codec *codec)
14677 return 0; 5192 return 0;
14678} 5193}
14679 5194
5195/*
5196 */
5197#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5198#include "alc269_quirks.c"
5199#endif
5200
14680static int patch_alc269(struct hda_codec *codec) 5201static int patch_alc269(struct hda_codec *codec)
14681{ 5202{
14682 struct alc_spec *spec; 5203 struct alc_spec *spec;
@@ -14726,33 +5247,35 @@ static int patch_alc269(struct hda_codec *codec)
14726 alc269_fill_coef(codec); 5247 alc269_fill_coef(codec);
14727 } 5248 }
14728 5249
14729 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 5250 board_config = alc_board_config(codec, ALC269_MODEL_LAST,
14730 alc269_models, 5251 alc269_models, alc269_cfg_tbl);
14731 alc269_cfg_tbl);
14732 5252
14733 if (board_config < 0) { 5253 if (board_config < 0) {
14734 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5254 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14735 codec->chip_name); 5255 codec->chip_name);
14736 board_config = ALC269_AUTO; 5256 board_config = ALC_MODEL_AUTO;
14737 } 5257 }
14738 5258
14739 if (board_config == ALC269_AUTO) { 5259 if (board_config == ALC_MODEL_AUTO) {
14740 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); 5260 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
14741 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5261 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
14742 } 5262 }
14743 5263
14744 if (board_config == ALC269_AUTO) { 5264 if (board_config == ALC_MODEL_AUTO) {
14745 /* automatic parse from the BIOS config */ 5265 /* automatic parse from the BIOS config */
14746 err = alc269_parse_auto_config(codec); 5266 err = alc269_parse_auto_config(codec);
14747 if (err < 0) { 5267 if (err < 0) {
14748 alc_free(codec); 5268 alc_free(codec);
14749 return err; 5269 return err;
14750 } else if (!err) { 5270 }
5271#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5272 else if (!err) {
14751 printk(KERN_INFO 5273 printk(KERN_INFO
14752 "hda_codec: Cannot set up configuration " 5274 "hda_codec: Cannot set up configuration "
14753 "from BIOS. Using base mode...\n"); 5275 "from BIOS. Using base mode...\n");
14754 board_config = ALC269_BASIC; 5276 board_config = ALC269_BASIC;
14755 } 5277 }
5278#endif
14756 } 5279 }
14757 5280
14758 if (has_cdefine_beep(codec)) { 5281 if (has_cdefine_beep(codec)) {
@@ -14763,9 +5286,10 @@ static int patch_alc269(struct hda_codec *codec)
14763 } 5286 }
14764 } 5287 }
14765 5288
14766 if (board_config != ALC269_AUTO) 5289 if (board_config != ALC_MODEL_AUTO)
14767 setup_preset(codec, &alc269_presets[board_config]); 5290 setup_preset(codec, &alc269_presets[board_config]);
14768 5291
5292#if 0
14769 if (board_config == ALC269_QUANTA_FL1) { 5293 if (board_config == ALC269_QUANTA_FL1) {
14770 /* Due to a hardware problem on Lenovo Ideadpad, we need to 5294 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14771 * fix the sample rate of analog I/O to 44.1kHz 5295 * fix the sample rate of analog I/O to 44.1kHz
@@ -14773,6 +5297,7 @@ static int patch_alc269(struct hda_codec *codec)
14773 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 5297 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14774 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 5298 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14775 } 5299 }
5300#endif
14776 5301
14777 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 5302 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14778 alc_auto_fill_adc_caps(codec); 5303 alc_auto_fill_adc_caps(codec);
@@ -14793,7 +5318,7 @@ static int patch_alc269(struct hda_codec *codec)
14793#ifdef SND_HDA_NEEDS_RESUME 5318#ifdef SND_HDA_NEEDS_RESUME
14794 codec->patch_ops.resume = alc269_resume; 5319 codec->patch_ops.resume = alc269_resume;
14795#endif 5320#endif
14796 if (board_config == ALC269_AUTO) 5321 if (board_config == ALC_MODEL_AUTO)
14797 spec->init_hook = alc269_auto_init; 5322 spec->init_hook = alc269_auto_init;
14798 spec->shutup = alc269_shutup; 5323 spec->shutup = alc269_shutup;
14799 5324
@@ -14809,564 +5334,8 @@ static int patch_alc269(struct hda_codec *codec)
14809} 5334}
14810 5335
14811/* 5336/*
14812 * ALC861 channel source setting (2/6 channel selection for 3-stack) 5337 * ALC861
14813 */
14814
14815/*
14816 * set the path ways for 2 channel output
14817 * need to set the codec line out and mic 1 pin widgets to inputs
14818 */ 5338 */
14819static const struct hda_verb alc861_threestack_ch2_init[] = {
14820 /* set pin widget 1Ah (line in) for input */
14821 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14822 /* set pin widget 18h (mic1/2) for input, for mic also enable
14823 * the vref
14824 */
14825 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14826
14827 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14828#if 0
14829 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14830 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14831#endif
14832 { } /* end */
14833};
14834/*
14835 * 6ch mode
14836 * need to set the codec line out and mic 1 pin widgets to outputs
14837 */
14838static const struct hda_verb alc861_threestack_ch6_init[] = {
14839 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14840 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14841 /* set pin widget 18h (mic1) for output (CLFE)*/
14842 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14843
14844 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14845 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14846
14847 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14848#if 0
14849 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14850 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14851#endif
14852 { } /* end */
14853};
14854
14855static const struct hda_channel_mode alc861_threestack_modes[2] = {
14856 { 2, alc861_threestack_ch2_init },
14857 { 6, alc861_threestack_ch6_init },
14858};
14859/* Set mic1 as input and unmute the mixer */
14860static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14861 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14862 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14863 { } /* end */
14864};
14865/* Set mic1 as output and mute mixer */
14866static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14867 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14868 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14869 { } /* end */
14870};
14871
14872static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14873 { 2, alc861_uniwill_m31_ch2_init },
14874 { 4, alc861_uniwill_m31_ch4_init },
14875};
14876
14877/* Set mic1 and line-in as input and unmute the mixer */
14878static const struct hda_verb alc861_asus_ch2_init[] = {
14879 /* set pin widget 1Ah (line in) for input */
14880 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14881 /* set pin widget 18h (mic1/2) for input, for mic also enable
14882 * the vref
14883 */
14884 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14885
14886 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14887#if 0
14888 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14889 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14890#endif
14891 { } /* end */
14892};
14893/* Set mic1 nad line-in as output and mute mixer */
14894static const struct hda_verb alc861_asus_ch6_init[] = {
14895 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14896 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14897 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14898 /* set pin widget 18h (mic1) for output (CLFE)*/
14899 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14900 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14901 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14902 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14903
14904 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14905#if 0
14906 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14907 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14908#endif
14909 { } /* end */
14910};
14911
14912static const struct hda_channel_mode alc861_asus_modes[2] = {
14913 { 2, alc861_asus_ch2_init },
14914 { 6, alc861_asus_ch6_init },
14915};
14916
14917/* patch-ALC861 */
14918
14919static const struct snd_kcontrol_new alc861_base_mixer[] = {
14920 /* output mixer control */
14921 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14922 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14923 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14924 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14925 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14926
14927 /*Input mixer control */
14928 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14929 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14930 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14931 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14932 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14933 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14935 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14937 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14938
14939 { } /* end */
14940};
14941
14942static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
14943 /* output mixer control */
14944 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14945 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14946 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14947 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14948 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14949
14950 /* Input mixer control */
14951 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14952 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14953 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14954 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14955 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14956 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14957 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14958 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14959 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14961
14962 {
14963 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14964 .name = "Channel Mode",
14965 .info = alc_ch_mode_info,
14966 .get = alc_ch_mode_get,
14967 .put = alc_ch_mode_put,
14968 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14969 },
14970 { } /* end */
14971};
14972
14973static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
14974 /* output mixer control */
14975 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14977 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14978
14979 { } /* end */
14980};
14981
14982static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14983 /* output mixer control */
14984 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14985 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14986 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14987 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14988 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14989
14990 /* Input mixer control */
14991 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14992 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14993 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14994 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14995 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14996 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14998 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15001
15002 {
15003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15004 .name = "Channel Mode",
15005 .info = alc_ch_mode_info,
15006 .get = alc_ch_mode_get,
15007 .put = alc_ch_mode_put,
15008 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15009 },
15010 { } /* end */
15011};
15012
15013static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15014 /* output mixer control */
15015 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15016 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15017 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15018 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15019 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15020
15021 /* Input mixer control */
15022 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15023 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15024 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15025 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15026 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15027 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15028 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15029 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15032
15033 {
15034 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15035 .name = "Channel Mode",
15036 .info = alc_ch_mode_info,
15037 .get = alc_ch_mode_get,
15038 .put = alc_ch_mode_put,
15039 .private_value = ARRAY_SIZE(alc861_asus_modes),
15040 },
15041 { }
15042};
15043
15044/* additional mixer */
15045static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15046 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15047 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15048 { }
15049};
15050
15051/*
15052 * generic initialization of ADC, input mixers and output mixers
15053 */
15054static const struct hda_verb alc861_base_init_verbs[] = {
15055 /*
15056 * Unmute ADC0 and set the default input to mic-in
15057 */
15058 /* port-A for surround (rear panel) */
15059 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15060 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15061 /* port-B for mic-in (rear panel) with vref */
15062 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15063 /* port-C for line-in (rear panel) */
15064 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15065 /* port-D for Front */
15066 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15067 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15068 /* port-E for HP out (front panel) */
15069 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15070 /* route front PCM to HP */
15071 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15072 /* port-F for mic-in (front panel) with vref */
15073 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15074 /* port-G for CLFE (rear panel) */
15075 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15076 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15077 /* port-H for side (rear panel) */
15078 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15079 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15080 /* CD-in */
15081 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15082 /* route front mic to ADC1*/
15083 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15084 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15085
15086 /* Unmute DAC0~3 & spdif out*/
15087 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15088 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15089 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15090 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15091 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15092
15093 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15094 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15095 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15096 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15097 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15098
15099 /* Unmute Stereo Mixer 15 */
15100 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15101 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15103 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15104
15105 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15106 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15107 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15108 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15109 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15110 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15111 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15112 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15113 /* hp used DAC 3 (Front) */
15114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15115 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15116
15117 { }
15118};
15119
15120static const struct hda_verb alc861_threestack_init_verbs[] = {
15121 /*
15122 * Unmute ADC0 and set the default input to mic-in
15123 */
15124 /* port-A for surround (rear panel) */
15125 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15126 /* port-B for mic-in (rear panel) with vref */
15127 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15128 /* port-C for line-in (rear panel) */
15129 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15130 /* port-D for Front */
15131 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15132 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15133 /* port-E for HP out (front panel) */
15134 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15135 /* route front PCM to HP */
15136 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15137 /* port-F for mic-in (front panel) with vref */
15138 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15139 /* port-G for CLFE (rear panel) */
15140 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15141 /* port-H for side (rear panel) */
15142 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15143 /* CD-in */
15144 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15145 /* route front mic to ADC1*/
15146 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15148 /* Unmute DAC0~3 & spdif out*/
15149 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15150 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15151 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15152 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15154
15155 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15156 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15157 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15158 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15159 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15160
15161 /* Unmute Stereo Mixer 15 */
15162 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15163 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15166
15167 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15168 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15170 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15171 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15172 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15174 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15175 /* hp used DAC 3 (Front) */
15176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15177 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15178 { }
15179};
15180
15181static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15182 /*
15183 * Unmute ADC0 and set the default input to mic-in
15184 */
15185 /* port-A for surround (rear panel) */
15186 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15187 /* port-B for mic-in (rear panel) with vref */
15188 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15189 /* port-C for line-in (rear panel) */
15190 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15191 /* port-D for Front */
15192 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15193 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15194 /* port-E for HP out (front panel) */
15195 /* this has to be set to VREF80 */
15196 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15197 /* route front PCM to HP */
15198 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15199 /* port-F for mic-in (front panel) with vref */
15200 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15201 /* port-G for CLFE (rear panel) */
15202 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15203 /* port-H for side (rear panel) */
15204 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15205 /* CD-in */
15206 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15207 /* route front mic to ADC1*/
15208 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15210 /* Unmute DAC0~3 & spdif out*/
15211 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15212 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15213 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15214 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15215 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15216
15217 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15218 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15219 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15220 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15221 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15222
15223 /* Unmute Stereo Mixer 15 */
15224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15226 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15227 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15228
15229 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15230 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15231 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15232 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15233 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15234 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15235 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15237 /* hp used DAC 3 (Front) */
15238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15239 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15240 { }
15241};
15242
15243static const struct hda_verb alc861_asus_init_verbs[] = {
15244 /*
15245 * Unmute ADC0 and set the default input to mic-in
15246 */
15247 /* port-A for surround (rear panel)
15248 * according to codec#0 this is the HP jack
15249 */
15250 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15251 /* route front PCM to HP */
15252 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15253 /* port-B for mic-in (rear panel) with vref */
15254 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15255 /* port-C for line-in (rear panel) */
15256 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15257 /* port-D for Front */
15258 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15259 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15260 /* port-E for HP out (front panel) */
15261 /* this has to be set to VREF80 */
15262 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15263 /* route front PCM to HP */
15264 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15265 /* port-F for mic-in (front panel) with vref */
15266 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15267 /* port-G for CLFE (rear panel) */
15268 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15269 /* port-H for side (rear panel) */
15270 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15271 /* CD-in */
15272 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15273 /* route front mic to ADC1*/
15274 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15275 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15276 /* Unmute DAC0~3 & spdif out*/
15277 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15278 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15279 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15280 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15282 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15283 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15284 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15285 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15286 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15287
15288 /* Unmute Stereo Mixer 15 */
15289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15290 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15292 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15293
15294 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15295 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15296 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15297 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15298 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15299 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15300 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15301 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15302 /* hp used DAC 3 (Front) */
15303 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15304 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15305 { }
15306};
15307
15308/* additional init verbs for ASUS laptops */
15309static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15310 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15311 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15312 { }
15313};
15314
15315static const struct hda_verb alc861_toshiba_init_verbs[] = {
15316 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15317
15318 { }
15319};
15320
15321/* toggle speaker-output according to the hp-jack state */
15322static void alc861_toshiba_automute(struct hda_codec *codec)
15323{
15324 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15325
15326 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15327 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15328 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15329 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15330}
15331
15332static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15333 unsigned int res)
15334{
15335 if ((res >> 26) == ALC880_HP_EVENT)
15336 alc861_toshiba_automute(codec);
15337}
15338
15339#define ALC861_DIGOUT_NID 0x07
15340
15341static const struct hda_channel_mode alc861_8ch_modes[1] = {
15342 { 8, NULL }
15343};
15344
15345static const hda_nid_t alc861_dac_nids[4] = {
15346 /* front, surround, clfe, side */
15347 0x03, 0x06, 0x05, 0x04
15348};
15349
15350static const hda_nid_t alc660_dac_nids[3] = {
15351 /* front, clfe, surround */
15352 0x03, 0x05, 0x06
15353};
15354
15355static const hda_nid_t alc861_adc_nids[1] = {
15356 /* ADC0-2 */
15357 0x08,
15358};
15359
15360static const struct hda_input_mux alc861_capture_source = {
15361 .num_items = 5,
15362 .items = {
15363 { "Mic", 0x0 },
15364 { "Front Mic", 0x3 },
15365 { "Line", 0x1 },
15366 { "CD", 0x4 },
15367 { "Mixer", 0x5 },
15368 },
15369};
15370 5339
15371static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 5340static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15372{ 5341{
@@ -15607,152 +5576,6 @@ static const struct hda_amp_list alc861_loopbacks[] = {
15607#endif 5576#endif
15608 5577
15609 5578
15610/*
15611 * configuration and preset
15612 */
15613static const char * const alc861_models[ALC861_MODEL_LAST] = {
15614 [ALC861_3ST] = "3stack",
15615 [ALC660_3ST] = "3stack-660",
15616 [ALC861_3ST_DIG] = "3stack-dig",
15617 [ALC861_6ST_DIG] = "6stack-dig",
15618 [ALC861_UNIWILL_M31] = "uniwill-m31",
15619 [ALC861_TOSHIBA] = "toshiba",
15620 [ALC861_ASUS] = "asus",
15621 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15622 [ALC861_AUTO] = "auto",
15623};
15624
15625static const struct snd_pci_quirk alc861_cfg_tbl[] = {
15626 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
15627 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15628 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15629 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
15630 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
15631 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
15632 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
15633 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15634 * Any other models that need this preset?
15635 */
15636 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
15637 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15638 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
15639 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
15640 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15641 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15642 /* FIXME: the below seems conflict */
15643 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
15644 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
15645 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
15646 {}
15647};
15648
15649static const struct alc_config_preset alc861_presets[] = {
15650 [ALC861_3ST] = {
15651 .mixers = { alc861_3ST_mixer },
15652 .init_verbs = { alc861_threestack_init_verbs },
15653 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15654 .dac_nids = alc861_dac_nids,
15655 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15656 .channel_mode = alc861_threestack_modes,
15657 .need_dac_fix = 1,
15658 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15659 .adc_nids = alc861_adc_nids,
15660 .input_mux = &alc861_capture_source,
15661 },
15662 [ALC861_3ST_DIG] = {
15663 .mixers = { alc861_base_mixer },
15664 .init_verbs = { alc861_threestack_init_verbs },
15665 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15666 .dac_nids = alc861_dac_nids,
15667 .dig_out_nid = ALC861_DIGOUT_NID,
15668 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15669 .channel_mode = alc861_threestack_modes,
15670 .need_dac_fix = 1,
15671 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15672 .adc_nids = alc861_adc_nids,
15673 .input_mux = &alc861_capture_source,
15674 },
15675 [ALC861_6ST_DIG] = {
15676 .mixers = { alc861_base_mixer },
15677 .init_verbs = { alc861_base_init_verbs },
15678 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15679 .dac_nids = alc861_dac_nids,
15680 .dig_out_nid = ALC861_DIGOUT_NID,
15681 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15682 .channel_mode = alc861_8ch_modes,
15683 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15684 .adc_nids = alc861_adc_nids,
15685 .input_mux = &alc861_capture_source,
15686 },
15687 [ALC660_3ST] = {
15688 .mixers = { alc861_3ST_mixer },
15689 .init_verbs = { alc861_threestack_init_verbs },
15690 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15691 .dac_nids = alc660_dac_nids,
15692 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15693 .channel_mode = alc861_threestack_modes,
15694 .need_dac_fix = 1,
15695 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15696 .adc_nids = alc861_adc_nids,
15697 .input_mux = &alc861_capture_source,
15698 },
15699 [ALC861_UNIWILL_M31] = {
15700 .mixers = { alc861_uniwill_m31_mixer },
15701 .init_verbs = { alc861_uniwill_m31_init_verbs },
15702 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15703 .dac_nids = alc861_dac_nids,
15704 .dig_out_nid = ALC861_DIGOUT_NID,
15705 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15706 .channel_mode = alc861_uniwill_m31_modes,
15707 .need_dac_fix = 1,
15708 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15709 .adc_nids = alc861_adc_nids,
15710 .input_mux = &alc861_capture_source,
15711 },
15712 [ALC861_TOSHIBA] = {
15713 .mixers = { alc861_toshiba_mixer },
15714 .init_verbs = { alc861_base_init_verbs,
15715 alc861_toshiba_init_verbs },
15716 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15717 .dac_nids = alc861_dac_nids,
15718 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15719 .channel_mode = alc883_3ST_2ch_modes,
15720 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15721 .adc_nids = alc861_adc_nids,
15722 .input_mux = &alc861_capture_source,
15723 .unsol_event = alc861_toshiba_unsol_event,
15724 .init_hook = alc861_toshiba_automute,
15725 },
15726 [ALC861_ASUS] = {
15727 .mixers = { alc861_asus_mixer },
15728 .init_verbs = { alc861_asus_init_verbs },
15729 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15730 .dac_nids = alc861_dac_nids,
15731 .dig_out_nid = ALC861_DIGOUT_NID,
15732 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15733 .channel_mode = alc861_asus_modes,
15734 .need_dac_fix = 1,
15735 .hp_nid = 0x06,
15736 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15737 .adc_nids = alc861_adc_nids,
15738 .input_mux = &alc861_capture_source,
15739 },
15740 [ALC861_ASUS_LAPTOP] = {
15741 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15742 .init_verbs = { alc861_asus_init_verbs,
15743 alc861_asus_laptop_init_verbs },
15744 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15745 .dac_nids = alc861_dac_nids,
15746 .dig_out_nid = ALC861_DIGOUT_NID,
15747 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15748 .channel_mode = alc883_3ST_2ch_modes,
15749 .need_dac_fix = 1,
15750 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15751 .adc_nids = alc861_adc_nids,
15752 .input_mux = &alc861_capture_source,
15753 },
15754};
15755
15756/* Pin config fixes */ 5579/* Pin config fixes */
15757enum { 5580enum {
15758 PINFIX_FSC_AMILO_PI1505, 5581 PINFIX_FSC_AMILO_PI1505,
@@ -15774,6 +5597,12 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = {
15774 {} 5597 {}
15775}; 5598};
15776 5599
5600/*
5601 */
5602#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5603#include "alc861_quirks.c"
5604#endif
5605
15777static int patch_alc861(struct hda_codec *codec) 5606static int patch_alc861(struct hda_codec *codec)
15778{ 5607{
15779 struct alc_spec *spec; 5608 struct alc_spec *spec;
@@ -15788,33 +5617,35 @@ static int patch_alc861(struct hda_codec *codec)
15788 5617
15789 spec->mixer_nid = 0x15; 5618 spec->mixer_nid = 0x15;
15790 5619
15791 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 5620 board_config = alc_board_config(codec, ALC861_MODEL_LAST,
15792 alc861_models, 5621 alc861_models, alc861_cfg_tbl);
15793 alc861_cfg_tbl);
15794 5622
15795 if (board_config < 0) { 5623 if (board_config < 0) {
15796 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5624 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15797 codec->chip_name); 5625 codec->chip_name);
15798 board_config = ALC861_AUTO; 5626 board_config = ALC_MODEL_AUTO;
15799 } 5627 }
15800 5628
15801 if (board_config == ALC861_AUTO) { 5629 if (board_config == ALC_MODEL_AUTO) {
15802 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 5630 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
15803 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5631 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15804 } 5632 }
15805 5633
15806 if (board_config == ALC861_AUTO) { 5634 if (board_config == ALC_MODEL_AUTO) {
15807 /* automatic parse from the BIOS config */ 5635 /* automatic parse from the BIOS config */
15808 err = alc861_parse_auto_config(codec); 5636 err = alc861_parse_auto_config(codec);
15809 if (err < 0) { 5637 if (err < 0) {
15810 alc_free(codec); 5638 alc_free(codec);
15811 return err; 5639 return err;
15812 } else if (!err) { 5640 }
5641#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5642 else if (!err) {
15813 printk(KERN_INFO 5643 printk(KERN_INFO
15814 "hda_codec: Cannot set up configuration " 5644 "hda_codec: Cannot set up configuration "
15815 "from BIOS. Using base mode...\n"); 5645 "from BIOS. Using base mode...\n");
15816 board_config = ALC861_3ST_DIG; 5646 board_config = ALC861_3ST_DIG;
15817 } 5647 }
5648#endif
15818 } 5649 }
15819 5650
15820 err = snd_hda_attach_beep_device(codec, 0x23); 5651 err = snd_hda_attach_beep_device(codec, 0x23);
@@ -15823,7 +5654,7 @@ static int patch_alc861(struct hda_codec *codec)
15823 return err; 5654 return err;
15824 } 5655 }
15825 5656
15826 if (board_config != ALC861_AUTO) 5657 if (board_config != ALC_MODEL_AUTO)
15827 setup_preset(codec, &alc861_presets[board_config]); 5658 setup_preset(codec, &alc861_presets[board_config]);
15828 5659
15829 if (!spec->adc_nids) { 5660 if (!spec->adc_nids) {
@@ -15841,7 +5672,7 @@ static int patch_alc861(struct hda_codec *codec)
15841 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 5672 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15842 5673
15843 codec->patch_ops = alc_patch_ops; 5674 codec->patch_ops = alc_patch_ops;
15844 if (board_config == ALC861_AUTO) { 5675 if (board_config == ALC_MODEL_AUTO) {
15845 spec->init_hook = alc861_auto_init; 5676 spec->init_hook = alc861_auto_init;
15846#ifdef CONFIG_SND_HDA_POWER_SAVE 5677#ifdef CONFIG_SND_HDA_POWER_SAVE
15847 spec->power_hook = alc_power_eapd; 5678 spec->power_hook = alc_power_eapd;
@@ -15862,604 +5693,19 @@ static int patch_alc861(struct hda_codec *codec)
15862 * 5693 *
15863 * In addition, an independent DAC 5694 * In addition, an independent DAC
15864 */ 5695 */
15865#define ALC861VD_DIGOUT_NID 0x06
15866
15867static const hda_nid_t alc861vd_dac_nids[4] = {
15868 /* front, surr, clfe, side surr */
15869 0x02, 0x03, 0x04, 0x05
15870};
15871
15872/* dac_nids for ALC660vd are in a different order - according to
15873 * Realtek's driver.
15874 * This should probably result in a different mixer for 6stack models
15875 * of ALC660vd codecs, but for now there is only 3stack mixer
15876 * - and it is the same as in 861vd.
15877 * adc_nids in ALC660vd are (is) the same as in 861vd
15878 */
15879static const hda_nid_t alc660vd_dac_nids[3] = {
15880 /* front, rear, clfe, rear_surr */
15881 0x02, 0x04, 0x03
15882};
15883
15884static const hda_nid_t alc861vd_adc_nids[1] = {
15885 /* ADC0 */
15886 0x09,
15887};
15888
15889static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15890
15891/* input MUX */
15892/* FIXME: should be a matrix-type input source selection */
15893static const struct hda_input_mux alc861vd_capture_source = {
15894 .num_items = 4,
15895 .items = {
15896 { "Mic", 0x0 },
15897 { "Front Mic", 0x1 },
15898 { "Line", 0x2 },
15899 { "CD", 0x4 },
15900 },
15901};
15902
15903static const struct hda_input_mux alc861vd_dallas_capture_source = {
15904 .num_items = 2,
15905 .items = {
15906 { "Mic", 0x0 },
15907 { "Internal Mic", 0x1 },
15908 },
15909};
15910
15911static const struct hda_input_mux alc861vd_hp_capture_source = {
15912 .num_items = 2,
15913 .items = {
15914 { "Front Mic", 0x0 },
15915 { "ATAPI Mic", 0x1 },
15916 },
15917};
15918
15919/*
15920 * 2ch mode
15921 */
15922static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15923 { 2, NULL }
15924};
15925
15926/*
15927 * 6ch mode
15928 */
15929static const struct hda_verb alc861vd_6stack_ch6_init[] = {
15930 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15931 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15932 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15933 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15934 { } /* end */
15935};
15936
15937/*
15938 * 8ch mode
15939 */
15940static const struct hda_verb alc861vd_6stack_ch8_init[] = {
15941 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15942 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15943 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15944 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15945 { } /* end */
15946};
15947
15948static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
15949 { 6, alc861vd_6stack_ch6_init },
15950 { 8, alc861vd_6stack_ch8_init },
15951};
15952
15953static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15954 {
15955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15956 .name = "Channel Mode",
15957 .info = alc_ch_mode_info,
15958 .get = alc_ch_mode_get,
15959 .put = alc_ch_mode_put,
15960 },
15961 { } /* end */
15962};
15963
15964/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15965 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15966 */
15967static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15968 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15969 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15970
15971 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15972 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15973
15974 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15975 HDA_OUTPUT),
15976 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15977 HDA_OUTPUT),
15978 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15979 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15980
15981 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15982 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15983
15984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15985
15986 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
15987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15989
15990 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
15991 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15992 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15993
15994 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15995 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15996
15997 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15998 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15999
16000 { } /* end */
16001};
16002
16003static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16004 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16006
16007 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16008
16009 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16012
16013 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16014 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16016
16017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16019
16020 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16021 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16022
16023 { } /* end */
16024};
16025
16026static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16027 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16028 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16029 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16030
16031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16032
16033 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16036
16037 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16038 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16039 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16040
16041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16042 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16043
16044 { } /* end */
16045};
16046
16047/* Pin assignment: Speaker=0x14, HP = 0x15,
16048 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16049 */
16050static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16051 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16052 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16053 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16054 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16055 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16057 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16058 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16059 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16060 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16061 { } /* end */
16062};
16063
16064/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16065 * Front Mic=0x18, ATAPI Mic = 0x19,
16066 */
16067static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16068 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16069 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16071 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16072 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16073 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16074 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16075 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16076
16077 { } /* end */
16078};
16079
16080/*
16081 * generic initialization of ADC, input mixers and output mixers
16082 */
16083static const struct hda_verb alc861vd_volume_init_verbs[] = {
16084 /*
16085 * Unmute ADC0 and set the default input to mic-in
16086 */
16087 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16089
16090 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16091 * the analog-loopback mixer widget
16092 */
16093 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16099
16100 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16103 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16104 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16105
16106 /*
16107 * Set up output mixers (0x02 - 0x05)
16108 */
16109 /* set vol=0 to output mixers */
16110 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16111 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16112 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16113 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16114
16115 /* set up input amps for analog loopback */
16116 /* Amp Indices: DAC = 0, mixer = 1 */
16117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16123 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16124 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16125
16126 { }
16127};
16128
16129/*
16130 * 3-stack pin configuration:
16131 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16132 */
16133static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16134 /*
16135 * Set pin mode and muting
16136 */
16137 /* set front pin widgets 0x14 for output */
16138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16141
16142 /* Mic (rear) pin: input vref at 80% */
16143 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16144 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16145 /* Front Mic pin: input vref at 80% */
16146 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16147 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16148 /* Line In pin: input */
16149 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16150 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16151 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16152 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16153 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16154 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16155 /* CD pin widget for input */
16156 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16157
16158 { }
16159};
16160
16161/*
16162 * 6-stack pin configuration:
16163 */
16164static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16165 /*
16166 * Set pin mode and muting
16167 */
16168 /* set front pin widgets 0x14 for output */
16169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16171 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16172
16173 /* Rear Pin: output 1 (0x0d) */
16174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16176 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16177 /* CLFE Pin: output 2 (0x0e) */
16178 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16179 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16180 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16181 /* Side Pin: output 3 (0x0f) */
16182 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16183 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16184 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16185
16186 /* Mic (rear) pin: input vref at 80% */
16187 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16188 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16189 /* Front Mic pin: input vref at 80% */
16190 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16191 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16192 /* Line In pin: input */
16193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16194 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16195 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16196 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16198 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16199 /* CD pin widget for input */
16200 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16201
16202 { }
16203};
16204
16205static const struct hda_verb alc861vd_eapd_verbs[] = {
16206 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16207 { }
16208};
16209
16210static const struct hda_verb alc660vd_eapd_verbs[] = {
16211 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16212 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16213 { }
16214};
16215
16216static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16219 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16220 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16221 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16222 {}
16223};
16224
16225static void alc861vd_lenovo_setup(struct hda_codec *codec)
16226{
16227 struct alc_spec *spec = codec->spec;
16228 spec->autocfg.hp_pins[0] = 0x1b;
16229 spec->autocfg.speaker_pins[0] = 0x14;
16230 spec->automute = 1;
16231 spec->automute_mode = ALC_AUTOMUTE_AMP;
16232}
16233
16234static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16235{
16236 alc_hp_automute(codec);
16237 alc88x_simple_mic_automute(codec);
16238}
16239
16240static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16241 unsigned int res)
16242{
16243 switch (res >> 26) {
16244 case ALC880_MIC_EVENT:
16245 alc88x_simple_mic_automute(codec);
16246 break;
16247 default:
16248 alc_sku_unsol_event(codec, res);
16249 break;
16250 }
16251}
16252
16253static const struct hda_verb alc861vd_dallas_verbs[] = {
16254 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16255 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16256 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16257 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16258
16259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16260 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16261 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16262 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16265 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16267
16268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16273 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16274 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16275 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16276
16277 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16278 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16279 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16280 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16281 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16282 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16283 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16284 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16285
16286 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16290
16291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16292 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16293 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16294
16295 { } /* end */
16296};
16297
16298/* toggle speaker-output according to the hp-jack state */
16299static void alc861vd_dallas_setup(struct hda_codec *codec)
16300{
16301 struct alc_spec *spec = codec->spec;
16302
16303 spec->autocfg.hp_pins[0] = 0x15;
16304 spec->autocfg.speaker_pins[0] = 0x14;
16305 spec->automute = 1;
16306 spec->automute_mode = ALC_AUTOMUTE_AMP;
16307}
16308
16309#ifdef CONFIG_SND_HDA_POWER_SAVE 5696#ifdef CONFIG_SND_HDA_POWER_SAVE
16310#define alc861vd_loopbacks alc880_loopbacks 5697#define alc861vd_loopbacks alc880_loopbacks
16311#endif 5698#endif
16312 5699
16313/* 5700/*
16314 * configuration and preset
16315 */
16316static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16317 [ALC660VD_3ST] = "3stack-660",
16318 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16319 [ALC660VD_ASUS_V1S] = "asus-v1s",
16320 [ALC861VD_3ST] = "3stack",
16321 [ALC861VD_3ST_DIG] = "3stack-digout",
16322 [ALC861VD_6ST_DIG] = "6stack-digout",
16323 [ALC861VD_LENOVO] = "lenovo",
16324 [ALC861VD_DALLAS] = "dallas",
16325 [ALC861VD_HP] = "hp",
16326 [ALC861VD_AUTO] = "auto",
16327};
16328
16329static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16330 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16331 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16332 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16333 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16334 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16335 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16336 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16337 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16338 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16339 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16340 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16341 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16342 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16343 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16344 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16345 {}
16346};
16347
16348static const struct alc_config_preset alc861vd_presets[] = {
16349 [ALC660VD_3ST] = {
16350 .mixers = { alc861vd_3st_mixer },
16351 .init_verbs = { alc861vd_volume_init_verbs,
16352 alc861vd_3stack_init_verbs },
16353 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16354 .dac_nids = alc660vd_dac_nids,
16355 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16356 .channel_mode = alc861vd_3stack_2ch_modes,
16357 .input_mux = &alc861vd_capture_source,
16358 },
16359 [ALC660VD_3ST_DIG] = {
16360 .mixers = { alc861vd_3st_mixer },
16361 .init_verbs = { alc861vd_volume_init_verbs,
16362 alc861vd_3stack_init_verbs },
16363 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16364 .dac_nids = alc660vd_dac_nids,
16365 .dig_out_nid = ALC861VD_DIGOUT_NID,
16366 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16367 .channel_mode = alc861vd_3stack_2ch_modes,
16368 .input_mux = &alc861vd_capture_source,
16369 },
16370 [ALC861VD_3ST] = {
16371 .mixers = { alc861vd_3st_mixer },
16372 .init_verbs = { alc861vd_volume_init_verbs,
16373 alc861vd_3stack_init_verbs },
16374 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16375 .dac_nids = alc861vd_dac_nids,
16376 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16377 .channel_mode = alc861vd_3stack_2ch_modes,
16378 .input_mux = &alc861vd_capture_source,
16379 },
16380 [ALC861VD_3ST_DIG] = {
16381 .mixers = { alc861vd_3st_mixer },
16382 .init_verbs = { alc861vd_volume_init_verbs,
16383 alc861vd_3stack_init_verbs },
16384 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16385 .dac_nids = alc861vd_dac_nids,
16386 .dig_out_nid = ALC861VD_DIGOUT_NID,
16387 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16388 .channel_mode = alc861vd_3stack_2ch_modes,
16389 .input_mux = &alc861vd_capture_source,
16390 },
16391 [ALC861VD_6ST_DIG] = {
16392 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16393 .init_verbs = { alc861vd_volume_init_verbs,
16394 alc861vd_6stack_init_verbs },
16395 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16396 .dac_nids = alc861vd_dac_nids,
16397 .dig_out_nid = ALC861VD_DIGOUT_NID,
16398 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16399 .channel_mode = alc861vd_6stack_modes,
16400 .input_mux = &alc861vd_capture_source,
16401 },
16402 [ALC861VD_LENOVO] = {
16403 .mixers = { alc861vd_lenovo_mixer },
16404 .init_verbs = { alc861vd_volume_init_verbs,
16405 alc861vd_3stack_init_verbs,
16406 alc861vd_eapd_verbs,
16407 alc861vd_lenovo_unsol_verbs },
16408 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16409 .dac_nids = alc660vd_dac_nids,
16410 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16411 .channel_mode = alc861vd_3stack_2ch_modes,
16412 .input_mux = &alc861vd_capture_source,
16413 .unsol_event = alc861vd_lenovo_unsol_event,
16414 .setup = alc861vd_lenovo_setup,
16415 .init_hook = alc861vd_lenovo_init_hook,
16416 },
16417 [ALC861VD_DALLAS] = {
16418 .mixers = { alc861vd_dallas_mixer },
16419 .init_verbs = { alc861vd_dallas_verbs },
16420 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16421 .dac_nids = alc861vd_dac_nids,
16422 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16423 .channel_mode = alc861vd_3stack_2ch_modes,
16424 .input_mux = &alc861vd_dallas_capture_source,
16425 .unsol_event = alc_sku_unsol_event,
16426 .setup = alc861vd_dallas_setup,
16427 .init_hook = alc_hp_automute,
16428 },
16429 [ALC861VD_HP] = {
16430 .mixers = { alc861vd_hp_mixer },
16431 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16432 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16433 .dac_nids = alc861vd_dac_nids,
16434 .dig_out_nid = ALC861VD_DIGOUT_NID,
16435 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16436 .channel_mode = alc861vd_3stack_2ch_modes,
16437 .input_mux = &alc861vd_hp_capture_source,
16438 .unsol_event = alc_sku_unsol_event,
16439 .setup = alc861vd_dallas_setup,
16440 .init_hook = alc_hp_automute,
16441 },
16442 [ALC660VD_ASUS_V1S] = {
16443 .mixers = { alc861vd_lenovo_mixer },
16444 .init_verbs = { alc861vd_volume_init_verbs,
16445 alc861vd_3stack_init_verbs,
16446 alc861vd_eapd_verbs,
16447 alc861vd_lenovo_unsol_verbs },
16448 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16449 .dac_nids = alc660vd_dac_nids,
16450 .dig_out_nid = ALC861VD_DIGOUT_NID,
16451 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16452 .channel_mode = alc861vd_3stack_2ch_modes,
16453 .input_mux = &alc861vd_capture_source,
16454 .unsol_event = alc861vd_lenovo_unsol_event,
16455 .setup = alc861vd_lenovo_setup,
16456 .init_hook = alc861vd_lenovo_init_hook,
16457 },
16458};
16459
16460/*
16461 * BIOS auto configuration 5701 * BIOS auto configuration
16462 */ 5702 */
5703#define alc861vd_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5704#define alc861vd_fixed_pin_idx(nid) ((nid) - 0x14)
5705#define alc861vd_is_multi_pin(nid) ((nid) >= 0x18)
5706#define alc861vd_multi_pin_idx(nid) ((nid) - 0x18)
5707#define alc861vd_idx_to_dac(nid) ((nid) + 0x02)
5708#define alc861vd_dac_to_idx(nid) ((nid) - 0x02)
16463#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 5709#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16464#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 5710#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16465 5711
@@ -16482,10 +5728,10 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16482 if (!spec->multiout.dac_nids[i]) 5728 if (!spec->multiout.dac_nids[i])
16483 continue; 5729 continue;
16484 nid_v = alc861vd_idx_to_mixer_vol( 5730 nid_v = alc861vd_idx_to_mixer_vol(
16485 alc880_dac_to_idx( 5731 alc861vd_dac_to_idx(
16486 spec->multiout.dac_nids[i])); 5732 spec->multiout.dac_nids[i]));
16487 nid_s = alc861vd_idx_to_mixer_switch( 5733 nid_s = alc861vd_idx_to_mixer_switch(
16488 alc880_dac_to_idx( 5734 alc861vd_dac_to_idx(
16489 spec->multiout.dac_nids[i])); 5735 spec->multiout.dac_nids[i]));
16490 5736
16491 name = alc_get_line_out_pfx(spec, i, true, &index); 5737 name = alc_get_line_out_pfx(spec, i, true, &index);
@@ -16545,8 +5791,8 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16545 if (!pin) 5791 if (!pin)
16546 return 0; 5792 return 0;
16547 5793
16548 if (alc880_is_fixed_pin(pin)) { 5794 if (alc861vd_is_fixed_pin(pin)) {
16549 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 5795 nid_v = alc861vd_idx_to_dac(alc861vd_fixed_pin_idx(pin));
16550 /* specify the DAC as the extra output */ 5796 /* specify the DAC as the extra output */
16551 if (!spec->multiout.hp_nid) 5797 if (!spec->multiout.hp_nid)
16552 spec->multiout.hp_nid = nid_v; 5798 spec->multiout.hp_nid = nid_v;
@@ -16554,9 +5800,9 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16554 spec->multiout.extra_out_nid[0] = nid_v; 5800 spec->multiout.extra_out_nid[0] = nid_v;
16555 /* control HP volume/switch on the output mixer amp */ 5801 /* control HP volume/switch on the output mixer amp */
16556 nid_v = alc861vd_idx_to_mixer_vol( 5802 nid_v = alc861vd_idx_to_mixer_vol(
16557 alc880_fixed_pin_idx(pin)); 5803 alc861vd_fixed_pin_idx(pin));
16558 nid_s = alc861vd_idx_to_mixer_switch( 5804 nid_s = alc861vd_idx_to_mixer_switch(
16559 alc880_fixed_pin_idx(pin)); 5805 alc861vd_fixed_pin_idx(pin));
16560 5806
16561 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 5807 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16562 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 5808 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
@@ -16566,7 +5812,7 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16566 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 5812 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16567 if (err < 0) 5813 if (err < 0)
16568 return err; 5814 return err;
16569 } else if (alc880_is_multi_pin(pin)) { 5815 } else if (alc861vd_is_multi_pin(pin)) {
16570 /* set manual connection */ 5816 /* set manual connection */
16571 /* we have only a switch on HP-out PIN */ 5817 /* we have only a switch on HP-out PIN */
16572 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 5818 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
@@ -16672,6 +5918,18 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16672 {} 5918 {}
16673}; 5919};
16674 5920
5921static const struct hda_verb alc660vd_eapd_verbs[] = {
5922 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
5923 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5924 { }
5925};
5926
5927/*
5928 */
5929#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5930#include "alc861vd_quirks.c"
5931#endif
5932
16675static int patch_alc861vd(struct hda_codec *codec) 5933static int patch_alc861vd(struct hda_codec *codec)
16676{ 5934{
16677 struct alc_spec *spec; 5935 struct alc_spec *spec;
@@ -16685,33 +5943,35 @@ static int patch_alc861vd(struct hda_codec *codec)
16685 5943
16686 spec->mixer_nid = 0x0b; 5944 spec->mixer_nid = 0x0b;
16687 5945
16688 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 5946 board_config = alc_board_config(codec, ALC861VD_MODEL_LAST,
16689 alc861vd_models, 5947 alc861vd_models, alc861vd_cfg_tbl);
16690 alc861vd_cfg_tbl);
16691 5948
16692 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 5949 if (board_config < 0) {
16693 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5950 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16694 codec->chip_name); 5951 codec->chip_name);
16695 board_config = ALC861VD_AUTO; 5952 board_config = ALC_MODEL_AUTO;
16696 } 5953 }
16697 5954
16698 if (board_config == ALC861VD_AUTO) { 5955 if (board_config == ALC_MODEL_AUTO) {
16699 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 5956 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
16700 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5957 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16701 } 5958 }
16702 5959
16703 if (board_config == ALC861VD_AUTO) { 5960 if (board_config == ALC_MODEL_AUTO) {
16704 /* automatic parse from the BIOS config */ 5961 /* automatic parse from the BIOS config */
16705 err = alc861vd_parse_auto_config(codec); 5962 err = alc861vd_parse_auto_config(codec);
16706 if (err < 0) { 5963 if (err < 0) {
16707 alc_free(codec); 5964 alc_free(codec);
16708 return err; 5965 return err;
16709 } else if (!err) { 5966 }
5967#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5968 else if (!err) {
16710 printk(KERN_INFO 5969 printk(KERN_INFO
16711 "hda_codec: Cannot set up configuration " 5970 "hda_codec: Cannot set up configuration "
16712 "from BIOS. Using base mode...\n"); 5971 "from BIOS. Using base mode...\n");
16713 board_config = ALC861VD_3ST; 5972 board_config = ALC861VD_3ST;
16714 } 5973 }
5974#endif
16715 } 5975 }
16716 5976
16717 err = snd_hda_attach_beep_device(codec, 0x23); 5977 err = snd_hda_attach_beep_device(codec, 0x23);
@@ -16720,7 +5980,7 @@ static int patch_alc861vd(struct hda_codec *codec)
16720 return err; 5980 return err;
16721 } 5981 }
16722 5982
16723 if (board_config != ALC861VD_AUTO) 5983 if (board_config != ALC_MODEL_AUTO)
16724 setup_preset(codec, &alc861vd_presets[board_config]); 5984 setup_preset(codec, &alc861vd_presets[board_config]);
16725 5985
16726 if (codec->vendor_id == 0x10ec0660) { 5986 if (codec->vendor_id == 0x10ec0660) {
@@ -16743,7 +6003,7 @@ static int patch_alc861vd(struct hda_codec *codec)
16743 6003
16744 codec->patch_ops = alc_patch_ops; 6004 codec->patch_ops = alc_patch_ops;
16745 6005
16746 if (board_config == ALC861VD_AUTO) 6006 if (board_config == ALC_MODEL_AUTO)
16747 spec->init_hook = alc861vd_auto_init; 6007 spec->init_hook = alc861vd_auto_init;
16748 spec->shutup = alc_eapd_shutup; 6008 spec->shutup = alc_eapd_shutup;
16749#ifdef CONFIG_SND_HDA_POWER_SAVE 6009#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -16765,1913 +6025,14 @@ static int patch_alc861vd(struct hda_codec *codec)
16765 * In addition, an independent DAC for the multi-playback (not used in this 6025 * In addition, an independent DAC for the multi-playback (not used in this
16766 * driver yet). 6026 * driver yet).
16767 */ 6027 */
16768#define ALC662_DIGOUT_NID 0x06
16769#define ALC662_DIGIN_NID 0x0a
16770
16771static const hda_nid_t alc662_dac_nids[3] = {
16772 /* front, rear, clfe */
16773 0x02, 0x03, 0x04
16774};
16775
16776static const hda_nid_t alc272_dac_nids[2] = {
16777 0x02, 0x03
16778};
16779
16780static const hda_nid_t alc662_adc_nids[2] = {
16781 /* ADC1-2 */
16782 0x09, 0x08
16783};
16784
16785static const hda_nid_t alc272_adc_nids[1] = {
16786 /* ADC1-2 */
16787 0x08,
16788};
16789
16790static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16791static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16792
16793
16794/* input MUX */
16795/* FIXME: should be a matrix-type input source selection */
16796static const struct hda_input_mux alc662_capture_source = {
16797 .num_items = 4,
16798 .items = {
16799 { "Mic", 0x0 },
16800 { "Front Mic", 0x1 },
16801 { "Line", 0x2 },
16802 { "CD", 0x4 },
16803 },
16804};
16805
16806static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
16807 .num_items = 2,
16808 .items = {
16809 { "Mic", 0x1 },
16810 { "Line", 0x2 },
16811 },
16812};
16813
16814static const struct hda_input_mux alc663_capture_source = {
16815 .num_items = 3,
16816 .items = {
16817 { "Mic", 0x0 },
16818 { "Front Mic", 0x1 },
16819 { "Line", 0x2 },
16820 },
16821};
16822
16823#if 0 /* set to 1 for testing other input sources below */
16824static const struct hda_input_mux alc272_nc10_capture_source = {
16825 .num_items = 16,
16826 .items = {
16827 { "Autoselect Mic", 0x0 },
16828 { "Internal Mic", 0x1 },
16829 { "In-0x02", 0x2 },
16830 { "In-0x03", 0x3 },
16831 { "In-0x04", 0x4 },
16832 { "In-0x05", 0x5 },
16833 { "In-0x06", 0x6 },
16834 { "In-0x07", 0x7 },
16835 { "In-0x08", 0x8 },
16836 { "In-0x09", 0x9 },
16837 { "In-0x0a", 0x0a },
16838 { "In-0x0b", 0x0b },
16839 { "In-0x0c", 0x0c },
16840 { "In-0x0d", 0x0d },
16841 { "In-0x0e", 0x0e },
16842 { "In-0x0f", 0x0f },
16843 },
16844};
16845#endif
16846
16847/*
16848 * 2ch mode
16849 */
16850static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16851 { 2, NULL }
16852};
16853
16854/*
16855 * 2ch mode
16856 */
16857static const struct hda_verb alc662_3ST_ch2_init[] = {
16858 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16859 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16862 { } /* end */
16863};
16864
16865/*
16866 * 6ch mode
16867 */
16868static const struct hda_verb alc662_3ST_ch6_init[] = {
16869 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16870 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16871 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16872 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16873 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16874 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16875 { } /* end */
16876};
16877
16878static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16879 { 2, alc662_3ST_ch2_init },
16880 { 6, alc662_3ST_ch6_init },
16881};
16882
16883/*
16884 * 2ch mode
16885 */
16886static const struct hda_verb alc662_sixstack_ch6_init[] = {
16887 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16888 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16889 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16890 { } /* end */
16891};
16892
16893/*
16894 * 6ch mode
16895 */
16896static const struct hda_verb alc662_sixstack_ch8_init[] = {
16897 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16898 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16899 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16900 { } /* end */
16901};
16902
16903static const struct hda_channel_mode alc662_5stack_modes[2] = {
16904 { 2, alc662_sixstack_ch6_init },
16905 { 6, alc662_sixstack_ch8_init },
16906};
16907
16908/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16909 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16910 */
16911
16912static const struct snd_kcontrol_new alc662_base_mixer[] = {
16913 /* output mixer control */
16914 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
16915 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16916 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
16917 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16918 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16919 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16920 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16921 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16922 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16923
16924 /*Input mixer control */
16925 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16926 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16927 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16928 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16929 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16930 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16931 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16932 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
16933 { } /* end */
16934};
16935
16936static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16937 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16938 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16939 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16942 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16943 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16945 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16946 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16947 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16948 { } /* end */
16949};
16950
16951static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16952 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16953 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16954 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16955 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16956 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16957 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16958 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16959 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16961 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16962 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16963 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16964 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16966 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16967 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16968 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16969 { } /* end */
16970};
16971
16972static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
16973 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16974 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
16975 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16976 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
16977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16982 { } /* end */
16983};
16984
16985static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
16986 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16987 ALC262_HIPPO_MASTER_SWITCH,
16988
16989 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16992
16993 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16994 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16995 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16996 { } /* end */
16997};
16998
16999static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17000 ALC262_HIPPO_MASTER_SWITCH,
17001 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17002 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17003 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17004 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17005 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17006 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17007 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17010 { } /* end */
17011};
17012
17013static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17014 .ops = &snd_hda_bind_vol,
17015 .values = {
17016 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17017 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17018 0
17019 },
17020};
17021
17022static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17023 .ops = &snd_hda_bind_sw,
17024 .values = {
17025 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17026 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17027 0
17028 },
17029};
17030
17031static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17032 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17033 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17036 { } /* end */
17037};
17038
17039static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17040 .ops = &snd_hda_bind_sw,
17041 .values = {
17042 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17043 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17044 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17045 0
17046 },
17047};
17048
17049static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17050 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17051 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17054 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17055 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17056
17057 { } /* end */
17058};
17059
17060static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17061 .ops = &snd_hda_bind_sw,
17062 .values = {
17063 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17064 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17065 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17066 0
17067 },
17068};
17069
17070static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17071 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17072 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17073 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17074 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17075 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17076 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17077 { } /* end */
17078};
17079
17080static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17081 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17082 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17084 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17086 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17087 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17088 { } /* end */
17089};
17090
17091static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17092 .ops = &snd_hda_bind_vol,
17093 .values = {
17094 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17095 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17096 0
17097 },
17098};
17099
17100static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17101 .ops = &snd_hda_bind_sw,
17102 .values = {
17103 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17104 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17105 0
17106 },
17107};
17108
17109static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17110 HDA_BIND_VOL("Master Playback Volume",
17111 &alc663_asus_two_bind_master_vol),
17112 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17113 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17117 { } /* end */
17118};
17119
17120static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17121 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17122 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17123 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17124 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17125 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17127 { } /* end */
17128};
17129
17130static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17131 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17132 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17133 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17134 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17136
17137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17138 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17139 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17140 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17141 { } /* end */
17142};
17143
17144static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17145 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17146 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17148
17149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17151 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17152 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17153 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17154 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17155 { } /* end */
17156};
17157
17158static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17159 .ops = &snd_hda_bind_sw,
17160 .values = {
17161 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17162 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17163 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17164 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17165 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17166 0
17167 },
17168};
17169
17170static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17171 .ops = &snd_hda_bind_sw,
17172 .values = {
17173 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17174 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17175 0
17176 },
17177};
17178
17179static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17180 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17181 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17182 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17183 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17184 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17185 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17186 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17189 { } /* end */
17190};
17191
17192static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17193 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17194 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17195 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17196 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17197 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17200 { } /* end */
17201};
17202
17203
17204static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17205 {
17206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17207 .name = "Channel Mode",
17208 .info = alc_ch_mode_info,
17209 .get = alc_ch_mode_get,
17210 .put = alc_ch_mode_put,
17211 },
17212 { } /* end */
17213};
17214
17215static const struct hda_verb alc662_init_verbs[] = {
17216 /* ADC: mute amp left and right */
17217 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17218 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17219
17220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17226
17227 /* Front Pin: output 0 (0x0c) */
17228 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17229 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17230
17231 /* Rear Pin: output 1 (0x0d) */
17232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17233 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17234
17235 /* CLFE Pin: output 2 (0x0e) */
17236 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17237 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17238
17239 /* Mic (rear) pin: input vref at 80% */
17240 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17241 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17242 /* Front Mic pin: input vref at 80% */
17243 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17244 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17245 /* Line In pin: input */
17246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17247 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17248 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17249 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17250 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17251 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17252 /* CD pin widget for input */
17253 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17254
17255 /* FIXME: use matrix-type input source selection */
17256 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17257 /* Input mixer */
17258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17259 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17260
17261 { }
17262};
17263
17264static const struct hda_verb alc662_eapd_init_verbs[] = {
17265 /* always trun on EAPD */
17266 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17267 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17268 { }
17269};
17270
17271static const struct hda_verb alc662_sue_init_verbs[] = {
17272 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17273 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17274 {}
17275};
17276
17277static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17278 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17279 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17280 {}
17281};
17282
17283/* Set Unsolicited Event*/
17284static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17286 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17287 {}
17288};
17289
17290static const struct hda_verb alc663_m51va_init_verbs[] = {
17291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17292 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17293 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17294 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17295 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17296 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17298 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17299 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17300 {}
17301};
17302
17303static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
17304 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17305 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17306 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17307 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17308 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17309 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17310 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17311 {}
17312};
17313
17314static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17315 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17316 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17317 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17318 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17321 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17322 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17323 {}
17324};
17325
17326static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
17327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17328 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17329 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17332 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17334 {}
17335};
17336
17337static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17338 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17339 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17340 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17341 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17343 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17344 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17345 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17347 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17348 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17349 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17350 {}
17351};
17352
17353static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17356 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17357 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17359 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17360 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17363 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17364 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17365 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17366 {}
17367};
17368
17369static const struct hda_verb alc663_g71v_init_verbs[] = {
17370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17371 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17372 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17373
17374 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17375 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17376 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17377
17378 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17379 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17380 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17381 {}
17382};
17383
17384static const struct hda_verb alc663_g50v_init_verbs[] = {
17385 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17386 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17387 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17388
17389 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17390 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17391 {}
17392};
17393
17394static const struct hda_verb alc662_ecs_init_verbs[] = {
17395 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17397 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17398 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17399 {}
17400};
17401
17402static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
17403 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17404 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17406 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17407 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17408 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17409 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17410 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17411 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17412 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17413 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17414 {}
17415};
17416
17417static const struct hda_verb alc272_dell_init_verbs[] = {
17418 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17419 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17421 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17422 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17423 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17424 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17425 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17427 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17428 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17429 {}
17430};
17431
17432static const struct hda_verb alc663_mode7_init_verbs[] = {
17433 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17434 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17435 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17436 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17437 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17438 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17439 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17440 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17441 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17442 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17444 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17445 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17446 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17447 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17448 {}
17449};
17450
17451static const struct hda_verb alc663_mode8_init_verbs[] = {
17452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17456 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17457 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17458 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17459 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17460 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17461 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17462 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17467 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17468 {}
17469};
17470
17471static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17472 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17473 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17474 { } /* end */
17475};
17476
17477static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17478 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17479 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17480 { } /* end */
17481};
17482
17483static void alc662_lenovo_101e_setup(struct hda_codec *codec)
17484{
17485 struct alc_spec *spec = codec->spec;
17486
17487 spec->autocfg.hp_pins[0] = 0x1b;
17488 spec->autocfg.line_out_pins[0] = 0x14;
17489 spec->autocfg.speaker_pins[0] = 0x15;
17490 spec->automute = 1;
17491 spec->detect_line = 1;
17492 spec->automute_lines = 1;
17493 spec->automute_mode = ALC_AUTOMUTE_AMP;
17494}
17495
17496static void alc662_eeepc_setup(struct hda_codec *codec)
17497{
17498 struct alc_spec *spec = codec->spec;
17499
17500 alc262_hippo1_setup(codec);
17501 spec->ext_mic_pin = 0x18;
17502 spec->int_mic_pin = 0x19;
17503 spec->auto_mic = 1;
17504}
17505
17506static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
17507{
17508 struct alc_spec *spec = codec->spec;
17509
17510 spec->autocfg.hp_pins[0] = 0x14;
17511 spec->autocfg.speaker_pins[0] = 0x1b;
17512 spec->automute = 1;
17513 spec->automute_mode = ALC_AUTOMUTE_AMP;
17514}
17515
17516static void alc663_m51va_setup(struct hda_codec *codec)
17517{
17518 struct alc_spec *spec = codec->spec;
17519 spec->autocfg.hp_pins[0] = 0x21;
17520 spec->autocfg.speaker_pins[0] = 0x14;
17521 spec->automute_mixer_nid[0] = 0x0c;
17522 spec->automute = 1;
17523 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17524 spec->ext_mic_pin = 0x18;
17525 spec->int_mic_pin = 0x12;
17526 spec->auto_mic = 1;
17527}
17528
17529/* ***************** Mode1 ******************************/
17530static void alc663_mode1_setup(struct hda_codec *codec)
17531{
17532 struct alc_spec *spec = codec->spec;
17533 spec->autocfg.hp_pins[0] = 0x21;
17534 spec->autocfg.speaker_pins[0] = 0x14;
17535 spec->automute_mixer_nid[0] = 0x0c;
17536 spec->automute = 1;
17537 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17538 spec->ext_mic_pin = 0x18;
17539 spec->int_mic_pin = 0x19;
17540 spec->auto_mic = 1;
17541}
17542
17543/* ***************** Mode2 ******************************/
17544static void alc662_mode2_setup(struct hda_codec *codec)
17545{
17546 struct alc_spec *spec = codec->spec;
17547 spec->autocfg.hp_pins[0] = 0x1b;
17548 spec->autocfg.speaker_pins[0] = 0x14;
17549 spec->automute = 1;
17550 spec->automute_mode = ALC_AUTOMUTE_PIN;
17551 spec->ext_mic_pin = 0x18;
17552 spec->int_mic_pin = 0x19;
17553 spec->auto_mic = 1;
17554}
17555
17556/* ***************** Mode3 ******************************/
17557static void alc663_mode3_setup(struct hda_codec *codec)
17558{
17559 struct alc_spec *spec = codec->spec;
17560 spec->autocfg.hp_pins[0] = 0x21;
17561 spec->autocfg.hp_pins[0] = 0x15;
17562 spec->autocfg.speaker_pins[0] = 0x14;
17563 spec->automute = 1;
17564 spec->automute_mode = ALC_AUTOMUTE_PIN;
17565 spec->ext_mic_pin = 0x18;
17566 spec->int_mic_pin = 0x19;
17567 spec->auto_mic = 1;
17568}
17569
17570/* ***************** Mode4 ******************************/
17571static void alc663_mode4_setup(struct hda_codec *codec)
17572{
17573 struct alc_spec *spec = codec->spec;
17574 spec->autocfg.hp_pins[0] = 0x21;
17575 spec->autocfg.speaker_pins[0] = 0x14;
17576 spec->autocfg.speaker_pins[1] = 0x16;
17577 spec->automute_mixer_nid[0] = 0x0c;
17578 spec->automute_mixer_nid[1] = 0x0e;
17579 spec->automute = 1;
17580 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17581 spec->ext_mic_pin = 0x18;
17582 spec->int_mic_pin = 0x19;
17583 spec->auto_mic = 1;
17584}
17585
17586/* ***************** Mode5 ******************************/
17587static void alc663_mode5_setup(struct hda_codec *codec)
17588{
17589 struct alc_spec *spec = codec->spec;
17590 spec->autocfg.hp_pins[0] = 0x15;
17591 spec->autocfg.speaker_pins[0] = 0x14;
17592 spec->autocfg.speaker_pins[1] = 0x16;
17593 spec->automute_mixer_nid[0] = 0x0c;
17594 spec->automute_mixer_nid[1] = 0x0e;
17595 spec->automute = 1;
17596 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17597 spec->ext_mic_pin = 0x18;
17598 spec->int_mic_pin = 0x19;
17599 spec->auto_mic = 1;
17600}
17601
17602/* ***************** Mode6 ******************************/
17603static void alc663_mode6_setup(struct hda_codec *codec)
17604{
17605 struct alc_spec *spec = codec->spec;
17606 spec->autocfg.hp_pins[0] = 0x1b;
17607 spec->autocfg.hp_pins[0] = 0x15;
17608 spec->autocfg.speaker_pins[0] = 0x14;
17609 spec->automute_mixer_nid[0] = 0x0c;
17610 spec->automute = 1;
17611 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17612 spec->ext_mic_pin = 0x18;
17613 spec->int_mic_pin = 0x19;
17614 spec->auto_mic = 1;
17615}
17616
17617/* ***************** Mode7 ******************************/
17618static void alc663_mode7_setup(struct hda_codec *codec)
17619{
17620 struct alc_spec *spec = codec->spec;
17621 spec->autocfg.hp_pins[0] = 0x1b;
17622 spec->autocfg.hp_pins[0] = 0x21;
17623 spec->autocfg.speaker_pins[0] = 0x14;
17624 spec->autocfg.speaker_pins[0] = 0x17;
17625 spec->automute = 1;
17626 spec->automute_mode = ALC_AUTOMUTE_PIN;
17627 spec->ext_mic_pin = 0x18;
17628 spec->int_mic_pin = 0x19;
17629 spec->auto_mic = 1;
17630}
17631
17632/* ***************** Mode8 ******************************/
17633static void alc663_mode8_setup(struct hda_codec *codec)
17634{
17635 struct alc_spec *spec = codec->spec;
17636 spec->autocfg.hp_pins[0] = 0x21;
17637 spec->autocfg.hp_pins[1] = 0x15;
17638 spec->autocfg.speaker_pins[0] = 0x14;
17639 spec->autocfg.speaker_pins[0] = 0x17;
17640 spec->automute = 1;
17641 spec->automute_mode = ALC_AUTOMUTE_PIN;
17642 spec->ext_mic_pin = 0x18;
17643 spec->int_mic_pin = 0x12;
17644 spec->auto_mic = 1;
17645}
17646
17647static void alc663_g71v_setup(struct hda_codec *codec)
17648{
17649 struct alc_spec *spec = codec->spec;
17650 spec->autocfg.hp_pins[0] = 0x21;
17651 spec->autocfg.line_out_pins[0] = 0x15;
17652 spec->autocfg.speaker_pins[0] = 0x14;
17653 spec->automute = 1;
17654 spec->automute_mode = ALC_AUTOMUTE_AMP;
17655 spec->detect_line = 1;
17656 spec->automute_lines = 1;
17657 spec->ext_mic_pin = 0x18;
17658 spec->int_mic_pin = 0x12;
17659 spec->auto_mic = 1;
17660}
17661
17662#define alc663_g50v_setup alc663_m51va_setup
17663
17664static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
17665 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17666 ALC262_HIPPO_MASTER_SWITCH,
17667
17668 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
17669 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17670 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17671
17672 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17673 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17674 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17675 { } /* end */
17676};
17677
17678static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
17679 /* Master Playback automatically created from Speaker and Headphone */
17680 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17681 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17682 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17684
17685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17687 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17688
17689 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17690 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17691 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17692 { } /* end */
17693};
17694
17695#ifdef CONFIG_SND_HDA_POWER_SAVE 6028#ifdef CONFIG_SND_HDA_POWER_SAVE
17696#define alc662_loopbacks alc880_loopbacks 6029#define alc662_loopbacks alc880_loopbacks
17697#endif 6030#endif
17698 6031
17699
17700/*
17701 * configuration and preset
17702 */
17703static const char * const alc662_models[ALC662_MODEL_LAST] = {
17704 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17705 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17706 [ALC662_3ST_6ch] = "3stack-6ch",
17707 [ALC662_5ST_DIG] = "5stack-dig",
17708 [ALC662_LENOVO_101E] = "lenovo-101e",
17709 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
17710 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
17711 [ALC662_ECS] = "ecs",
17712 [ALC663_ASUS_M51VA] = "m51va",
17713 [ALC663_ASUS_G71V] = "g71v",
17714 [ALC663_ASUS_H13] = "h13",
17715 [ALC663_ASUS_G50V] = "g50v",
17716 [ALC663_ASUS_MODE1] = "asus-mode1",
17717 [ALC662_ASUS_MODE2] = "asus-mode2",
17718 [ALC663_ASUS_MODE3] = "asus-mode3",
17719 [ALC663_ASUS_MODE4] = "asus-mode4",
17720 [ALC663_ASUS_MODE5] = "asus-mode5",
17721 [ALC663_ASUS_MODE6] = "asus-mode6",
17722 [ALC663_ASUS_MODE7] = "asus-mode7",
17723 [ALC663_ASUS_MODE8] = "asus-mode8",
17724 [ALC272_DELL] = "dell",
17725 [ALC272_DELL_ZM1] = "dell-zm1",
17726 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
17727 [ALC662_AUTO] = "auto",
17728};
17729
17730static const struct snd_pci_quirk alc662_cfg_tbl[] = {
17731 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
17732 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17733 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17734 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17735 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17736 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17737 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17738 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17739 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
17740 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
17741 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17742 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
17743 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
17744 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17745 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17746 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17747 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17748 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
17749 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
17750 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17751 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
17752 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17753 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17754 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17755 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
17756 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
17757 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17758 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17759 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
17760 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
17761 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17762 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17763 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
17764 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
17765 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
17766 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17767 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17768 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
17769 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17770 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17771 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17772 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17773 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17774 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17775 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17776 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17777 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
17778 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
17779 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17780 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
17781 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
17782 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17783 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17784 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17785 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17786 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
17787 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
17788 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
17789 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
17790 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17791 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17792 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17793 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
17794 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17795 ALC662_3ST_6ch_DIG),
17796 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
17797 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17798 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17799 ALC662_3ST_6ch_DIG),
17800 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17801 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17802 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17803 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
17804 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
17805 ALC662_3ST_6ch_DIG),
17806 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17807 ALC663_ASUS_H13),
17808 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
17809 {}
17810};
17811
17812static const struct alc_config_preset alc662_presets[] = {
17813 [ALC662_3ST_2ch_DIG] = {
17814 .mixers = { alc662_3ST_2ch_mixer },
17815 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17816 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17817 .dac_nids = alc662_dac_nids,
17818 .dig_out_nid = ALC662_DIGOUT_NID,
17819 .dig_in_nid = ALC662_DIGIN_NID,
17820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17821 .channel_mode = alc662_3ST_2ch_modes,
17822 .input_mux = &alc662_capture_source,
17823 },
17824 [ALC662_3ST_6ch_DIG] = {
17825 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17826 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17827 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17828 .dac_nids = alc662_dac_nids,
17829 .dig_out_nid = ALC662_DIGOUT_NID,
17830 .dig_in_nid = ALC662_DIGIN_NID,
17831 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17832 .channel_mode = alc662_3ST_6ch_modes,
17833 .need_dac_fix = 1,
17834 .input_mux = &alc662_capture_source,
17835 },
17836 [ALC662_3ST_6ch] = {
17837 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17838 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17839 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17840 .dac_nids = alc662_dac_nids,
17841 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17842 .channel_mode = alc662_3ST_6ch_modes,
17843 .need_dac_fix = 1,
17844 .input_mux = &alc662_capture_source,
17845 },
17846 [ALC662_5ST_DIG] = {
17847 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
17848 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17849 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17850 .dac_nids = alc662_dac_nids,
17851 .dig_out_nid = ALC662_DIGOUT_NID,
17852 .dig_in_nid = ALC662_DIGIN_NID,
17853 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17854 .channel_mode = alc662_5stack_modes,
17855 .input_mux = &alc662_capture_source,
17856 },
17857 [ALC662_LENOVO_101E] = {
17858 .mixers = { alc662_lenovo_101e_mixer },
17859 .init_verbs = { alc662_init_verbs,
17860 alc662_eapd_init_verbs,
17861 alc662_sue_init_verbs },
17862 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17863 .dac_nids = alc662_dac_nids,
17864 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17865 .channel_mode = alc662_3ST_2ch_modes,
17866 .input_mux = &alc662_lenovo_101e_capture_source,
17867 .unsol_event = alc_sku_unsol_event,
17868 .setup = alc662_lenovo_101e_setup,
17869 .init_hook = alc_inithook,
17870 },
17871 [ALC662_ASUS_EEEPC_P701] = {
17872 .mixers = { alc662_eeepc_p701_mixer },
17873 .init_verbs = { alc662_init_verbs,
17874 alc662_eapd_init_verbs,
17875 alc662_eeepc_sue_init_verbs },
17876 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17877 .dac_nids = alc662_dac_nids,
17878 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17879 .channel_mode = alc662_3ST_2ch_modes,
17880 .unsol_event = alc_sku_unsol_event,
17881 .setup = alc662_eeepc_setup,
17882 .init_hook = alc_inithook,
17883 },
17884 [ALC662_ASUS_EEEPC_EP20] = {
17885 .mixers = { alc662_eeepc_ep20_mixer,
17886 alc662_chmode_mixer },
17887 .init_verbs = { alc662_init_verbs,
17888 alc662_eapd_init_verbs,
17889 alc662_eeepc_ep20_sue_init_verbs },
17890 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17891 .dac_nids = alc662_dac_nids,
17892 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17893 .channel_mode = alc662_3ST_6ch_modes,
17894 .input_mux = &alc662_lenovo_101e_capture_source,
17895 .unsol_event = alc_sku_unsol_event,
17896 .setup = alc662_eeepc_ep20_setup,
17897 .init_hook = alc_inithook,
17898 },
17899 [ALC662_ECS] = {
17900 .mixers = { alc662_ecs_mixer },
17901 .init_verbs = { alc662_init_verbs,
17902 alc662_eapd_init_verbs,
17903 alc662_ecs_init_verbs },
17904 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17905 .dac_nids = alc662_dac_nids,
17906 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17907 .channel_mode = alc662_3ST_2ch_modes,
17908 .unsol_event = alc_sku_unsol_event,
17909 .setup = alc662_eeepc_setup,
17910 .init_hook = alc_inithook,
17911 },
17912 [ALC663_ASUS_M51VA] = {
17913 .mixers = { alc663_m51va_mixer },
17914 .init_verbs = { alc662_init_verbs,
17915 alc662_eapd_init_verbs,
17916 alc663_m51va_init_verbs },
17917 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17918 .dac_nids = alc662_dac_nids,
17919 .dig_out_nid = ALC662_DIGOUT_NID,
17920 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17921 .channel_mode = alc662_3ST_2ch_modes,
17922 .unsol_event = alc_sku_unsol_event,
17923 .setup = alc663_m51va_setup,
17924 .init_hook = alc_inithook,
17925 },
17926 [ALC663_ASUS_G71V] = {
17927 .mixers = { alc663_g71v_mixer },
17928 .init_verbs = { alc662_init_verbs,
17929 alc662_eapd_init_verbs,
17930 alc663_g71v_init_verbs },
17931 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17932 .dac_nids = alc662_dac_nids,
17933 .dig_out_nid = ALC662_DIGOUT_NID,
17934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17935 .channel_mode = alc662_3ST_2ch_modes,
17936 .unsol_event = alc_sku_unsol_event,
17937 .setup = alc663_g71v_setup,
17938 .init_hook = alc_inithook,
17939 },
17940 [ALC663_ASUS_H13] = {
17941 .mixers = { alc663_m51va_mixer },
17942 .init_verbs = { alc662_init_verbs,
17943 alc662_eapd_init_verbs,
17944 alc663_m51va_init_verbs },
17945 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17946 .dac_nids = alc662_dac_nids,
17947 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17948 .channel_mode = alc662_3ST_2ch_modes,
17949 .setup = alc663_m51va_setup,
17950 .unsol_event = alc_sku_unsol_event,
17951 .init_hook = alc_inithook,
17952 },
17953 [ALC663_ASUS_G50V] = {
17954 .mixers = { alc663_g50v_mixer },
17955 .init_verbs = { alc662_init_verbs,
17956 alc662_eapd_init_verbs,
17957 alc663_g50v_init_verbs },
17958 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17959 .dac_nids = alc662_dac_nids,
17960 .dig_out_nid = ALC662_DIGOUT_NID,
17961 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17962 .channel_mode = alc662_3ST_6ch_modes,
17963 .input_mux = &alc663_capture_source,
17964 .unsol_event = alc_sku_unsol_event,
17965 .setup = alc663_g50v_setup,
17966 .init_hook = alc_inithook,
17967 },
17968 [ALC663_ASUS_MODE1] = {
17969 .mixers = { alc663_m51va_mixer },
17970 .cap_mixer = alc662_auto_capture_mixer,
17971 .init_verbs = { alc662_init_verbs,
17972 alc662_eapd_init_verbs,
17973 alc663_21jd_amic_init_verbs },
17974 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17975 .hp_nid = 0x03,
17976 .dac_nids = alc662_dac_nids,
17977 .dig_out_nid = ALC662_DIGOUT_NID,
17978 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17979 .channel_mode = alc662_3ST_2ch_modes,
17980 .unsol_event = alc_sku_unsol_event,
17981 .setup = alc663_mode1_setup,
17982 .init_hook = alc_inithook,
17983 },
17984 [ALC662_ASUS_MODE2] = {
17985 .mixers = { alc662_1bjd_mixer },
17986 .cap_mixer = alc662_auto_capture_mixer,
17987 .init_verbs = { alc662_init_verbs,
17988 alc662_eapd_init_verbs,
17989 alc662_1bjd_amic_init_verbs },
17990 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17991 .dac_nids = alc662_dac_nids,
17992 .dig_out_nid = ALC662_DIGOUT_NID,
17993 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17994 .channel_mode = alc662_3ST_2ch_modes,
17995 .unsol_event = alc_sku_unsol_event,
17996 .setup = alc662_mode2_setup,
17997 .init_hook = alc_inithook,
17998 },
17999 [ALC663_ASUS_MODE3] = {
18000 .mixers = { alc663_two_hp_m1_mixer },
18001 .cap_mixer = alc662_auto_capture_mixer,
18002 .init_verbs = { alc662_init_verbs,
18003 alc662_eapd_init_verbs,
18004 alc663_two_hp_amic_m1_init_verbs },
18005 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18006 .hp_nid = 0x03,
18007 .dac_nids = alc662_dac_nids,
18008 .dig_out_nid = ALC662_DIGOUT_NID,
18009 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18010 .channel_mode = alc662_3ST_2ch_modes,
18011 .unsol_event = alc_sku_unsol_event,
18012 .setup = alc663_mode3_setup,
18013 .init_hook = alc_inithook,
18014 },
18015 [ALC663_ASUS_MODE4] = {
18016 .mixers = { alc663_asus_21jd_clfe_mixer },
18017 .cap_mixer = alc662_auto_capture_mixer,
18018 .init_verbs = { alc662_init_verbs,
18019 alc662_eapd_init_verbs,
18020 alc663_21jd_amic_init_verbs},
18021 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18022 .hp_nid = 0x03,
18023 .dac_nids = alc662_dac_nids,
18024 .dig_out_nid = ALC662_DIGOUT_NID,
18025 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18026 .channel_mode = alc662_3ST_2ch_modes,
18027 .unsol_event = alc_sku_unsol_event,
18028 .setup = alc663_mode4_setup,
18029 .init_hook = alc_inithook,
18030 },
18031 [ALC663_ASUS_MODE5] = {
18032 .mixers = { alc663_asus_15jd_clfe_mixer },
18033 .cap_mixer = alc662_auto_capture_mixer,
18034 .init_verbs = { alc662_init_verbs,
18035 alc662_eapd_init_verbs,
18036 alc663_15jd_amic_init_verbs },
18037 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18038 .hp_nid = 0x03,
18039 .dac_nids = alc662_dac_nids,
18040 .dig_out_nid = ALC662_DIGOUT_NID,
18041 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18042 .channel_mode = alc662_3ST_2ch_modes,
18043 .unsol_event = alc_sku_unsol_event,
18044 .setup = alc663_mode5_setup,
18045 .init_hook = alc_inithook,
18046 },
18047 [ALC663_ASUS_MODE6] = {
18048 .mixers = { alc663_two_hp_m2_mixer },
18049 .cap_mixer = alc662_auto_capture_mixer,
18050 .init_verbs = { alc662_init_verbs,
18051 alc662_eapd_init_verbs,
18052 alc663_two_hp_amic_m2_init_verbs },
18053 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18054 .hp_nid = 0x03,
18055 .dac_nids = alc662_dac_nids,
18056 .dig_out_nid = ALC662_DIGOUT_NID,
18057 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18058 .channel_mode = alc662_3ST_2ch_modes,
18059 .unsol_event = alc_sku_unsol_event,
18060 .setup = alc663_mode6_setup,
18061 .init_hook = alc_inithook,
18062 },
18063 [ALC663_ASUS_MODE7] = {
18064 .mixers = { alc663_mode7_mixer },
18065 .cap_mixer = alc662_auto_capture_mixer,
18066 .init_verbs = { alc662_init_verbs,
18067 alc662_eapd_init_verbs,
18068 alc663_mode7_init_verbs },
18069 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18070 .hp_nid = 0x03,
18071 .dac_nids = alc662_dac_nids,
18072 .dig_out_nid = ALC662_DIGOUT_NID,
18073 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18074 .channel_mode = alc662_3ST_2ch_modes,
18075 .unsol_event = alc_sku_unsol_event,
18076 .setup = alc663_mode7_setup,
18077 .init_hook = alc_inithook,
18078 },
18079 [ALC663_ASUS_MODE8] = {
18080 .mixers = { alc663_mode8_mixer },
18081 .cap_mixer = alc662_auto_capture_mixer,
18082 .init_verbs = { alc662_init_verbs,
18083 alc662_eapd_init_verbs,
18084 alc663_mode8_init_verbs },
18085 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18086 .hp_nid = 0x03,
18087 .dac_nids = alc662_dac_nids,
18088 .dig_out_nid = ALC662_DIGOUT_NID,
18089 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18090 .channel_mode = alc662_3ST_2ch_modes,
18091 .unsol_event = alc_sku_unsol_event,
18092 .setup = alc663_mode8_setup,
18093 .init_hook = alc_inithook,
18094 },
18095 [ALC272_DELL] = {
18096 .mixers = { alc663_m51va_mixer },
18097 .cap_mixer = alc272_auto_capture_mixer,
18098 .init_verbs = { alc662_init_verbs,
18099 alc662_eapd_init_verbs,
18100 alc272_dell_init_verbs },
18101 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18102 .dac_nids = alc272_dac_nids,
18103 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18104 .adc_nids = alc272_adc_nids,
18105 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18106 .capsrc_nids = alc272_capsrc_nids,
18107 .channel_mode = alc662_3ST_2ch_modes,
18108 .unsol_event = alc_sku_unsol_event,
18109 .setup = alc663_m51va_setup,
18110 .init_hook = alc_inithook,
18111 },
18112 [ALC272_DELL_ZM1] = {
18113 .mixers = { alc663_m51va_mixer },
18114 .cap_mixer = alc662_auto_capture_mixer,
18115 .init_verbs = { alc662_init_verbs,
18116 alc662_eapd_init_verbs,
18117 alc272_dell_zm1_init_verbs },
18118 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18119 .dac_nids = alc272_dac_nids,
18120 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18121 .adc_nids = alc662_adc_nids,
18122 .num_adc_nids = 1,
18123 .capsrc_nids = alc662_capsrc_nids,
18124 .channel_mode = alc662_3ST_2ch_modes,
18125 .unsol_event = alc_sku_unsol_event,
18126 .setup = alc663_m51va_setup,
18127 .init_hook = alc_inithook,
18128 },
18129 [ALC272_SAMSUNG_NC10] = {
18130 .mixers = { alc272_nc10_mixer },
18131 .init_verbs = { alc662_init_verbs,
18132 alc662_eapd_init_verbs,
18133 alc663_21jd_amic_init_verbs },
18134 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18135 .dac_nids = alc272_dac_nids,
18136 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18137 .channel_mode = alc662_3ST_2ch_modes,
18138 /*.input_mux = &alc272_nc10_capture_source,*/
18139 .unsol_event = alc_sku_unsol_event,
18140 .setup = alc663_mode4_setup,
18141 .init_hook = alc_inithook,
18142 },
18143};
18144
18145
18146/* 6032/*
18147 * BIOS auto configuration 6033 * BIOS auto configuration
18148 */ 6034 */
18149 6035
18150/* convert from MIX nid to DAC */
18151static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18152{
18153 hda_nid_t list[5];
18154 int i, num;
18155
18156 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18157 for (i = 0; i < num; i++) {
18158 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18159 return list[i];
18160 }
18161 return 0;
18162}
18163
18164/* go down to the selector widget before the mixer */
18165static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18166{
18167 hda_nid_t srcs[5];
18168 int num = snd_hda_get_connections(codec, pin, srcs,
18169 ARRAY_SIZE(srcs));
18170 if (num != 1 ||
18171 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18172 return pin;
18173 return srcs[0];
18174}
18175
18176/* get MIX nid connected to the given pin targeted to DAC */
18177static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18178 hda_nid_t dac)
18179{
18180 hda_nid_t mix[5];
18181 int i, num;
18182
18183 pin = alc_go_down_to_selector(codec, pin);
18184 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18185 for (i = 0; i < num; i++) {
18186 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18187 return mix[i];
18188 }
18189 return 0;
18190}
18191
18192/* select the connection from pin to DAC if needed */
18193static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18194 hda_nid_t dac)
18195{
18196 hda_nid_t mix[5];
18197 int i, num;
18198
18199 pin = alc_go_down_to_selector(codec, pin);
18200 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18201 if (num < 2)
18202 return 0;
18203 for (i = 0; i < num; i++) {
18204 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18205 snd_hda_codec_update_cache(codec, pin, 0,
18206 AC_VERB_SET_CONNECT_SEL, i);
18207 return 0;
18208 }
18209 }
18210 return 0;
18211}
18212
18213/* look for an empty DAC slot */
18214static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18215{
18216 struct alc_spec *spec = codec->spec;
18217 hda_nid_t srcs[5];
18218 int i, num;
18219
18220 pin = alc_go_down_to_selector(codec, pin);
18221 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18222 for (i = 0; i < num; i++) {
18223 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18224 if (!nid)
18225 continue;
18226 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18227 spec->multiout.num_dacs))
18228 continue;
18229 if (spec->multiout.hp_nid == nid)
18230 continue;
18231 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18232 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18233 continue;
18234 return nid;
18235 }
18236 return 0;
18237}
18238
18239static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18240{
18241 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18242 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18243 return alc_auto_look_for_dac(codec, pin);
18244 return 0;
18245}
18246
18247/* fill in the dac_nids table from the parsed pin configuration */
18248static int alc_auto_fill_dac_nids(struct hda_codec *codec)
18249{
18250 struct alc_spec *spec = codec->spec;
18251 const struct auto_pin_cfg *cfg = &spec->autocfg;
18252 bool redone = false;
18253 int i;
18254
18255 again:
18256 spec->multiout.num_dacs = 0;
18257 spec->multiout.hp_nid = 0;
18258 spec->multiout.extra_out_nid[0] = 0;
18259 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18260 spec->multiout.dac_nids = spec->private_dac_nids;
18261
18262 /* fill hard-wired DACs first */
18263 if (!redone) {
18264 for (i = 0; i < cfg->line_outs; i++)
18265 spec->private_dac_nids[i] =
18266 get_dac_if_single(codec, cfg->line_out_pins[i]);
18267 if (cfg->hp_outs)
18268 spec->multiout.hp_nid =
18269 get_dac_if_single(codec, cfg->hp_pins[0]);
18270 if (cfg->speaker_outs)
18271 spec->multiout.extra_out_nid[0] =
18272 get_dac_if_single(codec, cfg->speaker_pins[0]);
18273 }
18274
18275 for (i = 0; i < cfg->line_outs; i++) {
18276 hda_nid_t pin = cfg->line_out_pins[i];
18277 if (spec->private_dac_nids[i])
18278 continue;
18279 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18280 if (!spec->private_dac_nids[i] && !redone) {
18281 /* if we can't find primary DACs, re-probe without
18282 * checking the hard-wired DACs
18283 */
18284 redone = true;
18285 goto again;
18286 }
18287 }
18288
18289 for (i = 0; i < cfg->line_outs; i++) {
18290 if (spec->private_dac_nids[i])
18291 spec->multiout.num_dacs++;
18292 else
18293 memmove(spec->private_dac_nids + i,
18294 spec->private_dac_nids + i + 1,
18295 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
18296 }
18297
18298 if (cfg->hp_outs && !spec->multiout.hp_nid)
18299 spec->multiout.hp_nid =
18300 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
18301 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
18302 spec->multiout.extra_out_nid[0] =
18303 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
18304
18305 return 0;
18306}
18307
18308static int alc_auto_add_vol_ctl(struct hda_codec *codec,
18309 const char *pfx, int cidx,
18310 hda_nid_t nid, unsigned int chs)
18311{
18312 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
18313 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18314}
18315
18316#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
18317 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
18318
18319/* create a mute-switch for the given mixer widget;
18320 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
18321 */
18322static int alc_auto_add_sw_ctl(struct hda_codec *codec,
18323 const char *pfx, int cidx,
18324 hda_nid_t nid, unsigned int chs)
18325{
18326 int type;
18327 unsigned long val;
18328 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
18329 type = ALC_CTL_WIDGET_MUTE;
18330 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
18331 } else {
18332 type = ALC_CTL_BIND_MUTE;
18333 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
18334 }
18335 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
18336}
18337
18338#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
18339 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
18340
18341/* add playback controls from the parsed DAC table */
18342static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
18343 const struct auto_pin_cfg *cfg)
18344{
18345 struct alc_spec *spec = codec->spec;
18346 hda_nid_t nid, mix, pin;
18347 int i, err, noutputs;
18348
18349 noutputs = cfg->line_outs;
18350 if (spec->multi_ios > 0)
18351 noutputs += spec->multi_ios;
18352
18353 for (i = 0; i < noutputs; i++) {
18354 const char *name;
18355 int index;
18356 nid = spec->multiout.dac_nids[i];
18357 if (!nid)
18358 continue;
18359 if (i >= cfg->line_outs)
18360 pin = spec->multi_io[i - 1].pin;
18361 else
18362 pin = cfg->line_out_pins[i];
18363 mix = alc_auto_dac_to_mix(codec, pin, nid);
18364 if (!mix)
18365 continue;
18366 name = alc_get_line_out_pfx(spec, i, true, &index);
18367 if (!name) {
18368 /* Center/LFE */
18369 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1);
18370 if (err < 0)
18371 return err;
18372 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2);
18373 if (err < 0)
18374 return err;
18375 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1);
18376 if (err < 0)
18377 return err;
18378 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2);
18379 if (err < 0)
18380 return err;
18381 } else {
18382 err = alc_auto_add_stereo_vol(codec, name, index, nid);
18383 if (err < 0)
18384 return err;
18385 err = alc_auto_add_stereo_sw(codec, name, index, mix);
18386 if (err < 0)
18387 return err;
18388 }
18389 }
18390 return 0;
18391}
18392
18393/* add playback controls for speaker and HP outputs */
18394static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18395 hda_nid_t dac, const char *pfx)
18396{
18397 struct alc_spec *spec = codec->spec;
18398 hda_nid_t mix;
18399 int err;
18400
18401 if (!pin)
18402 return 0;
18403 if (!dac) {
18404 /* the corresponding DAC is already occupied */
18405 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18406 return 0; /* no way */
18407 /* create a switch only */
18408 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18409 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18410 }
18411
18412 mix = alc_auto_dac_to_mix(codec, pin, dac);
18413 if (!mix)
18414 return 0;
18415 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
18416 if (err < 0)
18417 return err;
18418 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix);
18419 if (err < 0)
18420 return err;
18421 return 0;
18422}
18423
18424static int alc_auto_create_hp_out(struct hda_codec *codec)
18425{
18426 struct alc_spec *spec = codec->spec;
18427 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18428 spec->multiout.hp_nid,
18429 "Headphone");
18430}
18431
18432static int alc_auto_create_speaker_out(struct hda_codec *codec)
18433{
18434 struct alc_spec *spec = codec->spec;
18435 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
18436 spec->multiout.extra_out_nid[0],
18437 "Speaker");
18438}
18439
18440static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
18441 hda_nid_t nid, int pin_type,
18442 hda_nid_t dac)
18443{
18444 int i, num;
18445 hda_nid_t mix = 0;
18446 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18447
18448 alc_set_pin_output(codec, nid, pin_type);
18449 nid = alc_go_down_to_selector(codec, nid);
18450 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18451 for (i = 0; i < num; i++) {
18452 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
18453 continue;
18454 mix = srcs[i];
18455 break;
18456 }
18457 if (!mix)
18458 return;
18459
18460 /* need the manual connection? */
18461 if (num > 1)
18462 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18463 /* unmute mixer widget inputs */
18464 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18465 AMP_IN_UNMUTE(0));
18466 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18467 AMP_IN_UNMUTE(1));
18468 /* initialize volume */
18469 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18470 nid = dac;
18471 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18472 nid = mix;
18473 else
18474 return;
18475 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18476 AMP_OUT_ZERO);
18477}
18478
18479static void alc_auto_init_multi_out(struct hda_codec *codec)
18480{
18481 struct alc_spec *spec = codec->spec;
18482 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18483 int i;
18484
18485 for (i = 0; i <= HDA_SIDE; i++) {
18486 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18487 if (nid)
18488 alc_auto_set_output_and_unmute(codec, nid, pin_type,
18489 spec->multiout.dac_nids[i]);
18490 }
18491}
18492
18493static void alc_auto_init_extra_out(struct hda_codec *codec)
18494{
18495 struct alc_spec *spec = codec->spec;
18496 hda_nid_t pin;
18497
18498 pin = spec->autocfg.hp_pins[0];
18499 if (pin)
18500 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
18501 spec->multiout.hp_nid);
18502 pin = spec->autocfg.speaker_pins[0];
18503 if (pin)
18504 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18505 spec->multiout.extra_out_nid[0]);
18506}
18507
18508/*
18509 * multi-io helper
18510 */
18511static int alc_auto_fill_multi_ios(struct hda_codec *codec,
18512 unsigned int location)
18513{
18514 struct alc_spec *spec = codec->spec;
18515 struct auto_pin_cfg *cfg = &spec->autocfg;
18516 int type, i, num_pins = 0;
18517
18518 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
18519 for (i = 0; i < cfg->num_inputs; i++) {
18520 hda_nid_t nid = cfg->inputs[i].pin;
18521 hda_nid_t dac;
18522 unsigned int defcfg, caps;
18523 if (cfg->inputs[i].type != type)
18524 continue;
18525 defcfg = snd_hda_codec_get_pincfg(codec, nid);
18526 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
18527 continue;
18528 if (location && get_defcfg_location(defcfg) != location)
18529 continue;
18530 caps = snd_hda_query_pin_caps(codec, nid);
18531 if (!(caps & AC_PINCAP_OUT))
18532 continue;
18533 dac = alc_auto_look_for_dac(codec, nid);
18534 if (!dac)
18535 continue;
18536 spec->multi_io[num_pins].pin = nid;
18537 spec->multi_io[num_pins].dac = dac;
18538 num_pins++;
18539 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18540 }
18541 }
18542 spec->multiout.num_dacs = 1;
18543 if (num_pins < 2)
18544 return 0;
18545 return num_pins;
18546}
18547
18548static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
18549 struct snd_ctl_elem_info *uinfo)
18550{
18551 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18552 struct alc_spec *spec = codec->spec;
18553
18554 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
18555 uinfo->count = 1;
18556 uinfo->value.enumerated.items = spec->multi_ios + 1;
18557 if (uinfo->value.enumerated.item > spec->multi_ios)
18558 uinfo->value.enumerated.item = spec->multi_ios;
18559 sprintf(uinfo->value.enumerated.name, "%dch",
18560 (uinfo->value.enumerated.item + 1) * 2);
18561 return 0;
18562}
18563
18564static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
18565 struct snd_ctl_elem_value *ucontrol)
18566{
18567 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18568 struct alc_spec *spec = codec->spec;
18569 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
18570 return 0;
18571}
18572
18573static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
18574{
18575 struct alc_spec *spec = codec->spec;
18576 hda_nid_t nid = spec->multi_io[idx].pin;
18577
18578 if (!spec->multi_io[idx].ctl_in)
18579 spec->multi_io[idx].ctl_in =
18580 snd_hda_codec_read(codec, nid, 0,
18581 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
18582 if (output) {
18583 snd_hda_codec_update_cache(codec, nid, 0,
18584 AC_VERB_SET_PIN_WIDGET_CONTROL,
18585 PIN_OUT);
18586 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18587 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18588 HDA_AMP_MUTE, 0);
18589 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
18590 } else {
18591 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18592 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18593 HDA_AMP_MUTE, HDA_AMP_MUTE);
18594 snd_hda_codec_update_cache(codec, nid, 0,
18595 AC_VERB_SET_PIN_WIDGET_CONTROL,
18596 spec->multi_io[idx].ctl_in);
18597 }
18598 return 0;
18599}
18600
18601static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
18602 struct snd_ctl_elem_value *ucontrol)
18603{
18604 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18605 struct alc_spec *spec = codec->spec;
18606 int i, ch;
18607
18608 ch = ucontrol->value.enumerated.item[0];
18609 if (ch < 0 || ch > spec->multi_ios)
18610 return -EINVAL;
18611 if (ch == (spec->ext_channel_count - 1) / 2)
18612 return 0;
18613 spec->ext_channel_count = (ch + 1) * 2;
18614 for (i = 0; i < spec->multi_ios; i++)
18615 alc_set_multi_io(codec, i, i < ch);
18616 spec->multiout.max_channels = spec->ext_channel_count;
18617 return 1;
18618}
18619
18620static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
18621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
18622 .name = "Channel Mode",
18623 .info = alc_auto_ch_mode_info,
18624 .get = alc_auto_ch_mode_get,
18625 .put = alc_auto_ch_mode_put,
18626};
18627
18628static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
18629 int (*fill_dac)(struct hda_codec *))
18630{
18631 struct alc_spec *spec = codec->spec;
18632 struct auto_pin_cfg *cfg = &spec->autocfg;
18633 unsigned int location, defcfg;
18634 int num_pins;
18635
18636 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
18637 /* use HP as primary out */
18638 cfg->speaker_outs = cfg->line_outs;
18639 memcpy(cfg->speaker_pins, cfg->line_out_pins,
18640 sizeof(cfg->speaker_pins));
18641 cfg->line_outs = cfg->hp_outs;
18642 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
18643 cfg->hp_outs = 0;
18644 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
18645 cfg->line_out_type = AUTO_PIN_HP_OUT;
18646 if (fill_dac)
18647 fill_dac(codec);
18648 }
18649 if (cfg->line_outs != 1 ||
18650 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18651 return 0;
18652
18653 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
18654 location = get_defcfg_location(defcfg);
18655
18656 num_pins = alc_auto_fill_multi_ios(codec, location);
18657 if (num_pins > 0) {
18658 struct snd_kcontrol_new *knew;
18659
18660 knew = alc_kcontrol_new(spec);
18661 if (!knew)
18662 return -ENOMEM;
18663 *knew = alc_auto_channel_mode_enum;
18664 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
18665 if (!knew->name)
18666 return -ENOMEM;
18667
18668 spec->multi_ios = num_pins;
18669 spec->ext_channel_count = 2;
18670 spec->multiout.num_dacs = num_pins + 1;
18671 }
18672 return 0;
18673}
18674
18675static int alc662_parse_auto_config(struct hda_codec *codec) 6036static int alc662_parse_auto_config(struct hda_codec *codec)
18676{ 6037{
18677 struct alc_spec *spec = codec->spec; 6038 struct alc_spec *spec = codec->spec;
@@ -18816,6 +6177,12 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
18816}; 6177};
18817 6178
18818 6179
6180/*
6181 */
6182#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6183#include "alc662_quirks.c"
6184#endif
6185
18819static int patch_alc662(struct hda_codec *codec) 6186static int patch_alc662(struct hda_codec *codec)
18820{ 6187{
18821 struct alc_spec *spec; 6188 struct alc_spec *spec;
@@ -18844,16 +6211,15 @@ static int patch_alc662(struct hda_codec *codec)
18844 else if (coef == 0x4011) 6211 else if (coef == 0x4011)
18845 alc_codec_rename(codec, "ALC656"); 6212 alc_codec_rename(codec, "ALC656");
18846 6213
18847 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 6214 board_config = alc_board_config(codec, ALC662_MODEL_LAST,
18848 alc662_models, 6215 alc662_models, alc662_cfg_tbl);
18849 alc662_cfg_tbl);
18850 if (board_config < 0) { 6216 if (board_config < 0) {
18851 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 6217 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18852 codec->chip_name); 6218 codec->chip_name);
18853 board_config = ALC662_AUTO; 6219 board_config = ALC_MODEL_AUTO;
18854 } 6220 }
18855 6221
18856 if (board_config == ALC662_AUTO) { 6222 if (board_config == ALC_MODEL_AUTO) {
18857 alc_pick_fixup(codec, alc662_fixup_models, 6223 alc_pick_fixup(codec, alc662_fixup_models,
18858 alc662_fixup_tbl, alc662_fixups); 6224 alc662_fixup_tbl, alc662_fixups);
18859 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 6225 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
@@ -18862,12 +6228,15 @@ static int patch_alc662(struct hda_codec *codec)
18862 if (err < 0) { 6228 if (err < 0) {
18863 alc_free(codec); 6229 alc_free(codec);
18864 return err; 6230 return err;
18865 } else if (!err) { 6231 }
6232#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6233 else if (!err) {
18866 printk(KERN_INFO 6234 printk(KERN_INFO
18867 "hda_codec: Cannot set up configuration " 6235 "hda_codec: Cannot set up configuration "
18868 "from BIOS. Using base mode...\n"); 6236 "from BIOS. Using base mode...\n");
18869 board_config = ALC662_3ST_2ch_DIG; 6237 board_config = ALC662_3ST_2ch_DIG;
18870 } 6238 }
6239#endif
18871 } 6240 }
18872 6241
18873 if (has_cdefine_beep(codec)) { 6242 if (has_cdefine_beep(codec)) {
@@ -18878,7 +6247,7 @@ static int patch_alc662(struct hda_codec *codec)
18878 } 6247 }
18879 } 6248 }
18880 6249
18881 if (board_config != ALC662_AUTO) 6250 if (board_config != ALC_MODEL_AUTO)
18882 setup_preset(codec, &alc662_presets[board_config]); 6251 setup_preset(codec, &alc662_presets[board_config]);
18883 6252
18884 if (!spec->adc_nids) { 6253 if (!spec->adc_nids) {
@@ -18910,7 +6279,7 @@ static int patch_alc662(struct hda_codec *codec)
18910 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 6279 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18911 6280
18912 codec->patch_ops = alc_patch_ops; 6281 codec->patch_ops = alc_patch_ops;
18913 if (board_config == ALC662_AUTO) 6282 if (board_config == ALC_MODEL_AUTO)
18914 spec->init_hook = alc662_auto_init; 6283 spec->init_hook = alc662_auto_init;
18915 spec->shutup = alc_eapd_shutup; 6284 spec->shutup = alc_eapd_shutup;
18916 6285
@@ -18953,187 +6322,6 @@ static int patch_alc899(struct hda_codec *codec)
18953/* 6322/*
18954 * ALC680 support 6323 * ALC680 support
18955 */ 6324 */
18956#define ALC680_DIGIN_NID ALC880_DIGIN_NID
18957#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18958#define alc680_modes alc260_modes
18959
18960static const hda_nid_t alc680_dac_nids[3] = {
18961 /* Lout1, Lout2, hp */
18962 0x02, 0x03, 0x04
18963};
18964
18965static const hda_nid_t alc680_adc_nids[3] = {
18966 /* ADC0-2 */
18967 /* DMIC, MIC, Line-in*/
18968 0x07, 0x08, 0x09
18969};
18970
18971/*
18972 * Analog capture ADC cgange
18973 */
18974static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
18975{
18976 static hda_nid_t pins[] = {0x18, 0x19};
18977 static hda_nid_t adcs[] = {0x08, 0x09};
18978 int i;
18979
18980 for (i = 0; i < ARRAY_SIZE(pins); i++) {
18981 if (!is_jack_detectable(codec, pins[i]))
18982 continue;
18983 if (snd_hda_jack_detect(codec, pins[i]))
18984 return adcs[i];
18985 }
18986 return 0x07;
18987}
18988
18989static void alc680_rec_autoswitch(struct hda_codec *codec)
18990{
18991 struct alc_spec *spec = codec->spec;
18992 hda_nid_t nid = alc680_get_cur_adc(codec);
18993 if (spec->cur_adc && nid != spec->cur_adc) {
18994 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
18995 spec->cur_adc = nid;
18996 snd_hda_codec_setup_stream(codec, nid,
18997 spec->cur_adc_stream_tag, 0,
18998 spec->cur_adc_format);
18999 }
19000}
19001
19002static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19003 struct hda_codec *codec,
19004 unsigned int stream_tag,
19005 unsigned int format,
19006 struct snd_pcm_substream *substream)
19007{
19008 struct alc_spec *spec = codec->spec;
19009 hda_nid_t nid = alc680_get_cur_adc(codec);
19010
19011 spec->cur_adc = nid;
19012 spec->cur_adc_stream_tag = stream_tag;
19013 spec->cur_adc_format = format;
19014 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
19015 return 0;
19016}
19017
19018static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19019 struct hda_codec *codec,
19020 struct snd_pcm_substream *substream)
19021{
19022 struct alc_spec *spec = codec->spec;
19023 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
19024 spec->cur_adc = 0;
19025 return 0;
19026}
19027
19028static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19029 .substreams = 1, /* can be overridden */
19030 .channels_min = 2,
19031 .channels_max = 2,
19032 /* NID is set in alc_build_pcms */
19033 .ops = {
19034 .prepare = alc680_capture_pcm_prepare,
19035 .cleanup = alc680_capture_pcm_cleanup
19036 },
19037};
19038
19039static const struct snd_kcontrol_new alc680_base_mixer[] = {
19040 /* output mixer control */
19041 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19042 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19044 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19045 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19046 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19047 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19048 { }
19049};
19050
19051static const struct hda_bind_ctls alc680_bind_cap_vol = {
19052 .ops = &snd_hda_bind_vol,
19053 .values = {
19054 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19055 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19056 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19057 0
19058 },
19059};
19060
19061static const struct hda_bind_ctls alc680_bind_cap_switch = {
19062 .ops = &snd_hda_bind_sw,
19063 .values = {
19064 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19065 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19066 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19067 0
19068 },
19069};
19070
19071static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19072 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19073 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19074 { } /* end */
19075};
19076
19077/*
19078 * generic initialization of ADC, input mixers and output mixers
19079 */
19080static const struct hda_verb alc680_init_verbs[] = {
19081 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19082 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19083 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19084
19085 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19089 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19091
19092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19093 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19094 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19095 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19096 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19097
19098 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19099 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19100 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19101
19102 { }
19103};
19104
19105/* toggle speaker-output according to the hp-jack state */
19106static void alc680_base_setup(struct hda_codec *codec)
19107{
19108 struct alc_spec *spec = codec->spec;
19109
19110 spec->autocfg.hp_pins[0] = 0x16;
19111 spec->autocfg.speaker_pins[0] = 0x14;
19112 spec->autocfg.speaker_pins[1] = 0x15;
19113 spec->autocfg.num_inputs = 2;
19114 spec->autocfg.inputs[0].pin = 0x18;
19115 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19116 spec->autocfg.inputs[1].pin = 0x19;
19117 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19118 spec->automute = 1;
19119 spec->automute_mode = ALC_AUTOMUTE_AMP;
19120}
19121
19122static void alc680_unsol_event(struct hda_codec *codec,
19123 unsigned int res)
19124{
19125 if ((res >> 26) == ALC880_HP_EVENT)
19126 alc_hp_automute(codec);
19127 if ((res >> 26) == ALC880_MIC_EVENT)
19128 alc680_rec_autoswitch(codec);
19129}
19130
19131static void alc680_inithook(struct hda_codec *codec)
19132{
19133 alc_hp_automute(codec);
19134 alc680_rec_autoswitch(codec);
19135}
19136
19137/* create input playback/capture controls for the given pin */ 6325/* create input playback/capture controls for the given pin */
19138static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 6326static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19139 const char *ctlname, int idx) 6327 const char *ctlname, int idx)
@@ -19300,34 +6488,10 @@ static void alc680_auto_init(struct hda_codec *codec)
19300} 6488}
19301 6489
19302/* 6490/*
19303 * configuration and preset
19304 */ 6491 */
19305static const char * const alc680_models[ALC680_MODEL_LAST] = { 6492#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
19306 [ALC680_BASE] = "base", 6493#include "alc680_quirks.c"
19307 [ALC680_AUTO] = "auto", 6494#endif
19308};
19309
19310static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19311 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19312 {}
19313};
19314
19315static const struct alc_config_preset alc680_presets[] = {
19316 [ALC680_BASE] = {
19317 .mixers = { alc680_base_mixer },
19318 .cap_mixer = alc680_master_capture_mixer,
19319 .init_verbs = { alc680_init_verbs },
19320 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19321 .dac_nids = alc680_dac_nids,
19322 .dig_out_nid = ALC680_DIGOUT_NID,
19323 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19324 .channel_mode = alc680_modes,
19325 .unsol_event = alc680_unsol_event,
19326 .setup = alc680_base_setup,
19327 .init_hook = alc680_inithook,
19328
19329 },
19330};
19331 6495
19332static int patch_alc680(struct hda_codec *codec) 6496static int patch_alc680(struct hda_codec *codec)
19333{ 6497{
@@ -19343,33 +6507,37 @@ static int patch_alc680(struct hda_codec *codec)
19343 6507
19344 /* ALC680 has no aa-loopback mixer */ 6508 /* ALC680 has no aa-loopback mixer */
19345 6509
19346 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 6510 board_config = alc_board_config(codec, ALC680_MODEL_LAST,
19347 alc680_models, 6511 alc680_models, alc680_cfg_tbl);
19348 alc680_cfg_tbl);
19349 6512
19350 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 6513 if (board_config < 0) {
19351 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 6514 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19352 codec->chip_name); 6515 codec->chip_name);
19353 board_config = ALC680_AUTO; 6516 board_config = ALC_MODEL_AUTO;
19354 } 6517 }
19355 6518
19356 if (board_config == ALC680_AUTO) { 6519 if (board_config == ALC_MODEL_AUTO) {
19357 /* automatic parse from the BIOS config */ 6520 /* automatic parse from the BIOS config */
19358 err = alc680_parse_auto_config(codec); 6521 err = alc680_parse_auto_config(codec);
19359 if (err < 0) { 6522 if (err < 0) {
19360 alc_free(codec); 6523 alc_free(codec);
19361 return err; 6524 return err;
19362 } else if (!err) { 6525 }
6526#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6527 else if (!err) {
19363 printk(KERN_INFO 6528 printk(KERN_INFO
19364 "hda_codec: Cannot set up configuration " 6529 "hda_codec: Cannot set up configuration "
19365 "from BIOS. Using base mode...\n"); 6530 "from BIOS. Using base mode...\n");
19366 board_config = ALC680_BASE; 6531 board_config = ALC680_BASE;
19367 } 6532 }
6533#endif
19368 } 6534 }
19369 6535
19370 if (board_config != ALC680_AUTO) { 6536 if (board_config != ALC_MODEL_AUTO) {
19371 setup_preset(codec, &alc680_presets[board_config]); 6537 setup_preset(codec, &alc680_presets[board_config]);
6538#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
19372 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 6539 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
6540#endif
19373 } 6541 }
19374 6542
19375 if (!spec->adc_nids) { 6543 if (!spec->adc_nids) {
@@ -19384,7 +6552,7 @@ static int patch_alc680(struct hda_codec *codec)
19384 spec->vmaster_nid = 0x02; 6552 spec->vmaster_nid = 0x02;
19385 6553
19386 codec->patch_ops = alc_patch_ops; 6554 codec->patch_ops = alc_patch_ops;
19387 if (board_config == ALC680_AUTO) 6555 if (board_config == ALC_MODEL_AUTO)
19388 spec->init_hook = alc680_auto_init; 6556 spec->init_hook = alc680_auto_init;
19389 6557
19390 return 0; 6558 return 0;