xref: /openbmc/linux/sound/pci/hda/patch_analog.c (revision 5104d265)
1 /*
2  * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
3  *   AD1986A, AD1988
4  *
5  * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
6  *
7  *  This driver is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This driver is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20  */
21 
22 #include <linux/init.h>
23 #include <linux/slab.h>
24 #include <linux/pci.h>
25 #include <linux/module.h>
26 
27 #include <sound/core.h>
28 #include "hda_codec.h"
29 #include "hda_local.h"
30 #include "hda_auto_parser.h"
31 #include "hda_beep.h"
32 #include "hda_jack.h"
33 #include "hda_generic.h"
34 
35 #define ENABLE_AD_STATIC_QUIRKS
36 
37 struct ad198x_spec {
38 	struct hda_gen_spec gen;
39 
40 	/* for auto parser */
41 	int smux_paths[4];
42 	unsigned int cur_smux;
43 	hda_nid_t eapd_nid;
44 
45 	unsigned int beep_amp;	/* beep amp value, set via set_beep_amp() */
46 
47 #ifdef ENABLE_AD_STATIC_QUIRKS
48 	const struct snd_kcontrol_new *mixers[6];
49 	int num_mixers;
50 	const struct hda_verb *init_verbs[6];	/* initialization verbs
51 						 * don't forget NULL termination!
52 						 */
53 	unsigned int num_init_verbs;
54 
55 	/* playback */
56 	struct hda_multi_out multiout;	/* playback set-up
57 					 * max_channels, dacs must be set
58 					 * dig_out_nid and hp_nid are optional
59 					 */
60 	unsigned int cur_eapd;
61 	unsigned int need_dac_fix;
62 
63 	/* capture */
64 	unsigned int num_adc_nids;
65 	const hda_nid_t *adc_nids;
66 	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
67 
68 	/* capture source */
69 	const struct hda_input_mux *input_mux;
70 	const hda_nid_t *capsrc_nids;
71 	unsigned int cur_mux[3];
72 
73 	/* channel model */
74 	const struct hda_channel_mode *channel_mode;
75 	int num_channel_mode;
76 
77 	/* PCM information */
78 	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
79 
80 	unsigned int spdif_route;
81 
82 	unsigned int jack_present: 1;
83 	unsigned int inv_jack_detect: 1;/* inverted jack-detection */
84 	unsigned int analog_beep: 1;	/* analog beep input present */
85 	unsigned int avoid_init_slave_vol:1;
86 
87 #ifdef CONFIG_PM
88 	struct hda_loopback_check loopback;
89 #endif
90 	/* for virtual master */
91 	hda_nid_t vmaster_nid;
92 	const char * const *slave_vols;
93 	const char * const *slave_sws;
94 #endif /* ENABLE_AD_STATIC_QUIRKS */
95 };
96 
97 #ifdef ENABLE_AD_STATIC_QUIRKS
98 /*
99  * input MUX handling (common part)
100  */
101 static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
102 {
103 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
104 	struct ad198x_spec *spec = codec->spec;
105 
106 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
107 }
108 
109 static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
110 {
111 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
112 	struct ad198x_spec *spec = codec->spec;
113 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
114 
115 	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
116 	return 0;
117 }
118 
119 static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
120 {
121 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
122 	struct ad198x_spec *spec = codec->spec;
123 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
124 
125 	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
126 				     spec->capsrc_nids[adc_idx],
127 				     &spec->cur_mux[adc_idx]);
128 }
129 
130 /*
131  * initialization (common callbacks)
132  */
133 static int ad198x_init(struct hda_codec *codec)
134 {
135 	struct ad198x_spec *spec = codec->spec;
136 	int i;
137 
138 	for (i = 0; i < spec->num_init_verbs; i++)
139 		snd_hda_sequence_write(codec, spec->init_verbs[i]);
140 	return 0;
141 }
142 
143 static const char * const ad_slave_pfxs[] = {
144 	"Front", "Surround", "Center", "LFE", "Side",
145 	"Headphone", "Mono", "Speaker", "IEC958",
146 	NULL
147 };
148 
149 static const char * const ad1988_6stack_fp_slave_pfxs[] = {
150 	"Front", "Surround", "Center", "LFE", "Side", "IEC958",
151 	NULL
152 };
153 #endif /* ENABLE_AD_STATIC_QUIRKS */
154 
155 #ifdef CONFIG_SND_HDA_INPUT_BEEP
156 /* additional beep mixers; the actual parameters are overwritten at build */
157 static const struct snd_kcontrol_new ad_beep_mixer[] = {
158 	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
159 	HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
160 	{ } /* end */
161 };
162 
163 static const struct snd_kcontrol_new ad_beep2_mixer[] = {
164 	HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
165 	HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
166 	{ } /* end */
167 };
168 
169 #define set_beep_amp(spec, nid, idx, dir) \
170 	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
171 #else
172 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
173 #endif
174 
175 #ifdef CONFIG_SND_HDA_INPUT_BEEP
176 static int create_beep_ctls(struct hda_codec *codec)
177 {
178 	struct ad198x_spec *spec = codec->spec;
179 	const struct snd_kcontrol_new *knew;
180 
181 	if (!spec->beep_amp)
182 		return 0;
183 
184 	knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
185 	for ( ; knew->name; knew++) {
186 		int err;
187 		struct snd_kcontrol *kctl;
188 		kctl = snd_ctl_new1(knew, codec);
189 		if (!kctl)
190 			return -ENOMEM;
191 		kctl->private_value = spec->beep_amp;
192 		err = snd_hda_ctl_add(codec, 0, kctl);
193 		if (err < 0)
194 			return err;
195 	}
196 	return 0;
197 }
198 #else
199 #define create_beep_ctls(codec)		0
200 #endif
201 
202 #ifdef ENABLE_AD_STATIC_QUIRKS
203 static int ad198x_build_controls(struct hda_codec *codec)
204 {
205 	struct ad198x_spec *spec = codec->spec;
206 	struct snd_kcontrol *kctl;
207 	unsigned int i;
208 	int err;
209 
210 	for (i = 0; i < spec->num_mixers; i++) {
211 		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
212 		if (err < 0)
213 			return err;
214 	}
215 	if (spec->multiout.dig_out_nid) {
216 		err = snd_hda_create_spdif_out_ctls(codec,
217 						    spec->multiout.dig_out_nid,
218 						    spec->multiout.dig_out_nid);
219 		if (err < 0)
220 			return err;
221 		err = snd_hda_create_spdif_share_sw(codec,
222 						    &spec->multiout);
223 		if (err < 0)
224 			return err;
225 		spec->multiout.share_spdif = 1;
226 	}
227 	if (spec->dig_in_nid) {
228 		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
229 		if (err < 0)
230 			return err;
231 	}
232 
233 	/* create beep controls if needed */
234 	err = create_beep_ctls(codec);
235 	if (err < 0)
236 		return err;
237 
238 	/* if we have no master control, let's create it */
239 	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
240 		unsigned int vmaster_tlv[4];
241 		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
242 					HDA_OUTPUT, vmaster_tlv);
243 		err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
244 					  vmaster_tlv,
245 					  (spec->slave_vols ?
246 					   spec->slave_vols : ad_slave_pfxs),
247 					  "Playback Volume",
248 					  !spec->avoid_init_slave_vol, NULL);
249 		if (err < 0)
250 			return err;
251 	}
252 	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
253 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
254 					  NULL,
255 					  (spec->slave_sws ?
256 					   spec->slave_sws : ad_slave_pfxs),
257 					  "Playback Switch");
258 		if (err < 0)
259 			return err;
260 	}
261 
262 	/* assign Capture Source enums to NID */
263 	kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
264 	if (!kctl)
265 		kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
266 	for (i = 0; kctl && i < kctl->count; i++) {
267 		err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
268 		if (err < 0)
269 			return err;
270 	}
271 
272 	/* assign IEC958 enums to NID */
273 	kctl = snd_hda_find_mixer_ctl(codec,
274 			SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
275 	if (kctl) {
276 		err = snd_hda_add_nid(codec, kctl, 0,
277 				      spec->multiout.dig_out_nid);
278 		if (err < 0)
279 			return err;
280 	}
281 
282 	return 0;
283 }
284 
285 #ifdef CONFIG_PM
286 static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
287 {
288 	struct ad198x_spec *spec = codec->spec;
289 	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
290 }
291 #endif
292 
293 /*
294  * Analog playback callbacks
295  */
296 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
297 				    struct hda_codec *codec,
298 				    struct snd_pcm_substream *substream)
299 {
300 	struct ad198x_spec *spec = codec->spec;
301 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
302 					     hinfo);
303 }
304 
305 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
306 				       struct hda_codec *codec,
307 				       unsigned int stream_tag,
308 				       unsigned int format,
309 				       struct snd_pcm_substream *substream)
310 {
311 	struct ad198x_spec *spec = codec->spec;
312 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
313 						format, substream);
314 }
315 
316 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
317 				       struct hda_codec *codec,
318 				       struct snd_pcm_substream *substream)
319 {
320 	struct ad198x_spec *spec = codec->spec;
321 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
322 }
323 
324 /*
325  * Digital out
326  */
327 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
328 					struct hda_codec *codec,
329 					struct snd_pcm_substream *substream)
330 {
331 	struct ad198x_spec *spec = codec->spec;
332 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
333 }
334 
335 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
336 					 struct hda_codec *codec,
337 					 struct snd_pcm_substream *substream)
338 {
339 	struct ad198x_spec *spec = codec->spec;
340 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
341 }
342 
343 static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
344 					   struct hda_codec *codec,
345 					   unsigned int stream_tag,
346 					   unsigned int format,
347 					   struct snd_pcm_substream *substream)
348 {
349 	struct ad198x_spec *spec = codec->spec;
350 	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
351 					     format, substream);
352 }
353 
354 static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
355 					   struct hda_codec *codec,
356 					   struct snd_pcm_substream *substream)
357 {
358 	struct ad198x_spec *spec = codec->spec;
359 	return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
360 }
361 
362 /*
363  * Analog capture
364  */
365 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
366 				      struct hda_codec *codec,
367 				      unsigned int stream_tag,
368 				      unsigned int format,
369 				      struct snd_pcm_substream *substream)
370 {
371 	struct ad198x_spec *spec = codec->spec;
372 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
373 				   stream_tag, 0, format);
374 	return 0;
375 }
376 
377 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
378 				      struct hda_codec *codec,
379 				      struct snd_pcm_substream *substream)
380 {
381 	struct ad198x_spec *spec = codec->spec;
382 	snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
383 	return 0;
384 }
385 
386 /*
387  */
388 static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
389 	.substreams = 1,
390 	.channels_min = 2,
391 	.channels_max = 6, /* changed later */
392 	.nid = 0, /* fill later */
393 	.ops = {
394 		.open = ad198x_playback_pcm_open,
395 		.prepare = ad198x_playback_pcm_prepare,
396 		.cleanup = ad198x_playback_pcm_cleanup,
397 	},
398 };
399 
400 static const struct hda_pcm_stream ad198x_pcm_analog_capture = {
401 	.substreams = 1,
402 	.channels_min = 2,
403 	.channels_max = 2,
404 	.nid = 0, /* fill later */
405 	.ops = {
406 		.prepare = ad198x_capture_pcm_prepare,
407 		.cleanup = ad198x_capture_pcm_cleanup
408 	},
409 };
410 
411 static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
412 	.substreams = 1,
413 	.channels_min = 2,
414 	.channels_max = 2,
415 	.nid = 0, /* fill later */
416 	.ops = {
417 		.open = ad198x_dig_playback_pcm_open,
418 		.close = ad198x_dig_playback_pcm_close,
419 		.prepare = ad198x_dig_playback_pcm_prepare,
420 		.cleanup = ad198x_dig_playback_pcm_cleanup
421 	},
422 };
423 
424 static const struct hda_pcm_stream ad198x_pcm_digital_capture = {
425 	.substreams = 1,
426 	.channels_min = 2,
427 	.channels_max = 2,
428 	/* NID is set in alc_build_pcms */
429 };
430 
431 static int ad198x_build_pcms(struct hda_codec *codec)
432 {
433 	struct ad198x_spec *spec = codec->spec;
434 	struct hda_pcm *info = spec->pcm_rec;
435 
436 	codec->num_pcms = 1;
437 	codec->pcm_info = info;
438 
439 	info->name = "AD198x Analog";
440 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
441 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
442 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
443 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
444 	info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
445 	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
446 
447 	if (spec->multiout.dig_out_nid) {
448 		info++;
449 		codec->num_pcms++;
450 		codec->spdif_status_reset = 1;
451 		info->name = "AD198x Digital";
452 		info->pcm_type = HDA_PCM_TYPE_SPDIF;
453 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
454 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
455 		if (spec->dig_in_nid) {
456 			info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
457 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
458 		}
459 	}
460 
461 	return 0;
462 }
463 #endif /* ENABLE_AD_STATIC_QUIRKS */
464 
465 static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
466 				hda_nid_t hp)
467 {
468 	if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
469 		snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
470 			    !codec->inv_eapd ? 0x00 : 0x02);
471 	if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
472 		snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
473 			    !codec->inv_eapd ? 0x00 : 0x02);
474 }
475 
476 static void ad198x_power_eapd(struct hda_codec *codec)
477 {
478 	/* We currently only handle front, HP */
479 	switch (codec->vendor_id) {
480 	case 0x11d41882:
481 	case 0x11d4882a:
482 	case 0x11d41884:
483 	case 0x11d41984:
484 	case 0x11d41883:
485 	case 0x11d4184a:
486 	case 0x11d4194a:
487 	case 0x11d4194b:
488 	case 0x11d41988:
489 	case 0x11d4198b:
490 	case 0x11d4989a:
491 	case 0x11d4989b:
492 		ad198x_power_eapd_write(codec, 0x12, 0x11);
493 		break;
494 	case 0x11d41981:
495 	case 0x11d41983:
496 		ad198x_power_eapd_write(codec, 0x05, 0x06);
497 		break;
498 	case 0x11d41986:
499 		ad198x_power_eapd_write(codec, 0x1b, 0x1a);
500 		break;
501 	}
502 }
503 
504 static void ad198x_shutup(struct hda_codec *codec)
505 {
506 	snd_hda_shutup_pins(codec);
507 	ad198x_power_eapd(codec);
508 }
509 
510 static void ad198x_free(struct hda_codec *codec)
511 {
512 	struct ad198x_spec *spec = codec->spec;
513 
514 	if (!spec)
515 		return;
516 
517 	snd_hda_gen_spec_free(&spec->gen);
518 	kfree(spec);
519 	snd_hda_detach_beep_device(codec);
520 }
521 
522 #ifdef CONFIG_PM
523 static int ad198x_suspend(struct hda_codec *codec)
524 {
525 	ad198x_shutup(codec);
526 	return 0;
527 }
528 #endif
529 
530 #ifdef ENABLE_AD_STATIC_QUIRKS
531 static const struct hda_codec_ops ad198x_patch_ops = {
532 	.build_controls = ad198x_build_controls,
533 	.build_pcms = ad198x_build_pcms,
534 	.init = ad198x_init,
535 	.free = ad198x_free,
536 #ifdef CONFIG_PM
537 	.check_power_status = ad198x_check_power_status,
538 	.suspend = ad198x_suspend,
539 #endif
540 	.reboot_notify = ad198x_shutup,
541 };
542 
543 
544 /*
545  * EAPD control
546  * the private value = nid
547  */
548 #define ad198x_eapd_info	snd_ctl_boolean_mono_info
549 
550 static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
551 			   struct snd_ctl_elem_value *ucontrol)
552 {
553 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
554 	struct ad198x_spec *spec = codec->spec;
555 	if (codec->inv_eapd)
556 		ucontrol->value.integer.value[0] = ! spec->cur_eapd;
557 	else
558 		ucontrol->value.integer.value[0] = spec->cur_eapd;
559 	return 0;
560 }
561 
562 static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
563 			   struct snd_ctl_elem_value *ucontrol)
564 {
565 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566 	struct ad198x_spec *spec = codec->spec;
567 	hda_nid_t nid = kcontrol->private_value & 0xff;
568 	unsigned int eapd;
569 	eapd = !!ucontrol->value.integer.value[0];
570 	if (codec->inv_eapd)
571 		eapd = !eapd;
572 	if (eapd == spec->cur_eapd)
573 		return 0;
574 	spec->cur_eapd = eapd;
575 	snd_hda_codec_write_cache(codec, nid,
576 				  0, AC_VERB_SET_EAPD_BTLENABLE,
577 				  eapd ? 0x02 : 0x00);
578 	return 1;
579 }
580 
581 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
582 			       struct snd_ctl_elem_info *uinfo);
583 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
584 			      struct snd_ctl_elem_value *ucontrol);
585 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
586 			      struct snd_ctl_elem_value *ucontrol);
587 #endif /* ENABLE_AD_STATIC_QUIRKS */
588 
589 
590 /*
591  * Automatic parse of I/O pins from the BIOS configuration
592  */
593 
594 static int ad198x_auto_build_controls(struct hda_codec *codec)
595 {
596 	int err;
597 
598 	err = snd_hda_gen_build_controls(codec);
599 	if (err < 0)
600 		return err;
601 	err = create_beep_ctls(codec);
602 	if (err < 0)
603 		return err;
604 	return 0;
605 }
606 
607 static const struct hda_codec_ops ad198x_auto_patch_ops = {
608 	.build_controls = ad198x_auto_build_controls,
609 	.build_pcms = snd_hda_gen_build_pcms,
610 	.init = snd_hda_gen_init,
611 	.free = snd_hda_gen_free,
612 	.unsol_event = snd_hda_jack_unsol_event,
613 #ifdef CONFIG_PM
614 	.check_power_status = snd_hda_gen_check_power_status,
615 	.suspend = ad198x_suspend,
616 #endif
617 	.reboot_notify = ad198x_shutup,
618 };
619 
620 
621 static int ad198x_parse_auto_config(struct hda_codec *codec)
622 {
623 	struct ad198x_spec *spec = codec->spec;
624 	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
625 	int err;
626 
627 	codec->spdif_status_reset = 1;
628 	codec->no_trigger_sense = 1;
629 	codec->no_sticky_stream = 1;
630 
631 	spec->gen.indep_hp = 1;
632 
633 	err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
634 	if (err < 0)
635 		return err;
636 	err = snd_hda_gen_parse_auto_config(codec, cfg);
637 	if (err < 0)
638 		return err;
639 
640 	codec->patch_ops = ad198x_auto_patch_ops;
641 
642 	return 0;
643 }
644 
645 /*
646  * AD1986A specific
647  */
648 
649 #ifdef ENABLE_AD_STATIC_QUIRKS
650 #define AD1986A_SPDIF_OUT	0x02
651 #define AD1986A_FRONT_DAC	0x03
652 #define AD1986A_SURR_DAC	0x04
653 #define AD1986A_CLFE_DAC	0x05
654 #define AD1986A_ADC		0x06
655 
656 static const hda_nid_t ad1986a_dac_nids[3] = {
657 	AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
658 };
659 static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
660 static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
661 
662 static const struct hda_input_mux ad1986a_capture_source = {
663 	.num_items = 7,
664 	.items = {
665 		{ "Mic", 0x0 },
666 		{ "CD", 0x1 },
667 		{ "Aux", 0x3 },
668 		{ "Line", 0x4 },
669 		{ "Mix", 0x5 },
670 		{ "Mono", 0x6 },
671 		{ "Phone", 0x7 },
672 	},
673 };
674 
675 
676 static const struct hda_bind_ctls ad1986a_bind_pcm_vol = {
677 	.ops = &snd_hda_bind_vol,
678 	.values = {
679 		HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
680 		HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
681 		HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
682 		0
683 	},
684 };
685 
686 static const struct hda_bind_ctls ad1986a_bind_pcm_sw = {
687 	.ops = &snd_hda_bind_sw,
688 	.values = {
689 		HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
690 		HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
691 		HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
692 		0
693 	},
694 };
695 
696 /*
697  * mixers
698  */
699 static const struct snd_kcontrol_new ad1986a_mixers[] = {
700 	/*
701 	 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
702 	 */
703 	HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
704 	HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
705 	HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
706 	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
707 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
708 	HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
709 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
710 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
711 	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
712 	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
713 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
714 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
715 	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
716 	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
717 	HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
718 	HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
719 	HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
720 	HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
721 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
722 	HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
723 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
724 	HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
725 	HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
726 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
727 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
728 	{
729 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
730 		.name = "Capture Source",
731 		.info = ad198x_mux_enum_info,
732 		.get = ad198x_mux_enum_get,
733 		.put = ad198x_mux_enum_put,
734 	},
735 	HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
736 	{ } /* end */
737 };
738 
739 /* additional mixers for 3stack mode */
740 static const struct snd_kcontrol_new ad1986a_3st_mixers[] = {
741 	{
742 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
743 		.name = "Channel Mode",
744 		.info = ad198x_ch_mode_info,
745 		.get = ad198x_ch_mode_get,
746 		.put = ad198x_ch_mode_put,
747 	},
748 	{ } /* end */
749 };
750 
751 /* laptop model - 2ch only */
752 static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
753 
754 /* master controls both pins 0x1a and 0x1b */
755 static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
756 	.ops = &snd_hda_bind_vol,
757 	.values = {
758 		HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
759 		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
760 		0,
761 	},
762 };
763 
764 static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
765 	.ops = &snd_hda_bind_sw,
766 	.values = {
767 		HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
768 		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
769 		0,
770 	},
771 };
772 
773 static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
774 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
775 	HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
776 	HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
777 	HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
778 	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
779 	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
780 	HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
781 	HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
782 	HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
783 	HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
784 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
785 	HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
786 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
787 	/*
788 	   HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
789 	   HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
790 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
791 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
792 	{
793 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
794 		.name = "Capture Source",
795 		.info = ad198x_mux_enum_info,
796 		.get = ad198x_mux_enum_get,
797 		.put = ad198x_mux_enum_put,
798 	},
799 	{ } /* end */
800 };
801 
802 /* laptop-eapd model - 2ch only */
803 
804 static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
805 	.num_items = 3,
806 	.items = {
807 		{ "Mic", 0x0 },
808 		{ "Internal Mic", 0x4 },
809 		{ "Mix", 0x5 },
810 	},
811 };
812 
813 static const struct hda_input_mux ad1986a_automic_capture_source = {
814 	.num_items = 2,
815 	.items = {
816 		{ "Mic", 0x0 },
817 		{ "Mix", 0x5 },
818 	},
819 };
820 
821 static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
822 	HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
823 	HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
824 	{ } /* end */
825 };
826 
827 static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
828 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
829 	HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
830 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
831 	HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
832 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
833 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
834 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
835 	{
836 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
837 		.name = "Capture Source",
838 		.info = ad198x_mux_enum_info,
839 		.get = ad198x_mux_enum_get,
840 		.put = ad198x_mux_enum_put,
841 	},
842 	{
843 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
844 		.name = "External Amplifier",
845 		.subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
846 		.info = ad198x_eapd_info,
847 		.get = ad198x_eapd_get,
848 		.put = ad198x_eapd_put,
849 		.private_value = 0x1b, /* port-D */
850 	},
851 	{ } /* end */
852 };
853 
854 static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
855 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
856 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
857 	{ } /* end */
858 };
859 
860 /* re-connect the mic boost input according to the jack sensing */
861 static void ad1986a_automic(struct hda_codec *codec)
862 {
863 	unsigned int present;
864 	present = snd_hda_jack_detect(codec, 0x1f);
865 	/* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
866 	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
867 			    present ? 0 : 2);
868 }
869 
870 #define AD1986A_MIC_EVENT		0x36
871 
872 static void ad1986a_automic_unsol_event(struct hda_codec *codec,
873 					    unsigned int res)
874 {
875 	if ((res >> 26) != AD1986A_MIC_EVENT)
876 		return;
877 	ad1986a_automic(codec);
878 }
879 
880 static int ad1986a_automic_init(struct hda_codec *codec)
881 {
882 	ad198x_init(codec);
883 	ad1986a_automic(codec);
884 	return 0;
885 }
886 
887 /* laptop-automute - 2ch only */
888 
889 static void ad1986a_update_hp(struct hda_codec *codec)
890 {
891 	struct ad198x_spec *spec = codec->spec;
892 	unsigned int mute;
893 
894 	if (spec->jack_present)
895 		mute = HDA_AMP_MUTE; /* mute internal speaker */
896 	else
897 		/* unmute internal speaker if necessary */
898 		mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
899 	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
900 				 HDA_AMP_MUTE, mute);
901 }
902 
903 static void ad1986a_hp_automute(struct hda_codec *codec)
904 {
905 	struct ad198x_spec *spec = codec->spec;
906 
907 	spec->jack_present = snd_hda_jack_detect(codec, 0x1a);
908 	if (spec->inv_jack_detect)
909 		spec->jack_present = !spec->jack_present;
910 	ad1986a_update_hp(codec);
911 }
912 
913 #define AD1986A_HP_EVENT		0x37
914 
915 static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
916 {
917 	if ((res >> 26) != AD1986A_HP_EVENT)
918 		return;
919 	ad1986a_hp_automute(codec);
920 }
921 
922 static int ad1986a_hp_init(struct hda_codec *codec)
923 {
924 	ad198x_init(codec);
925 	ad1986a_hp_automute(codec);
926 	return 0;
927 }
928 
929 /* bind hp and internal speaker mute (with plug check) */
930 static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
931 				    struct snd_ctl_elem_value *ucontrol)
932 {
933 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
934 	int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
935 	if (change)
936 		ad1986a_update_hp(codec);
937 	return change;
938 }
939 
940 static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
941 	HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
942 	{
943 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
944 		.name = "Master Playback Switch",
945 		.subdevice = HDA_SUBDEV_AMP_FLAG,
946 		.info = snd_hda_mixer_amp_switch_info,
947 		.get = snd_hda_mixer_amp_switch_get,
948 		.put = ad1986a_hp_master_sw_put,
949 		.private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
950 	},
951 	{ } /* end */
952 };
953 
954 
955 /*
956  * initialization verbs
957  */
958 static const struct hda_verb ad1986a_init_verbs[] = {
959 	/* Front, Surround, CLFE DAC; mute as default */
960 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
961 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
962 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
963 	/* Downmix - off */
964 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
965 	/* HP, Line-Out, Surround, CLFE selectors */
966 	{0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
967 	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
968 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
969 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
970 	/* Mono selector */
971 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
972 	/* Mic selector: Mic 1/2 pin */
973 	{0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
974 	/* Line-in selector: Line-in */
975 	{0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
976 	/* Mic 1/2 swap */
977 	{0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
978 	/* Record selector: mic */
979 	{0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
980 	/* Mic, Phone, CD, Aux, Line-In amp; mute as default */
981 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
982 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
983 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
984 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
985 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
986 	/* PC beep */
987 	{0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
988 	/* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
989 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
990 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
991 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
992 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
993 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
994 	/* HP Pin */
995 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
996 	/* Front, Surround, CLFE Pins */
997 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
998 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
999 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1000 	/* Mono Pin */
1001 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1002 	/* Mic Pin */
1003 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1004 	/* Line, Aux, CD, Beep-In Pin */
1005 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1006 	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1007 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1008 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1009 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1010 	{ } /* end */
1011 };
1012 
1013 static const struct hda_verb ad1986a_ch2_init[] = {
1014 	/* Surround out -> Line In */
1015 	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1016  	/* Line-in selectors */
1017 	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
1018 	/* CLFE -> Mic in */
1019 	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1020 	/* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
1021 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1022 	{ } /* end */
1023 };
1024 
1025 static const struct hda_verb ad1986a_ch4_init[] = {
1026 	/* Surround out -> Surround */
1027 	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1028 	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1029 	/* CLFE -> Mic in */
1030 	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1031 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1032 	{ } /* end */
1033 };
1034 
1035 static const struct hda_verb ad1986a_ch6_init[] = {
1036 	/* Surround out -> Surround out */
1037 	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1038 	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1039 	/* CLFE -> CLFE */
1040 	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1041 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
1042 	{ } /* end */
1043 };
1044 
1045 static const struct hda_channel_mode ad1986a_modes[3] = {
1046 	{ 2, ad1986a_ch2_init },
1047 	{ 4, ad1986a_ch4_init },
1048 	{ 6, ad1986a_ch6_init },
1049 };
1050 
1051 /* eapd initialization */
1052 static const struct hda_verb ad1986a_eapd_init_verbs[] = {
1053 	{0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1054 	{}
1055 };
1056 
1057 static const struct hda_verb ad1986a_automic_verbs[] = {
1058 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1059 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1060 	/*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
1061 	{0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
1062 	{0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT},
1063 	{}
1064 };
1065 
1066 /* Ultra initialization */
1067 static const struct hda_verb ad1986a_ultra_init[] = {
1068 	/* eapd initialization */
1069 	{ 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1070 	/* CLFE -> Mic in */
1071 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
1072 	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1073 	{ 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
1074 	{ } /* end */
1075 };
1076 
1077 /* pin sensing on HP jack */
1078 static const struct hda_verb ad1986a_hp_init_verbs[] = {
1079 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
1080 	{}
1081 };
1082 
1083 static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec,
1084 					    unsigned int res)
1085 {
1086 	switch (res >> 26) {
1087 	case AD1986A_HP_EVENT:
1088 		ad1986a_hp_automute(codec);
1089 		break;
1090 	case AD1986A_MIC_EVENT:
1091 		ad1986a_automic(codec);
1092 		break;
1093 	}
1094 }
1095 
1096 static int ad1986a_samsung_p50_init(struct hda_codec *codec)
1097 {
1098 	ad198x_init(codec);
1099 	ad1986a_hp_automute(codec);
1100 	ad1986a_automic(codec);
1101 	return 0;
1102 }
1103 
1104 
1105 /* models */
1106 enum {
1107 	AD1986A_AUTO,
1108 	AD1986A_6STACK,
1109 	AD1986A_3STACK,
1110 	AD1986A_LAPTOP,
1111 	AD1986A_LAPTOP_EAPD,
1112 	AD1986A_LAPTOP_AUTOMUTE,
1113 	AD1986A_ULTRA,
1114 	AD1986A_SAMSUNG,
1115 	AD1986A_SAMSUNG_P50,
1116 	AD1986A_MODELS
1117 };
1118 
1119 static const char * const ad1986a_models[AD1986A_MODELS] = {
1120 	[AD1986A_AUTO]		= "auto",
1121 	[AD1986A_6STACK]	= "6stack",
1122 	[AD1986A_3STACK]	= "3stack",
1123 	[AD1986A_LAPTOP]	= "laptop",
1124 	[AD1986A_LAPTOP_EAPD]	= "laptop-eapd",
1125 	[AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
1126 	[AD1986A_ULTRA]		= "ultra",
1127 	[AD1986A_SAMSUNG]	= "samsung",
1128 	[AD1986A_SAMSUNG_P50]	= "samsung-p50",
1129 };
1130 
1131 static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1132 	SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
1133 	SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
1134 	SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
1135 	SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
1136 	SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
1137 	SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
1138 	SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
1139 	SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
1140 	SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
1141 	SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
1142 	SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
1143 	SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
1144 	SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
1145 	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1146 	SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1147 	SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1148 	SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1149 	SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1150 	SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1151 	SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
1152 	SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
1153 	SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG),
1154 	SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
1155 	SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
1156 	SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
1157 	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
1158 	SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
1159 	{}
1160 };
1161 
1162 #ifdef CONFIG_PM
1163 static const struct hda_amp_list ad1986a_loopbacks[] = {
1164 	{ 0x13, HDA_OUTPUT, 0 }, /* Mic */
1165 	{ 0x14, HDA_OUTPUT, 0 }, /* Phone */
1166 	{ 0x15, HDA_OUTPUT, 0 }, /* CD */
1167 	{ 0x16, HDA_OUTPUT, 0 }, /* Aux */
1168 	{ 0x17, HDA_OUTPUT, 0 }, /* Line */
1169 	{ } /* end */
1170 };
1171 #endif
1172 
1173 static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
1174 {
1175 	unsigned int conf = snd_hda_codec_get_pincfg(codec, nid);
1176 	return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
1177 }
1178 #endif /* ENABLE_AD_STATIC_QUIRKS */
1179 
1180 static int alloc_ad_spec(struct hda_codec *codec)
1181 {
1182 	struct ad198x_spec *spec;
1183 
1184 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1185 	if (!spec)
1186 		return -ENOMEM;
1187 	codec->spec = spec;
1188 	snd_hda_gen_spec_init(&spec->gen);
1189 	return 0;
1190 }
1191 
1192 /*
1193  * AD1986A fixup codes
1194  */
1195 
1196 /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
1197 static void ad_fixup_inv_jack_detect(struct hda_codec *codec,
1198 				     const struct hda_fixup *fix, int action)
1199 {
1200 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
1201 		codec->inv_jack_detect = 1;
1202 }
1203 
1204 enum {
1205 	AD1986A_FIXUP_INV_JACK_DETECT,
1206 };
1207 
1208 static const struct hda_fixup ad1986a_fixups[] = {
1209 	[AD1986A_FIXUP_INV_JACK_DETECT] = {
1210 		.type = HDA_FIXUP_FUNC,
1211 		.v.func = ad_fixup_inv_jack_detect,
1212 	},
1213 };
1214 
1215 static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
1216 	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT),
1217 	{}
1218 };
1219 
1220 /*
1221  */
1222 static int ad1986a_parse_auto_config(struct hda_codec *codec)
1223 {
1224 	int err;
1225 	struct ad198x_spec *spec;
1226 
1227 	err = alloc_ad_spec(codec);
1228 	if (err < 0)
1229 		return err;
1230 	spec = codec->spec;
1231 
1232 	/* AD1986A has the inverted EAPD implementation */
1233 	codec->inv_eapd = 1;
1234 
1235 	spec->gen.mixer_nid = 0x07;
1236 	spec->gen.beep_nid = 0x19;
1237 	set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1238 
1239 	/* AD1986A has a hardware problem that it can't share a stream
1240 	 * with multiple output pins.  The copy of front to surrounds
1241 	 * causes noisy or silent outputs at a certain timing, e.g.
1242 	 * changing the volume.
1243 	 * So, let's disable the shared stream.
1244 	 */
1245 	spec->gen.multiout.no_share_stream = 1;
1246 
1247 	snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups);
1248 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1249 
1250 	err = ad198x_parse_auto_config(codec);
1251 	if (err < 0) {
1252 		snd_hda_gen_free(codec);
1253 		return err;
1254 	}
1255 
1256 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1257 
1258 	return 0;
1259 }
1260 
1261 #ifdef ENABLE_AD_STATIC_QUIRKS
1262 static int patch_ad1986a(struct hda_codec *codec)
1263 {
1264 	struct ad198x_spec *spec;
1265 	int err, board_config;
1266 
1267 	board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
1268 						  ad1986a_models,
1269 						  ad1986a_cfg_tbl);
1270 	if (board_config < 0) {
1271 		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1272 		       codec->chip_name);
1273 		board_config = AD1986A_AUTO;
1274 	}
1275 
1276 	if (board_config == AD1986A_AUTO)
1277 		return ad1986a_parse_auto_config(codec);
1278 
1279 	err = alloc_ad_spec(codec);
1280 	if (err < 0)
1281 		return err;
1282 	spec = codec->spec;
1283 
1284 	err = snd_hda_attach_beep_device(codec, 0x19);
1285 	if (err < 0) {
1286 		ad198x_free(codec);
1287 		return err;
1288 	}
1289 	set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1290 
1291 	spec->multiout.max_channels = 6;
1292 	spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
1293 	spec->multiout.dac_nids = ad1986a_dac_nids;
1294 	spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
1295 	spec->num_adc_nids = 1;
1296 	spec->adc_nids = ad1986a_adc_nids;
1297 	spec->capsrc_nids = ad1986a_capsrc_nids;
1298 	spec->input_mux = &ad1986a_capture_source;
1299 	spec->num_mixers = 1;
1300 	spec->mixers[0] = ad1986a_mixers;
1301 	spec->num_init_verbs = 1;
1302 	spec->init_verbs[0] = ad1986a_init_verbs;
1303 #ifdef CONFIG_PM
1304 	spec->loopback.amplist = ad1986a_loopbacks;
1305 #endif
1306 	spec->vmaster_nid = 0x1b;
1307 	codec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
1308 
1309 	codec->patch_ops = ad198x_patch_ops;
1310 
1311 	/* override some parameters */
1312 	switch (board_config) {
1313 	case AD1986A_3STACK:
1314 		spec->num_mixers = 2;
1315 		spec->mixers[1] = ad1986a_3st_mixers;
1316 		spec->num_init_verbs = 2;
1317 		spec->init_verbs[1] = ad1986a_ch2_init;
1318 		spec->channel_mode = ad1986a_modes;
1319 		spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
1320 		spec->need_dac_fix = 1;
1321 		spec->multiout.max_channels = 2;
1322 		spec->multiout.num_dacs = 1;
1323 		break;
1324 	case AD1986A_LAPTOP:
1325 		spec->mixers[0] = ad1986a_laptop_mixers;
1326 		spec->multiout.max_channels = 2;
1327 		spec->multiout.num_dacs = 1;
1328 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1329 		break;
1330 	case AD1986A_LAPTOP_EAPD:
1331 		spec->num_mixers = 3;
1332 		spec->mixers[0] = ad1986a_laptop_master_mixers;
1333 		spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1334 		spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1335 		spec->num_init_verbs = 2;
1336 		spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1337 		spec->multiout.max_channels = 2;
1338 		spec->multiout.num_dacs = 1;
1339 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1340 		if (!is_jack_available(codec, 0x25))
1341 			spec->multiout.dig_out_nid = 0;
1342 		spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1343 		break;
1344 	case AD1986A_SAMSUNG:
1345 		spec->num_mixers = 2;
1346 		spec->mixers[0] = ad1986a_laptop_master_mixers;
1347 		spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1348 		spec->num_init_verbs = 3;
1349 		spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1350 		spec->init_verbs[2] = ad1986a_automic_verbs;
1351 		spec->multiout.max_channels = 2;
1352 		spec->multiout.num_dacs = 1;
1353 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1354 		if (!is_jack_available(codec, 0x25))
1355 			spec->multiout.dig_out_nid = 0;
1356 		spec->input_mux = &ad1986a_automic_capture_source;
1357 		codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1358 		codec->patch_ops.init = ad1986a_automic_init;
1359 		break;
1360 	case AD1986A_SAMSUNG_P50:
1361 		spec->num_mixers = 2;
1362 		spec->mixers[0] = ad1986a_automute_master_mixers;
1363 		spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1364 		spec->num_init_verbs = 4;
1365 		spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1366 		spec->init_verbs[2] = ad1986a_automic_verbs;
1367 		spec->init_verbs[3] = ad1986a_hp_init_verbs;
1368 		spec->multiout.max_channels = 2;
1369 		spec->multiout.num_dacs = 1;
1370 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1371 		if (!is_jack_available(codec, 0x25))
1372 			spec->multiout.dig_out_nid = 0;
1373 		spec->input_mux = &ad1986a_automic_capture_source;
1374 		codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
1375 		codec->patch_ops.init = ad1986a_samsung_p50_init;
1376 		break;
1377 	case AD1986A_LAPTOP_AUTOMUTE:
1378 		spec->num_mixers = 3;
1379 		spec->mixers[0] = ad1986a_automute_master_mixers;
1380 		spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1381 		spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1382 		spec->num_init_verbs = 3;
1383 		spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1384 		spec->init_verbs[2] = ad1986a_hp_init_verbs;
1385 		spec->multiout.max_channels = 2;
1386 		spec->multiout.num_dacs = 1;
1387 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1388 		if (!is_jack_available(codec, 0x25))
1389 			spec->multiout.dig_out_nid = 0;
1390 		spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1391 		codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1392 		codec->patch_ops.init = ad1986a_hp_init;
1393 		/* Lenovo N100 seems to report the reversed bit
1394 		 * for HP jack-sensing
1395 		 */
1396 		spec->inv_jack_detect = 1;
1397 		break;
1398 	case AD1986A_ULTRA:
1399 		spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1400 		spec->num_init_verbs = 2;
1401 		spec->init_verbs[1] = ad1986a_ultra_init;
1402 		spec->multiout.max_channels = 2;
1403 		spec->multiout.num_dacs = 1;
1404 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1405 		spec->multiout.dig_out_nid = 0;
1406 		break;
1407 	}
1408 
1409 	/* AD1986A has a hardware problem that it can't share a stream
1410 	 * with multiple output pins.  The copy of front to surrounds
1411 	 * causes noisy or silent outputs at a certain timing, e.g.
1412 	 * changing the volume.
1413 	 * So, let's disable the shared stream.
1414 	 */
1415 	spec->multiout.no_share_stream = 1;
1416 
1417 	codec->no_trigger_sense = 1;
1418 	codec->no_sticky_stream = 1;
1419 
1420 	return 0;
1421 }
1422 #else /* ENABLE_AD_STATIC_QUIRKS */
1423 #define patch_ad1986a	ad1986a_parse_auto_config
1424 #endif /* ENABLE_AD_STATIC_QUIRKS */
1425 
1426 /*
1427  * AD1983 specific
1428  */
1429 
1430 #ifdef ENABLE_AD_STATIC_QUIRKS
1431 #define AD1983_SPDIF_OUT	0x02
1432 #define AD1983_DAC		0x03
1433 #define AD1983_ADC		0x04
1434 
1435 static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1436 static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1437 static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1438 
1439 static const struct hda_input_mux ad1983_capture_source = {
1440 	.num_items = 4,
1441 	.items = {
1442 		{ "Mic", 0x0 },
1443 		{ "Line", 0x1 },
1444 		{ "Mix", 0x2 },
1445 		{ "Mix Mono", 0x3 },
1446 	},
1447 };
1448 
1449 /*
1450  * SPDIF playback route
1451  */
1452 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1453 {
1454 	static const char * const texts[] = { "PCM", "ADC" };
1455 
1456 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1457 	uinfo->count = 1;
1458 	uinfo->value.enumerated.items = 2;
1459 	if (uinfo->value.enumerated.item > 1)
1460 		uinfo->value.enumerated.item = 1;
1461 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1462 	return 0;
1463 }
1464 
1465 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1466 {
1467 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1468 	struct ad198x_spec *spec = codec->spec;
1469 
1470 	ucontrol->value.enumerated.item[0] = spec->spdif_route;
1471 	return 0;
1472 }
1473 
1474 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1475 {
1476 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1477 	struct ad198x_spec *spec = codec->spec;
1478 
1479 	if (ucontrol->value.enumerated.item[0] > 1)
1480 		return -EINVAL;
1481 	if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1482 		spec->spdif_route = ucontrol->value.enumerated.item[0];
1483 		snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1484 					  AC_VERB_SET_CONNECT_SEL,
1485 					  spec->spdif_route);
1486 		return 1;
1487 	}
1488 	return 0;
1489 }
1490 
1491 static const struct snd_kcontrol_new ad1983_mixers[] = {
1492 	HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1493 	HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1494 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1495 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1496 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1497 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1498 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1499 	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1500 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1501 	HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1502 	HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1503 	HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1504 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1505 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1506 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1507 	{
1508 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509 		.name = "Capture Source",
1510 		.info = ad198x_mux_enum_info,
1511 		.get = ad198x_mux_enum_get,
1512 		.put = ad198x_mux_enum_put,
1513 	},
1514 	{
1515 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1517 		.info = ad1983_spdif_route_info,
1518 		.get = ad1983_spdif_route_get,
1519 		.put = ad1983_spdif_route_put,
1520 	},
1521 	{ } /* end */
1522 };
1523 
1524 static const struct hda_verb ad1983_init_verbs[] = {
1525 	/* Front, HP, Mono; mute as default */
1526 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1527 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1528 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1529 	/* Beep, PCM, Mic, Line-In: mute */
1530 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1531 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1532 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1533 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1534 	/* Front, HP selectors; from Mix */
1535 	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1536 	{0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1537 	/* Mono selector; from Mix */
1538 	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1539 	/* Mic selector; Mic */
1540 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1541 	/* Line-in selector: Line-in */
1542 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1543 	/* Mic boost: 0dB */
1544 	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1545 	/* Record selector: mic */
1546 	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1547 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1548 	/* SPDIF route: PCM */
1549 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1550 	/* Front Pin */
1551 	{0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1552 	/* HP Pin */
1553 	{0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1554 	/* Mono Pin */
1555 	{0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1556 	/* Mic Pin */
1557 	{0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1558 	/* Line Pin */
1559 	{0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1560 	{ } /* end */
1561 };
1562 
1563 #ifdef CONFIG_PM
1564 static const struct hda_amp_list ad1983_loopbacks[] = {
1565 	{ 0x12, HDA_OUTPUT, 0 }, /* Mic */
1566 	{ 0x13, HDA_OUTPUT, 0 }, /* Line */
1567 	{ } /* end */
1568 };
1569 #endif
1570 
1571 /* models */
1572 enum {
1573 	AD1983_AUTO,
1574 	AD1983_BASIC,
1575 	AD1983_MODELS
1576 };
1577 
1578 static const char * const ad1983_models[AD1983_MODELS] = {
1579 	[AD1983_AUTO]		= "auto",
1580 	[AD1983_BASIC]		= "basic",
1581 };
1582 #endif /* ENABLE_AD_STATIC_QUIRKS */
1583 
1584 
1585 /*
1586  * SPDIF mux control for AD1983 auto-parser
1587  */
1588 static int ad1983_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
1589 				      struct snd_ctl_elem_info *uinfo)
1590 {
1591 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1592 	struct ad198x_spec *spec = codec->spec;
1593 	static const char * const texts2[] = { "PCM", "ADC" };
1594 	static const char * const texts3[] = { "PCM", "ADC1", "ADC2" };
1595 	hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
1596 	int num_conns = snd_hda_get_num_conns(codec, dig_out);
1597 
1598 	if (num_conns == 2)
1599 		return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2);
1600 	else if (num_conns == 3)
1601 		return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3);
1602 	else
1603 		return -EINVAL;
1604 }
1605 
1606 static int ad1983_auto_smux_enum_get(struct snd_kcontrol *kcontrol,
1607 				     struct snd_ctl_elem_value *ucontrol)
1608 {
1609 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1610 	struct ad198x_spec *spec = codec->spec;
1611 
1612 	ucontrol->value.enumerated.item[0] = spec->cur_smux;
1613 	return 0;
1614 }
1615 
1616 static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
1617 				     struct snd_ctl_elem_value *ucontrol)
1618 {
1619 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1620 	struct ad198x_spec *spec = codec->spec;
1621 	unsigned int val = ucontrol->value.enumerated.item[0];
1622 	hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
1623 	int num_conns = snd_hda_get_num_conns(codec, dig_out);
1624 
1625 	if (val >= num_conns)
1626 		return -EINVAL;
1627 	if (spec->cur_smux == val)
1628 		return 0;
1629 	spec->cur_smux = val;
1630 	snd_hda_codec_write_cache(codec, dig_out, 0,
1631 				  AC_VERB_SET_CONNECT_SEL, val);
1632 	return 1;
1633 }
1634 
1635 static struct snd_kcontrol_new ad1983_auto_smux_mixer = {
1636 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1637 	.name = "IEC958 Playback Source",
1638 	.info = ad1983_auto_smux_enum_info,
1639 	.get = ad1983_auto_smux_enum_get,
1640 	.put = ad1983_auto_smux_enum_put,
1641 };
1642 
1643 static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
1644 {
1645 	struct ad198x_spec *spec = codec->spec;
1646 	hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
1647 	int num_conns;
1648 
1649 	if (!dig_out)
1650 		return 0;
1651 	num_conns = snd_hda_get_num_conns(codec, dig_out);
1652 	if (num_conns != 2 && num_conns != 3)
1653 		return 0;
1654 	if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer))
1655 		return -ENOMEM;
1656 	return 0;
1657 }
1658 
1659 static int ad1983_parse_auto_config(struct hda_codec *codec)
1660 {
1661 	struct ad198x_spec *spec;
1662 	int err;
1663 
1664 	err = alloc_ad_spec(codec);
1665 	if (err < 0)
1666 		return err;
1667 	spec = codec->spec;
1668 
1669 	spec->gen.beep_nid = 0x10;
1670 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1671 	err = ad198x_parse_auto_config(codec);
1672 	if (err < 0)
1673 		goto error;
1674 	err = ad1983_add_spdif_mux_ctl(codec);
1675 	if (err < 0)
1676 		goto error;
1677 	return 0;
1678 
1679  error:
1680 	snd_hda_gen_free(codec);
1681 	return err;
1682 }
1683 
1684 #ifdef ENABLE_AD_STATIC_QUIRKS
1685 static int patch_ad1983(struct hda_codec *codec)
1686 {
1687 	struct ad198x_spec *spec;
1688 	int board_config;
1689 	int err;
1690 
1691 	board_config = snd_hda_check_board_config(codec, AD1983_MODELS,
1692 						  ad1983_models, NULL);
1693 	if (board_config < 0) {
1694 		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1695 		       codec->chip_name);
1696 		board_config = AD1983_AUTO;
1697 	}
1698 
1699 	if (board_config == AD1983_AUTO)
1700 		return ad1983_parse_auto_config(codec);
1701 
1702 	err = alloc_ad_spec(codec);
1703 	if (err < 0)
1704 		return err;
1705 	spec = codec->spec;
1706 
1707 	err = snd_hda_attach_beep_device(codec, 0x10);
1708 	if (err < 0) {
1709 		ad198x_free(codec);
1710 		return err;
1711 	}
1712 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1713 
1714 	spec->multiout.max_channels = 2;
1715 	spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1716 	spec->multiout.dac_nids = ad1983_dac_nids;
1717 	spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1718 	spec->num_adc_nids = 1;
1719 	spec->adc_nids = ad1983_adc_nids;
1720 	spec->capsrc_nids = ad1983_capsrc_nids;
1721 	spec->input_mux = &ad1983_capture_source;
1722 	spec->num_mixers = 1;
1723 	spec->mixers[0] = ad1983_mixers;
1724 	spec->num_init_verbs = 1;
1725 	spec->init_verbs[0] = ad1983_init_verbs;
1726 	spec->spdif_route = 0;
1727 #ifdef CONFIG_PM
1728 	spec->loopback.amplist = ad1983_loopbacks;
1729 #endif
1730 	spec->vmaster_nid = 0x05;
1731 
1732 	codec->patch_ops = ad198x_patch_ops;
1733 
1734 	codec->no_trigger_sense = 1;
1735 	codec->no_sticky_stream = 1;
1736 
1737 	return 0;
1738 }
1739 #else /* ENABLE_AD_STATIC_QUIRKS */
1740 #define patch_ad1983	ad1983_parse_auto_config
1741 #endif /* ENABLE_AD_STATIC_QUIRKS */
1742 
1743 
1744 /*
1745  * AD1981 HD specific
1746  */
1747 
1748 #ifdef ENABLE_AD_STATIC_QUIRKS
1749 #define AD1981_SPDIF_OUT	0x02
1750 #define AD1981_DAC		0x03
1751 #define AD1981_ADC		0x04
1752 
1753 static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1754 static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1755 static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1756 
1757 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1758 static const struct hda_input_mux ad1981_capture_source = {
1759 	.num_items = 7,
1760 	.items = {
1761 		{ "Front Mic", 0x0 },
1762 		{ "Line", 0x1 },
1763 		{ "Mix", 0x2 },
1764 		{ "Mix Mono", 0x3 },
1765 		{ "CD", 0x4 },
1766 		{ "Mic", 0x6 },
1767 		{ "Aux", 0x7 },
1768 	},
1769 };
1770 
1771 static const struct snd_kcontrol_new ad1981_mixers[] = {
1772 	HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1773 	HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1774 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1775 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1776 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1777 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1778 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1779 	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1780 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1781 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1782 	HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1783 	HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1784 	HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1785 	HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1786 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1787 	HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1788 	HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1789 	HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1790 	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1791 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1792 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1793 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1794 	{
1795 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1796 		.name = "Capture Source",
1797 		.info = ad198x_mux_enum_info,
1798 		.get = ad198x_mux_enum_get,
1799 		.put = ad198x_mux_enum_put,
1800 	},
1801 	/* identical with AD1983 */
1802 	{
1803 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1804 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1805 		.info = ad1983_spdif_route_info,
1806 		.get = ad1983_spdif_route_get,
1807 		.put = ad1983_spdif_route_put,
1808 	},
1809 	{ } /* end */
1810 };
1811 
1812 static const struct hda_verb ad1981_init_verbs[] = {
1813 	/* Front, HP, Mono; mute as default */
1814 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1815 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1816 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1817 	/* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1818 	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1819 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1820 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1821 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1822 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1823 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1824 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1825 	/* Front, HP selectors; from Mix */
1826 	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1827 	{0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1828 	/* Mono selector; from Mix */
1829 	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1830 	/* Mic Mixer; select Front Mic */
1831 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1832 	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1833 	/* Mic boost: 0dB */
1834 	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1835 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1836 	/* Record selector: Front mic */
1837 	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1838 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1839 	/* SPDIF route: PCM */
1840 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1841 	/* Front Pin */
1842 	{0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1843 	/* HP Pin */
1844 	{0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1845 	/* Mono Pin */
1846 	{0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1847 	/* Front & Rear Mic Pins */
1848 	{0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1849 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1850 	/* Line Pin */
1851 	{0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1852 	/* Digital Beep */
1853 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1854 	/* Line-Out as Input: disabled */
1855 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1856 	{ } /* end */
1857 };
1858 
1859 #ifdef CONFIG_PM
1860 static const struct hda_amp_list ad1981_loopbacks[] = {
1861 	{ 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1862 	{ 0x13, HDA_OUTPUT, 0 }, /* Line */
1863 	{ 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1864 	{ 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1865 	{ 0x1d, HDA_OUTPUT, 0 }, /* CD */
1866 	{ } /* end */
1867 };
1868 #endif
1869 
1870 /*
1871  * Patch for HP nx6320
1872  *
1873  * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1874  * speaker output enabled _and_ mute-LED off.
1875  */
1876 
1877 #define AD1981_HP_EVENT		0x37
1878 #define AD1981_MIC_EVENT	0x38
1879 
1880 static const struct hda_verb ad1981_hp_init_verbs[] = {
1881 	{0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1882 	/* pin sensing on HP and Mic jacks */
1883 	{0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1884 	{0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1885 	{}
1886 };
1887 
1888 /* turn on/off EAPD (+ mute HP) as a master switch */
1889 static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1890 				   struct snd_ctl_elem_value *ucontrol)
1891 {
1892 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1893 	struct ad198x_spec *spec = codec->spec;
1894 
1895 	if (! ad198x_eapd_put(kcontrol, ucontrol))
1896 		return 0;
1897 	/* change speaker pin appropriately */
1898 	snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0);
1899 	/* toggle HP mute appropriately */
1900 	snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1901 				 HDA_AMP_MUTE,
1902 				 spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1903 	return 1;
1904 }
1905 
1906 /* bind volumes of both NID 0x05 and 0x06 */
1907 static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1908 	.ops = &snd_hda_bind_vol,
1909 	.values = {
1910 		HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1911 		HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1912 		0
1913 	},
1914 };
1915 
1916 /* mute internal speaker if HP is plugged */
1917 static void ad1981_hp_automute(struct hda_codec *codec)
1918 {
1919 	unsigned int present;
1920 
1921 	present = snd_hda_jack_detect(codec, 0x06);
1922 	snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1923 				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1924 }
1925 
1926 /* toggle input of built-in and mic jack appropriately */
1927 static void ad1981_hp_automic(struct hda_codec *codec)
1928 {
1929 	static const struct hda_verb mic_jack_on[] = {
1930 		{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1931 		{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1932 		{}
1933 	};
1934 	static const struct hda_verb mic_jack_off[] = {
1935 		{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1936 		{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1937 		{}
1938 	};
1939 	unsigned int present;
1940 
1941 	present = snd_hda_jack_detect(codec, 0x08);
1942 	if (present)
1943 		snd_hda_sequence_write(codec, mic_jack_on);
1944 	else
1945 		snd_hda_sequence_write(codec, mic_jack_off);
1946 }
1947 
1948 /* unsolicited event for HP jack sensing */
1949 static void ad1981_hp_unsol_event(struct hda_codec *codec,
1950 				  unsigned int res)
1951 {
1952 	res >>= 26;
1953 	switch (res) {
1954 	case AD1981_HP_EVENT:
1955 		ad1981_hp_automute(codec);
1956 		break;
1957 	case AD1981_MIC_EVENT:
1958 		ad1981_hp_automic(codec);
1959 		break;
1960 	}
1961 }
1962 
1963 static const struct hda_input_mux ad1981_hp_capture_source = {
1964 	.num_items = 3,
1965 	.items = {
1966 		{ "Mic", 0x0 },
1967 		{ "Dock Mic", 0x1 },
1968 		{ "Mix", 0x2 },
1969 	},
1970 };
1971 
1972 static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
1973 	HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1974 	{
1975 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1976 		.subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1977 		.name = "Master Playback Switch",
1978 		.info = ad198x_eapd_info,
1979 		.get = ad198x_eapd_get,
1980 		.put = ad1981_hp_master_sw_put,
1981 		.private_value = 0x05,
1982 	},
1983 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1984 	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1985 #if 0
1986 	/* FIXME: analog mic/line loopback doesn't work with my tests...
1987 	 *        (although recording is OK)
1988 	 */
1989 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1990 	HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1991 	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1992 	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1993 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1994 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1995 	/* FIXME: does this laptop have analog CD connection? */
1996 	HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1997 	HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1998 #endif
1999 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
2000 	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
2001 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
2002 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
2003 	{
2004 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2005 		.name = "Capture Source",
2006 		.info = ad198x_mux_enum_info,
2007 		.get = ad198x_mux_enum_get,
2008 		.put = ad198x_mux_enum_put,
2009 	},
2010 	{ } /* end */
2011 };
2012 
2013 /* initialize jack-sensing, too */
2014 static int ad1981_hp_init(struct hda_codec *codec)
2015 {
2016 	ad198x_init(codec);
2017 	ad1981_hp_automute(codec);
2018 	ad1981_hp_automic(codec);
2019 	return 0;
2020 }
2021 
2022 /* configuration for Toshiba Laptops */
2023 static const struct hda_verb ad1981_toshiba_init_verbs[] = {
2024 	{0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
2025 	/* pin sensing on HP and Mic jacks */
2026 	{0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
2027 	{0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
2028 	{}
2029 };
2030 
2031 static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
2032 	HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
2033 	HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
2034 	{ }
2035 };
2036 
2037 /* configuration for Lenovo Thinkpad T60 */
2038 static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
2039 	HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2040 	HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
2041 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
2042 	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2043 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
2044 	HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2045 	HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2046 	HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
2047 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
2048 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
2049 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
2050 	{
2051 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2052 		.name = "Capture Source",
2053 		.info = ad198x_mux_enum_info,
2054 		.get = ad198x_mux_enum_get,
2055 		.put = ad198x_mux_enum_put,
2056 	},
2057 	/* identical with AD1983 */
2058 	{
2059 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2060 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2061 		.info = ad1983_spdif_route_info,
2062 		.get = ad1983_spdif_route_get,
2063 		.put = ad1983_spdif_route_put,
2064 	},
2065 	{ } /* end */
2066 };
2067 
2068 static const struct hda_input_mux ad1981_thinkpad_capture_source = {
2069 	.num_items = 3,
2070 	.items = {
2071 		{ "Mic", 0x0 },
2072 		{ "Mix", 0x2 },
2073 		{ "CD", 0x4 },
2074 	},
2075 };
2076 
2077 /* models */
2078 enum {
2079 	AD1981_AUTO,
2080 	AD1981_BASIC,
2081 	AD1981_HP,
2082 	AD1981_THINKPAD,
2083 	AD1981_TOSHIBA,
2084 	AD1981_MODELS
2085 };
2086 
2087 static const char * const ad1981_models[AD1981_MODELS] = {
2088 	[AD1981_AUTO]		= "auto",
2089 	[AD1981_HP]		= "hp",
2090 	[AD1981_THINKPAD]	= "thinkpad",
2091 	[AD1981_BASIC]		= "basic",
2092 	[AD1981_TOSHIBA]	= "toshiba"
2093 };
2094 
2095 static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
2096 	SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
2097 	SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
2098 	/* All HP models */
2099 	SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP),
2100 	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
2101 	/* Lenovo Thinkpad T60/X60/Z6xx */
2102 	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD),
2103 	/* HP nx6320 (reversed SSID, H/W bug) */
2104 	SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
2105 	{}
2106 };
2107 #endif /* ENABLE_AD_STATIC_QUIRKS */
2108 
2109 
2110 /* follow EAPD via vmaster hook */
2111 static void ad_vmaster_eapd_hook(void *private_data, int enabled)
2112 {
2113 	struct hda_codec *codec = private_data;
2114 	struct ad198x_spec *spec = codec->spec;
2115 
2116 	if (!spec->eapd_nid)
2117 		return;
2118 	snd_hda_codec_update_cache(codec, spec->eapd_nid, 0,
2119 				   AC_VERB_SET_EAPD_BTLENABLE,
2120 				   enabled ? 0x02 : 0x00);
2121 }
2122 
2123 static void ad1981_fixup_hp_eapd(struct hda_codec *codec,
2124 				 const struct hda_fixup *fix, int action)
2125 {
2126 	struct ad198x_spec *spec = codec->spec;
2127 
2128 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2129 		spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
2130 		spec->eapd_nid = 0x05;
2131 	}
2132 }
2133 
2134 /* set the upper-limit for mixer amp to 0dB for avoiding the possible
2135  * damage by overloading
2136  */
2137 static void ad1981_fixup_amp_override(struct hda_codec *codec,
2138 				      const struct hda_fixup *fix, int action)
2139 {
2140 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
2141 		snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2142 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2143 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2144 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2145 					  (1 << AC_AMPCAP_MUTE_SHIFT));
2146 }
2147 
2148 enum {
2149 	AD1981_FIXUP_AMP_OVERRIDE,
2150 	AD1981_FIXUP_HP_EAPD,
2151 };
2152 
2153 static const struct hda_fixup ad1981_fixups[] = {
2154 	[AD1981_FIXUP_AMP_OVERRIDE] = {
2155 		.type = HDA_FIXUP_FUNC,
2156 		.v.func = ad1981_fixup_amp_override,
2157 	},
2158 	[AD1981_FIXUP_HP_EAPD] = {
2159 		.type = HDA_FIXUP_FUNC,
2160 		.v.func = ad1981_fixup_hp_eapd,
2161 		.chained = true,
2162 		.chain_id = AD1981_FIXUP_AMP_OVERRIDE,
2163 	},
2164 };
2165 
2166 static const struct snd_pci_quirk ad1981_fixup_tbl[] = {
2167 	SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
2168 	SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD),
2169 	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
2170 	/* HP nx6320 (reversed SSID, H/W bug) */
2171 	SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD),
2172 	{}
2173 };
2174 
2175 static int ad1981_parse_auto_config(struct hda_codec *codec)
2176 {
2177 	struct ad198x_spec *spec;
2178 	int err;
2179 
2180 	err = alloc_ad_spec(codec);
2181 	if (err < 0)
2182 		return -ENOMEM;
2183 	spec = codec->spec;
2184 
2185 	spec->gen.mixer_nid = 0x0e;
2186 	spec->gen.beep_nid = 0x10;
2187 	set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
2188 
2189 	snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups);
2190 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2191 
2192 	err = ad198x_parse_auto_config(codec);
2193 	if (err < 0)
2194 		goto error;
2195 	err = ad1983_add_spdif_mux_ctl(codec);
2196 	if (err < 0)
2197 		goto error;
2198 
2199 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2200 
2201 	return 0;
2202 
2203  error:
2204 	snd_hda_gen_free(codec);
2205 	return err;
2206 }
2207 
2208 #ifdef ENABLE_AD_STATIC_QUIRKS
2209 static int patch_ad1981(struct hda_codec *codec)
2210 {
2211 	struct ad198x_spec *spec;
2212 	int err, board_config;
2213 
2214 	board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
2215 						  ad1981_models,
2216 						  ad1981_cfg_tbl);
2217 	if (board_config < 0) {
2218 		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
2219 		       codec->chip_name);
2220 		board_config = AD1981_AUTO;
2221 	}
2222 
2223 	if (board_config == AD1981_AUTO)
2224 		return ad1981_parse_auto_config(codec);
2225 
2226 	err = alloc_ad_spec(codec);
2227 	if (err < 0)
2228 		return -ENOMEM;
2229 	spec = codec->spec;
2230 
2231 	err = snd_hda_attach_beep_device(codec, 0x10);
2232 	if (err < 0) {
2233 		ad198x_free(codec);
2234 		return err;
2235 	}
2236 	set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
2237 
2238 	spec->multiout.max_channels = 2;
2239 	spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
2240 	spec->multiout.dac_nids = ad1981_dac_nids;
2241 	spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
2242 	spec->num_adc_nids = 1;
2243 	spec->adc_nids = ad1981_adc_nids;
2244 	spec->capsrc_nids = ad1981_capsrc_nids;
2245 	spec->input_mux = &ad1981_capture_source;
2246 	spec->num_mixers = 1;
2247 	spec->mixers[0] = ad1981_mixers;
2248 	spec->num_init_verbs = 1;
2249 	spec->init_verbs[0] = ad1981_init_verbs;
2250 	spec->spdif_route = 0;
2251 #ifdef CONFIG_PM
2252 	spec->loopback.amplist = ad1981_loopbacks;
2253 #endif
2254 	spec->vmaster_nid = 0x05;
2255 
2256 	codec->patch_ops = ad198x_patch_ops;
2257 
2258 	/* override some parameters */
2259 	switch (board_config) {
2260 	case AD1981_HP:
2261 		spec->mixers[0] = ad1981_hp_mixers;
2262 		spec->num_init_verbs = 2;
2263 		spec->init_verbs[1] = ad1981_hp_init_verbs;
2264 		if (!is_jack_available(codec, 0x0a))
2265 			spec->multiout.dig_out_nid = 0;
2266 		spec->input_mux = &ad1981_hp_capture_source;
2267 
2268 		codec->patch_ops.init = ad1981_hp_init;
2269 		codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2270 		/* set the upper-limit for mixer amp to 0dB for avoiding the
2271 		 * possible damage by overloading
2272 		 */
2273 		snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2274 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2275 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2276 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2277 					  (1 << AC_AMPCAP_MUTE_SHIFT));
2278 		break;
2279 	case AD1981_THINKPAD:
2280 		spec->mixers[0] = ad1981_thinkpad_mixers;
2281 		spec->input_mux = &ad1981_thinkpad_capture_source;
2282 		/* set the upper-limit for mixer amp to 0dB for avoiding the
2283 		 * possible damage by overloading
2284 		 */
2285 		snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2286 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2287 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2288 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2289 					  (1 << AC_AMPCAP_MUTE_SHIFT));
2290 		break;
2291 	case AD1981_TOSHIBA:
2292 		spec->mixers[0] = ad1981_hp_mixers;
2293 		spec->mixers[1] = ad1981_toshiba_mixers;
2294 		spec->num_init_verbs = 2;
2295 		spec->init_verbs[1] = ad1981_toshiba_init_verbs;
2296 		spec->multiout.dig_out_nid = 0;
2297 		spec->input_mux = &ad1981_hp_capture_source;
2298 		codec->patch_ops.init = ad1981_hp_init;
2299 		codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2300 		break;
2301 	}
2302 
2303 	codec->no_trigger_sense = 1;
2304 	codec->no_sticky_stream = 1;
2305 
2306 	return 0;
2307 }
2308 #else /* ENABLE_AD_STATIC_QUIRKS */
2309 #define patch_ad1981	ad1981_parse_auto_config
2310 #endif /* ENABLE_AD_STATIC_QUIRKS */
2311 
2312 
2313 /*
2314  * AD1988
2315  *
2316  * Output pins and routes
2317  *
2318  *        Pin               Mix     Sel     DAC (*)
2319  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
2320  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
2321  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
2322  * port-D 0x12 (mute/hp) <- 0x29         <- 04
2323  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
2324  * port-F 0x16 (mute)    <- 0x2a         <- 06
2325  * port-G 0x24 (mute)    <- 0x27         <- 05
2326  * port-H 0x25 (mute)    <- 0x28         <- 0a
2327  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
2328  *
2329  * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
2330  * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
2331  *
2332  * Input pins and routes
2333  *
2334  *        pin     boost   mix input # / adc input #
2335  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
2336  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
2337  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
2338  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
2339  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
2340  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
2341  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
2342  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
2343  *
2344  *
2345  * DAC assignment
2346  *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
2347  *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
2348  *
2349  * Inputs of Analog Mix (0x20)
2350  *   0:Port-B (front mic)
2351  *   1:Port-C/G/H (line-in)
2352  *   2:Port-A
2353  *   3:Port-D (line-in/2)
2354  *   4:Port-E/G/H (mic-in)
2355  *   5:Port-F (mic2-in)
2356  *   6:CD
2357  *   7:Beep
2358  *
2359  * ADC selection
2360  *   0:Port-A
2361  *   1:Port-B (front mic-in)
2362  *   2:Port-C (line-in)
2363  *   3:Port-F (mic2-in)
2364  *   4:Port-E (mic-in)
2365  *   5:CD
2366  *   6:Port-G
2367  *   7:Port-H
2368  *   8:Port-D (line-in/2)
2369  *   9:Mix
2370  *
2371  * Proposed pin assignments by the datasheet
2372  *
2373  * 6-stack
2374  * Port-A front headphone
2375  *      B front mic-in
2376  *      C rear line-in
2377  *      D rear front-out
2378  *      E rear mic-in
2379  *      F rear surround
2380  *      G rear CLFE
2381  *      H rear side
2382  *
2383  * 3-stack
2384  * Port-A front headphone
2385  *      B front mic
2386  *      C rear line-in/surround
2387  *      D rear front-out
2388  *      E rear mic-in/CLFE
2389  *
2390  * laptop
2391  * Port-A headphone
2392  *      B mic-in
2393  *      C docking station
2394  *      D internal speaker (with EAPD)
2395  *      E/F quad mic array
2396  */
2397 
2398 
2399 #ifdef ENABLE_AD_STATIC_QUIRKS
2400 /* models */
2401 enum {
2402 	AD1988_AUTO,
2403 	AD1988_6STACK,
2404 	AD1988_6STACK_DIG,
2405 	AD1988_3STACK,
2406 	AD1988_3STACK_DIG,
2407 	AD1988_LAPTOP,
2408 	AD1988_LAPTOP_DIG,
2409 	AD1988_MODEL_LAST,
2410 };
2411 
2412 /* reivision id to check workarounds */
2413 #define AD1988A_REV2		0x100200
2414 
2415 #define is_rev2(codec) \
2416 	((codec)->vendor_id == 0x11d41988 && \
2417 	 (codec)->revision_id == AD1988A_REV2)
2418 
2419 /*
2420  * mixers
2421  */
2422 
2423 static const hda_nid_t ad1988_6stack_dac_nids[4] = {
2424 	0x04, 0x06, 0x05, 0x0a
2425 };
2426 
2427 static const hda_nid_t ad1988_3stack_dac_nids[3] = {
2428 	0x04, 0x05, 0x0a
2429 };
2430 
2431 /* for AD1988A revision-2, DAC2-4 are swapped */
2432 static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2433 	0x04, 0x05, 0x0a, 0x06
2434 };
2435 
2436 static const hda_nid_t ad1988_alt_dac_nid[1] = {
2437 	0x03
2438 };
2439 
2440 static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2441 	0x04, 0x0a, 0x06
2442 };
2443 
2444 static const hda_nid_t ad1988_adc_nids[3] = {
2445 	0x08, 0x09, 0x0f
2446 };
2447 
2448 static const hda_nid_t ad1988_capsrc_nids[3] = {
2449 	0x0c, 0x0d, 0x0e
2450 };
2451 
2452 #define AD1988_SPDIF_OUT		0x02
2453 #define AD1988_SPDIF_OUT_HDMI	0x0b
2454 #define AD1988_SPDIF_IN		0x07
2455 
2456 static const hda_nid_t ad1989b_slave_dig_outs[] = {
2457 	AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2458 };
2459 
2460 static const struct hda_input_mux ad1988_6stack_capture_source = {
2461 	.num_items = 5,
2462 	.items = {
2463 		{ "Front Mic", 0x1 },	/* port-B */
2464 		{ "Line", 0x2 },	/* port-C */
2465 		{ "Mic", 0x4 },		/* port-E */
2466 		{ "CD", 0x5 },
2467 		{ "Mix", 0x9 },
2468 	},
2469 };
2470 
2471 static const struct hda_input_mux ad1988_laptop_capture_source = {
2472 	.num_items = 3,
2473 	.items = {
2474 		{ "Mic/Line", 0x1 },	/* port-B */
2475 		{ "CD", 0x5 },
2476 		{ "Mix", 0x9 },
2477 	},
2478 };
2479 
2480 /*
2481  */
2482 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
2483 			       struct snd_ctl_elem_info *uinfo)
2484 {
2485 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2486 	struct ad198x_spec *spec = codec->spec;
2487 	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
2488 				    spec->num_channel_mode);
2489 }
2490 
2491 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
2492 			      struct snd_ctl_elem_value *ucontrol)
2493 {
2494 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2495 	struct ad198x_spec *spec = codec->spec;
2496 	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
2497 				   spec->num_channel_mode, spec->multiout.max_channels);
2498 }
2499 
2500 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2501 			      struct snd_ctl_elem_value *ucontrol)
2502 {
2503 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2504 	struct ad198x_spec *spec = codec->spec;
2505 	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
2506 				      spec->num_channel_mode,
2507 				      &spec->multiout.max_channels);
2508 	if (err >= 0 && spec->need_dac_fix)
2509 		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
2510 	return err;
2511 }
2512 
2513 /* 6-stack mode */
2514 static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2515 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2516 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2517 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2518 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2519 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2520 	{ } /* end */
2521 };
2522 
2523 static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2524 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2525 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2526 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2527 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
2528 	HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2529 	{ } /* end */
2530 };
2531 
2532 static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2533 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2534 	HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2535 	HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2536 	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2537 	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2538 	HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2539 	HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2540 	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2541 
2542 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2543 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2544 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2545 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2546 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2547 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2548 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2549 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2550 
2551 	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2552 	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2553 
2554 	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2555 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2556 	{ } /* end */
2557 };
2558 
2559 /* 3-stack mode */
2560 static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2561 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2562 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2563 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2564 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2565 	{ } /* end */
2566 };
2567 
2568 static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2569 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2570 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2571 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
2572 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
2573 	{ } /* end */
2574 };
2575 
2576 static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2577 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2578 	HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2579 	HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2580 	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
2581 	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
2582 	HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2583 	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2584 
2585 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2586 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2587 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2588 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2589 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2590 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2591 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2592 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2593 
2594 	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2595 	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2596 
2597 	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2598 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2599 	{
2600 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2601 		.name = "Channel Mode",
2602 		.info = ad198x_ch_mode_info,
2603 		.get = ad198x_ch_mode_get,
2604 		.put = ad198x_ch_mode_put,
2605 	},
2606 
2607 	{ } /* end */
2608 };
2609 
2610 /* laptop mode */
2611 static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2612 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2613 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2614 	HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2615 	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2616 
2617 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2618 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2619 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2620 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2621 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2622 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2623 
2624 	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2625 	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2626 
2627 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2628 
2629 	{
2630 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2631 		.name = "External Amplifier",
2632 		.subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2633 		.info = ad198x_eapd_info,
2634 		.get = ad198x_eapd_get,
2635 		.put = ad198x_eapd_put,
2636 		.private_value = 0x12, /* port-D */
2637 	},
2638 
2639 	{ } /* end */
2640 };
2641 
2642 /* capture */
2643 static const struct snd_kcontrol_new ad1988_capture_mixers[] = {
2644 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2645 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2646 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2647 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2648 	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2649 	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2650 	{
2651 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2652 		/* The multiple "Capture Source" controls confuse alsamixer
2653 		 * So call somewhat different..
2654 		 */
2655 		/* .name = "Capture Source", */
2656 		.name = "Input Source",
2657 		.count = 3,
2658 		.info = ad198x_mux_enum_info,
2659 		.get = ad198x_mux_enum_get,
2660 		.put = ad198x_mux_enum_put,
2661 	},
2662 	{ } /* end */
2663 };
2664 
2665 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2666 					     struct snd_ctl_elem_info *uinfo)
2667 {
2668 	static const char * const texts[] = {
2669 		"PCM", "ADC1", "ADC2", "ADC3"
2670 	};
2671 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2672 	uinfo->count = 1;
2673 	uinfo->value.enumerated.items = 4;
2674 	if (uinfo->value.enumerated.item >= 4)
2675 		uinfo->value.enumerated.item = 3;
2676 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2677 	return 0;
2678 }
2679 
2680 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2681 					    struct snd_ctl_elem_value *ucontrol)
2682 {
2683 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2684 	unsigned int sel;
2685 
2686 	sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2687 				 AC_AMP_GET_INPUT);
2688 	if (!(sel & 0x80))
2689 		ucontrol->value.enumerated.item[0] = 0;
2690 	else {
2691 		sel = snd_hda_codec_read(codec, 0x0b, 0,
2692 					 AC_VERB_GET_CONNECT_SEL, 0);
2693 		if (sel < 3)
2694 			sel++;
2695 		else
2696 			sel = 0;
2697 		ucontrol->value.enumerated.item[0] = sel;
2698 	}
2699 	return 0;
2700 }
2701 
2702 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2703 					    struct snd_ctl_elem_value *ucontrol)
2704 {
2705 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2706 	unsigned int val, sel;
2707 	int change;
2708 
2709 	val = ucontrol->value.enumerated.item[0];
2710 	if (val > 3)
2711 		return -EINVAL;
2712 	if (!val) {
2713 		sel = snd_hda_codec_read(codec, 0x1d, 0,
2714 					 AC_VERB_GET_AMP_GAIN_MUTE,
2715 					 AC_AMP_GET_INPUT);
2716 		change = sel & 0x80;
2717 		if (change) {
2718 			snd_hda_codec_write_cache(codec, 0x1d, 0,
2719 						  AC_VERB_SET_AMP_GAIN_MUTE,
2720 						  AMP_IN_UNMUTE(0));
2721 			snd_hda_codec_write_cache(codec, 0x1d, 0,
2722 						  AC_VERB_SET_AMP_GAIN_MUTE,
2723 						  AMP_IN_MUTE(1));
2724 		}
2725 	} else {
2726 		sel = snd_hda_codec_read(codec, 0x1d, 0,
2727 					 AC_VERB_GET_AMP_GAIN_MUTE,
2728 					 AC_AMP_GET_INPUT | 0x01);
2729 		change = sel & 0x80;
2730 		if (change) {
2731 			snd_hda_codec_write_cache(codec, 0x1d, 0,
2732 						  AC_VERB_SET_AMP_GAIN_MUTE,
2733 						  AMP_IN_MUTE(0));
2734 			snd_hda_codec_write_cache(codec, 0x1d, 0,
2735 						  AC_VERB_SET_AMP_GAIN_MUTE,
2736 						  AMP_IN_UNMUTE(1));
2737 		}
2738 		sel = snd_hda_codec_read(codec, 0x0b, 0,
2739 					 AC_VERB_GET_CONNECT_SEL, 0) + 1;
2740 		change |= sel != val;
2741 		if (change)
2742 			snd_hda_codec_write_cache(codec, 0x0b, 0,
2743 						  AC_VERB_SET_CONNECT_SEL,
2744 						  val - 1);
2745 	}
2746 	return change;
2747 }
2748 
2749 static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2750 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2751 	{
2752 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2753 		.name = "IEC958 Playback Source",
2754 		.subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2755 		.info = ad1988_spdif_playback_source_info,
2756 		.get = ad1988_spdif_playback_source_get,
2757 		.put = ad1988_spdif_playback_source_put,
2758 	},
2759 	{ } /* end */
2760 };
2761 
2762 static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2763 	HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2764 	{ } /* end */
2765 };
2766 
2767 static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2768 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2769 	HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2770 	{ } /* end */
2771 };
2772 
2773 /*
2774  * initialization verbs
2775  */
2776 
2777 /*
2778  * for 6-stack (+dig)
2779  */
2780 static const struct hda_verb ad1988_6stack_init_verbs[] = {
2781 	/* Front, Surround, CLFE, side DAC; unmute as default */
2782 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2783 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2784 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2785 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2786 	/* Port-A front headphon path */
2787 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2788 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2789 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2790 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2791 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2792 	/* Port-D line-out path */
2793 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2794 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2795 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2797 	/* Port-F surround path */
2798 	{0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2799 	{0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2800 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2801 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2802 	/* Port-G CLFE path */
2803 	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2804 	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2805 	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2806 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2807 	/* Port-H side path */
2808 	{0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2809 	{0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2810 	{0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2811 	{0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2812 	/* Mono out path */
2813 	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2814 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2815 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2816 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2817 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2818 	/* Port-B front mic-in path */
2819 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2820 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2821 	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2822 	/* Port-C line-in path */
2823 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2824 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2825 	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2826 	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2827 	/* Port-E mic-in path */
2828 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2829 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2830 	{0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2831 	{0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2832 	/* Analog CD Input */
2833 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2834 	/* Analog Mix output amp */
2835 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2836 
2837 	{ }
2838 };
2839 
2840 static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2841 	/* Headphone; unmute as default */
2842 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2843 	/* Port-A front headphon path */
2844 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2845 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2846 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2847 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2848 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2849 
2850 	{ }
2851 };
2852 
2853 static const struct hda_verb ad1988_capture_init_verbs[] = {
2854 	/* mute analog mix */
2855 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2856 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2857 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2858 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2859 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2860 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2861 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2862 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2863 	/* select ADCs - front-mic */
2864 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2865 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2866 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2867 
2868 	{ }
2869 };
2870 
2871 static const struct hda_verb ad1988_spdif_init_verbs[] = {
2872 	/* SPDIF out sel */
2873 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2874 	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2875 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2876 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2877 	/* SPDIF out pin */
2878 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2879 
2880 	{ }
2881 };
2882 
2883 static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
2884 	/* unmute SPDIF input pin */
2885 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2886 	{ }
2887 };
2888 
2889 /* AD1989 has no ADC -> SPDIF route */
2890 static const struct hda_verb ad1989_spdif_init_verbs[] = {
2891 	/* SPDIF-1 out pin */
2892 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2893 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2894 	/* SPDIF-2/HDMI out pin */
2895 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2896 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2897 	{ }
2898 };
2899 
2900 /*
2901  * verbs for 3stack (+dig)
2902  */
2903 static const struct hda_verb ad1988_3stack_ch2_init[] = {
2904 	/* set port-C to line-in */
2905 	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2906 	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2907 	/* set port-E to mic-in */
2908 	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2909 	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2910 	{ } /* end */
2911 };
2912 
2913 static const struct hda_verb ad1988_3stack_ch6_init[] = {
2914 	/* set port-C to surround out */
2915 	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2916 	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2917 	/* set port-E to CLFE out */
2918 	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2919 	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2920 	{ } /* end */
2921 };
2922 
2923 static const struct hda_channel_mode ad1988_3stack_modes[2] = {
2924 	{ 2, ad1988_3stack_ch2_init },
2925 	{ 6, ad1988_3stack_ch6_init },
2926 };
2927 
2928 static const struct hda_verb ad1988_3stack_init_verbs[] = {
2929 	/* Front, Surround, CLFE, side DAC; unmute as default */
2930 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2931 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2932 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2933 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2934 	/* Port-A front headphon path */
2935 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2936 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2937 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2938 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2939 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2940 	/* Port-D line-out path */
2941 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2942 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2943 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2944 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2945 	/* Mono out path */
2946 	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2947 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2948 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2949 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2950 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2951 	/* Port-B front mic-in path */
2952 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2953 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2954 	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2955 	/* Port-C line-in/surround path - 6ch mode as default */
2956 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2957 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2958 	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2959 	{0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2960 	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2961 	/* Port-E mic-in/CLFE path - 6ch mode as default */
2962 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2963 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2964 	{0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2965 	{0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2966 	{0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2967 	/* mute analog mix */
2968 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2969 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2970 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2971 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2972 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2973 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2974 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2975 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2976 	/* select ADCs - front-mic */
2977 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2978 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2979 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2980 	/* Analog Mix output amp */
2981 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2982 	{ }
2983 };
2984 
2985 /*
2986  * verbs for laptop mode (+dig)
2987  */
2988 static const struct hda_verb ad1988_laptop_hp_on[] = {
2989 	/* unmute port-A and mute port-D */
2990 	{ 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2991 	{ 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2992 	{ } /* end */
2993 };
2994 static const struct hda_verb ad1988_laptop_hp_off[] = {
2995 	/* mute port-A and unmute port-D */
2996 	{ 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2997 	{ 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2998 	{ } /* end */
2999 };
3000 
3001 #define AD1988_HP_EVENT	0x01
3002 
3003 static const struct hda_verb ad1988_laptop_init_verbs[] = {
3004 	/* Front, Surround, CLFE, side DAC; unmute as default */
3005 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3006 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3007 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3008 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3009 	/* Port-A front headphon path */
3010 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
3011 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3012 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3013 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3014 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3015 	/* unsolicited event for pin-sense */
3016 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
3017 	/* Port-D line-out path + EAPD */
3018 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3019 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3020 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3021 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3022 	{0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
3023 	/* Mono out path */
3024 	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
3025 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3026 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3027 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3028 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
3029 	/* Port-B mic-in path */
3030 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3031 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3032 	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3033 	/* Port-C docking station - try to output */
3034 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3035 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3036 	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3037 	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
3038 	/* mute analog mix */
3039 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3040 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3041 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3042 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3043 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3044 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3045 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3046 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3047 	/* select ADCs - mic */
3048 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
3049 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
3050 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3051 	/* Analog Mix output amp */
3052 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3053 	{ }
3054 };
3055 
3056 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
3057 {
3058 	if ((res >> 26) != AD1988_HP_EVENT)
3059 		return;
3060 	if (snd_hda_jack_detect(codec, 0x11))
3061 		snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
3062 	else
3063 		snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
3064 }
3065 
3066 #ifdef CONFIG_PM
3067 static const struct hda_amp_list ad1988_loopbacks[] = {
3068 	{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
3069 	{ 0x20, HDA_INPUT, 1 }, /* Line */
3070 	{ 0x20, HDA_INPUT, 4 }, /* Mic */
3071 	{ 0x20, HDA_INPUT, 6 }, /* CD */
3072 	{ } /* end */
3073 };
3074 #endif
3075 #endif /* ENABLE_AD_STATIC_QUIRKS */
3076 
3077 static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
3078 				      struct snd_ctl_elem_info *uinfo)
3079 {
3080 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3081 	static const char * const texts[] = {
3082 		"PCM", "ADC1", "ADC2", "ADC3",
3083 	};
3084 	int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
3085 	if (num_conns > 4)
3086 		num_conns = 4;
3087 	return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts);
3088 }
3089 
3090 static int ad1988_auto_smux_enum_get(struct snd_kcontrol *kcontrol,
3091 				     struct snd_ctl_elem_value *ucontrol)
3092 {
3093 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3094 	struct ad198x_spec *spec = codec->spec;
3095 
3096 	ucontrol->value.enumerated.item[0] = spec->cur_smux;
3097 	return 0;
3098 }
3099 
3100 static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
3101 				     struct snd_ctl_elem_value *ucontrol)
3102 {
3103 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3104 	struct ad198x_spec *spec = codec->spec;
3105 	unsigned int val = ucontrol->value.enumerated.item[0];
3106 	struct nid_path *path;
3107 	int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
3108 
3109 	if (val >= num_conns)
3110 		return -EINVAL;
3111 	if (spec->cur_smux == val)
3112 		return 0;
3113 
3114 	mutex_lock(&codec->control_mutex);
3115 	codec->cached_write = 1;
3116 	path = snd_hda_get_path_from_idx(codec,
3117 					 spec->smux_paths[spec->cur_smux]);
3118 	if (path)
3119 		snd_hda_activate_path(codec, path, false, true);
3120 	path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]);
3121 	if (path)
3122 		snd_hda_activate_path(codec, path, true, true);
3123 	spec->cur_smux = val;
3124 	codec->cached_write = 0;
3125 	mutex_unlock(&codec->control_mutex);
3126 	snd_hda_codec_flush_cache(codec); /* flush the updates */
3127 	return 1;
3128 }
3129 
3130 static struct snd_kcontrol_new ad1988_auto_smux_mixer = {
3131 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3132 	.name = "IEC958 Playback Source",
3133 	.info = ad1988_auto_smux_enum_info,
3134 	.get = ad1988_auto_smux_enum_get,
3135 	.put = ad1988_auto_smux_enum_put,
3136 };
3137 
3138 static int ad1988_auto_init(struct hda_codec *codec)
3139 {
3140 	struct ad198x_spec *spec = codec->spec;
3141 	int i, err;
3142 
3143 	err = snd_hda_gen_init(codec);
3144 	if (err < 0)
3145 		return err;
3146 	if (!spec->gen.autocfg.dig_outs)
3147 		return 0;
3148 
3149 	for (i = 0; i < 4; i++) {
3150 		struct nid_path *path;
3151 		path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]);
3152 		if (path)
3153 			snd_hda_activate_path(codec, path, path->active, false);
3154 	}
3155 
3156 	return 0;
3157 }
3158 
3159 static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec)
3160 {
3161 	struct ad198x_spec *spec = codec->spec;
3162 	int i, num_conns;
3163 	/* we create four static faked paths, since AD codecs have odd
3164 	 * widget connections regarding the SPDIF out source
3165 	 */
3166 	static struct nid_path fake_paths[4] = {
3167 		{
3168 			.depth = 3,
3169 			.path = { 0x02, 0x1d, 0x1b },
3170 			.idx = { 0, 0, 0 },
3171 			.multi = { 0, 0, 0 },
3172 		},
3173 		{
3174 			.depth = 4,
3175 			.path = { 0x08, 0x0b, 0x1d, 0x1b },
3176 			.idx = { 0, 0, 1, 0 },
3177 			.multi = { 0, 1, 0, 0 },
3178 		},
3179 		{
3180 			.depth = 4,
3181 			.path = { 0x09, 0x0b, 0x1d, 0x1b },
3182 			.idx = { 0, 1, 1, 0 },
3183 			.multi = { 0, 1, 0, 0 },
3184 		},
3185 		{
3186 			.depth = 4,
3187 			.path = { 0x0f, 0x0b, 0x1d, 0x1b },
3188 			.idx = { 0, 2, 1, 0 },
3189 			.multi = { 0, 1, 0, 0 },
3190 		},
3191 	};
3192 
3193 	/* SPDIF source mux appears to be present only on AD1988A */
3194 	if (!spec->gen.autocfg.dig_outs ||
3195 	    get_wcaps_type(get_wcaps(codec, 0x1d)) != AC_WID_AUD_MIX)
3196 		return 0;
3197 
3198 	num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
3199 	if (num_conns != 3 && num_conns != 4)
3200 		return 0;
3201 
3202 	for (i = 0; i < num_conns; i++) {
3203 		struct nid_path *path = snd_array_new(&spec->gen.paths);
3204 		if (!path)
3205 			return -ENOMEM;
3206 		*path = fake_paths[i];
3207 		if (!i)
3208 			path->active = 1;
3209 		spec->smux_paths[i] = snd_hda_get_path_idx(codec, path);
3210 	}
3211 
3212 	if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer))
3213 		return -ENOMEM;
3214 
3215 	codec->patch_ops.init = ad1988_auto_init;
3216 
3217 	return 0;
3218 }
3219 
3220 /*
3221  */
3222 
3223 static int ad1988_parse_auto_config(struct hda_codec *codec)
3224 {
3225 	struct ad198x_spec *spec;
3226 	int err;
3227 
3228 	err = alloc_ad_spec(codec);
3229 	if (err < 0)
3230 		return err;
3231 	spec = codec->spec;
3232 
3233 	spec->gen.mixer_nid = 0x20;
3234 	spec->gen.mixer_merge_nid = 0x21;
3235 	spec->gen.beep_nid = 0x10;
3236 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3237 	err = ad198x_parse_auto_config(codec);
3238 	if (err < 0)
3239 		goto error;
3240 	err = ad1988_add_spdif_mux_ctl(codec);
3241 	if (err < 0)
3242 		goto error;
3243 	return 0;
3244 
3245  error:
3246 	snd_hda_gen_free(codec);
3247 	return err;
3248 }
3249 
3250 /*
3251  */
3252 
3253 #ifdef ENABLE_AD_STATIC_QUIRKS
3254 static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3255 	[AD1988_6STACK]		= "6stack",
3256 	[AD1988_6STACK_DIG]	= "6stack-dig",
3257 	[AD1988_3STACK]		= "3stack",
3258 	[AD1988_3STACK_DIG]	= "3stack-dig",
3259 	[AD1988_LAPTOP]		= "laptop",
3260 	[AD1988_LAPTOP_DIG]	= "laptop-dig",
3261 	[AD1988_AUTO]		= "auto",
3262 };
3263 
3264 static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
3265 	SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3266 	SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3267 	SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3268 	SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG),
3269 	SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3270 	{}
3271 };
3272 
3273 static int patch_ad1988(struct hda_codec *codec)
3274 {
3275 	struct ad198x_spec *spec;
3276 	int err, board_config;
3277 
3278 	board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3279 						  ad1988_models, ad1988_cfg_tbl);
3280 	if (board_config < 0) {
3281 		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3282 		       codec->chip_name);
3283 		board_config = AD1988_AUTO;
3284 	}
3285 
3286 	if (board_config == AD1988_AUTO)
3287 		return ad1988_parse_auto_config(codec);
3288 
3289 	err = alloc_ad_spec(codec);
3290 	if (err < 0)
3291 		return err;
3292 	spec = codec->spec;
3293 
3294 	if (is_rev2(codec))
3295 		snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3296 
3297 	err = snd_hda_attach_beep_device(codec, 0x10);
3298 	if (err < 0) {
3299 		ad198x_free(codec);
3300 		return err;
3301 	}
3302 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3303 
3304 	if (!spec->multiout.hp_nid)
3305 		spec->multiout.hp_nid = ad1988_alt_dac_nid[0];
3306 	switch (board_config) {
3307 	case AD1988_6STACK:
3308 	case AD1988_6STACK_DIG:
3309 		spec->multiout.max_channels = 8;
3310 		spec->multiout.num_dacs = 4;
3311 		if (is_rev2(codec))
3312 			spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3313 		else
3314 			spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3315 		spec->input_mux = &ad1988_6stack_capture_source;
3316 		spec->num_mixers = 2;
3317 		if (is_rev2(codec))
3318 			spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3319 		else
3320 			spec->mixers[0] = ad1988_6stack_mixers1;
3321 		spec->mixers[1] = ad1988_6stack_mixers2;
3322 		spec->num_init_verbs = 1;
3323 		spec->init_verbs[0] = ad1988_6stack_init_verbs;
3324 		if (board_config == AD1988_6STACK_DIG) {
3325 			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3326 			spec->dig_in_nid = AD1988_SPDIF_IN;
3327 		}
3328 		break;
3329 	case AD1988_3STACK:
3330 	case AD1988_3STACK_DIG:
3331 		spec->multiout.max_channels = 6;
3332 		spec->multiout.num_dacs = 3;
3333 		if (is_rev2(codec))
3334 			spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3335 		else
3336 			spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3337 		spec->input_mux = &ad1988_6stack_capture_source;
3338 		spec->channel_mode = ad1988_3stack_modes;
3339 		spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3340 		spec->num_mixers = 2;
3341 		if (is_rev2(codec))
3342 			spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3343 		else
3344 			spec->mixers[0] = ad1988_3stack_mixers1;
3345 		spec->mixers[1] = ad1988_3stack_mixers2;
3346 		spec->num_init_verbs = 1;
3347 		spec->init_verbs[0] = ad1988_3stack_init_verbs;
3348 		if (board_config == AD1988_3STACK_DIG)
3349 			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3350 		break;
3351 	case AD1988_LAPTOP:
3352 	case AD1988_LAPTOP_DIG:
3353 		spec->multiout.max_channels = 2;
3354 		spec->multiout.num_dacs = 1;
3355 		spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3356 		spec->input_mux = &ad1988_laptop_capture_source;
3357 		spec->num_mixers = 1;
3358 		spec->mixers[0] = ad1988_laptop_mixers;
3359 		codec->inv_eapd = 1; /* inverted EAPD */
3360 		spec->num_init_verbs = 1;
3361 		spec->init_verbs[0] = ad1988_laptop_init_verbs;
3362 		if (board_config == AD1988_LAPTOP_DIG)
3363 			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3364 		break;
3365 	}
3366 
3367 	spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3368 	spec->adc_nids = ad1988_adc_nids;
3369 	spec->capsrc_nids = ad1988_capsrc_nids;
3370 	spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3371 	spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3372 	if (spec->multiout.dig_out_nid) {
3373 		if (codec->vendor_id >= 0x11d4989a) {
3374 			spec->mixers[spec->num_mixers++] =
3375 				ad1989_spdif_out_mixers;
3376 			spec->init_verbs[spec->num_init_verbs++] =
3377 				ad1989_spdif_init_verbs;
3378 			codec->slave_dig_outs = ad1989b_slave_dig_outs;
3379 		} else {
3380 			spec->mixers[spec->num_mixers++] =
3381 				ad1988_spdif_out_mixers;
3382 			spec->init_verbs[spec->num_init_verbs++] =
3383 				ad1988_spdif_init_verbs;
3384 		}
3385 	}
3386 	if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3387 		spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3388 		spec->init_verbs[spec->num_init_verbs++] =
3389 			ad1988_spdif_in_init_verbs;
3390 	}
3391 
3392 	codec->patch_ops = ad198x_patch_ops;
3393 	switch (board_config) {
3394 	case AD1988_LAPTOP:
3395 	case AD1988_LAPTOP_DIG:
3396 		codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3397 		break;
3398 	}
3399 #ifdef CONFIG_PM
3400 	spec->loopback.amplist = ad1988_loopbacks;
3401 #endif
3402 	spec->vmaster_nid = 0x04;
3403 
3404 	codec->no_trigger_sense = 1;
3405 	codec->no_sticky_stream = 1;
3406 
3407 	return 0;
3408 }
3409 #else /* ENABLE_AD_STATIC_QUIRKS */
3410 #define patch_ad1988	ad1988_parse_auto_config
3411 #endif /* ENABLE_AD_STATIC_QUIRKS */
3412 
3413 
3414 /*
3415  * AD1884 / AD1984
3416  *
3417  * port-B - front line/mic-in
3418  * port-E - aux in/out
3419  * port-F - aux in/out
3420  * port-C - rear line/mic-in
3421  * port-D - rear line/hp-out
3422  * port-A - front line/hp-out
3423  *
3424  * AD1984 = AD1884 + two digital mic-ins
3425  *
3426  * FIXME:
3427  * For simplicity, we share the single DAC for both HP and line-outs
3428  * right now.  The inidividual playbacks could be easily implemented,
3429  * but no build-up framework is given, so far.
3430  */
3431 
3432 #ifdef ENABLE_AD_STATIC_QUIRKS
3433 static const hda_nid_t ad1884_dac_nids[1] = {
3434 	0x04,
3435 };
3436 
3437 static const hda_nid_t ad1884_adc_nids[2] = {
3438 	0x08, 0x09,
3439 };
3440 
3441 static const hda_nid_t ad1884_capsrc_nids[2] = {
3442 	0x0c, 0x0d,
3443 };
3444 
3445 #define AD1884_SPDIF_OUT	0x02
3446 
3447 static const struct hda_input_mux ad1884_capture_source = {
3448 	.num_items = 4,
3449 	.items = {
3450 		{ "Front Mic", 0x0 },
3451 		{ "Mic", 0x1 },
3452 		{ "CD", 0x2 },
3453 		{ "Mix", 0x3 },
3454 	},
3455 };
3456 
3457 static const struct snd_kcontrol_new ad1884_base_mixers[] = {
3458 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3459 	/* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3460 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3461 	HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3462 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3463 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3464 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3465 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3466 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3467 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3468 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3469 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3470 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3471 	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3472 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3473 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3474 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3475 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3476 	{
3477 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3478 		/* The multiple "Capture Source" controls confuse alsamixer
3479 		 * So call somewhat different..
3480 		 */
3481 		/* .name = "Capture Source", */
3482 		.name = "Input Source",
3483 		.count = 2,
3484 		.info = ad198x_mux_enum_info,
3485 		.get = ad198x_mux_enum_get,
3486 		.put = ad198x_mux_enum_put,
3487 	},
3488 	/* SPDIF controls */
3489 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3490 	{
3491 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3492 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3493 		/* identical with ad1983 */
3494 		.info = ad1983_spdif_route_info,
3495 		.get = ad1983_spdif_route_get,
3496 		.put = ad1983_spdif_route_put,
3497 	},
3498 	{ } /* end */
3499 };
3500 
3501 static const struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3502 	HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3503 	HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3504 	HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3505 			     HDA_INPUT),
3506 	HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3507 			   HDA_INPUT),
3508 	{ } /* end */
3509 };
3510 
3511 /*
3512  * initialization verbs
3513  */
3514 static const struct hda_verb ad1884_init_verbs[] = {
3515 	/* DACs; mute as default */
3516 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3517 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3518 	/* Port-A (HP) mixer */
3519 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3520 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3521 	/* Port-A pin */
3522 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3523 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3524 	/* HP selector - select DAC2 */
3525 	{0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3526 	/* Port-D (Line-out) mixer */
3527 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3528 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3529 	/* Port-D pin */
3530 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3531 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3532 	/* Mono-out mixer */
3533 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3534 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3535 	/* Mono-out pin */
3536 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3537 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3538 	/* Mono selector */
3539 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3540 	/* Port-B (front mic) pin */
3541 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3542 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3543 	/* Port-C (rear mic) pin */
3544 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3545 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3546 	/* Analog mixer; mute as default */
3547 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3548 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3549 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3550 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3551 	/* Analog Mix output amp */
3552 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3553 	/* SPDIF output selector */
3554 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3555 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3556 	{ } /* end */
3557 };
3558 
3559 #ifdef CONFIG_PM
3560 static const struct hda_amp_list ad1884_loopbacks[] = {
3561 	{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
3562 	{ 0x20, HDA_INPUT, 1 }, /* Mic */
3563 	{ 0x20, HDA_INPUT, 2 }, /* CD */
3564 	{ 0x20, HDA_INPUT, 4 }, /* Docking */
3565 	{ } /* end */
3566 };
3567 #endif
3568 
3569 static const char * const ad1884_slave_vols[] = {
3570 	"PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
3571 	"Internal Mic", "Dock Mic", /* "Beep", */ "IEC958",
3572 	NULL
3573 };
3574 
3575 enum {
3576 	AD1884_AUTO,
3577 	AD1884_BASIC,
3578 	AD1884_MODELS
3579 };
3580 
3581 static const char * const ad1884_models[AD1884_MODELS] = {
3582 	[AD1884_AUTO]		= "auto",
3583 	[AD1884_BASIC]		= "basic",
3584 };
3585 #endif /* ENABLE_AD_STATIC_QUIRKS */
3586 
3587 
3588 /* set the upper-limit for mixer amp to 0dB for avoiding the possible
3589  * damage by overloading
3590  */
3591 static void ad1884_fixup_amp_override(struct hda_codec *codec,
3592 				      const struct hda_fixup *fix, int action)
3593 {
3594 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
3595 		snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
3596 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
3597 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3598 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3599 					  (1 << AC_AMPCAP_MUTE_SHIFT));
3600 }
3601 
3602 static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
3603 				 const struct hda_fixup *fix, int action)
3604 {
3605 	struct ad198x_spec *spec = codec->spec;
3606 
3607 	switch (action) {
3608 	case HDA_FIXUP_ACT_PRE_PROBE:
3609 		spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
3610 		break;
3611 	case HDA_FIXUP_ACT_PROBE:
3612 		if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
3613 			spec->eapd_nid = spec->gen.autocfg.line_out_pins[0];
3614 		else
3615 			spec->eapd_nid = spec->gen.autocfg.speaker_pins[0];
3616 		break;
3617 	}
3618 }
3619 
3620 enum {
3621 	AD1884_FIXUP_AMP_OVERRIDE,
3622 	AD1884_FIXUP_HP_EAPD,
3623 };
3624 
3625 static const struct hda_fixup ad1884_fixups[] = {
3626 	[AD1884_FIXUP_AMP_OVERRIDE] = {
3627 		.type = HDA_FIXUP_FUNC,
3628 		.v.func = ad1884_fixup_amp_override,
3629 	},
3630 	[AD1884_FIXUP_HP_EAPD] = {
3631 		.type = HDA_FIXUP_FUNC,
3632 		.v.func = ad1884_fixup_hp_eapd,
3633 		.chained = true,
3634 		.chain_id = AD1884_FIXUP_AMP_OVERRIDE,
3635 	},
3636 };
3637 
3638 static const struct snd_pci_quirk ad1884_fixup_tbl[] = {
3639 	SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD),
3640 	{}
3641 };
3642 
3643 
3644 static int ad1884_parse_auto_config(struct hda_codec *codec)
3645 {
3646 	struct ad198x_spec *spec;
3647 	int err;
3648 
3649 	err = alloc_ad_spec(codec);
3650 	if (err < 0)
3651 		return err;
3652 	spec = codec->spec;
3653 
3654 	spec->gen.mixer_nid = 0x20;
3655 	spec->gen.beep_nid = 0x10;
3656 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3657 
3658 	snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups);
3659 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3660 
3661 	err = ad198x_parse_auto_config(codec);
3662 	if (err < 0)
3663 		goto error;
3664 	err = ad1983_add_spdif_mux_ctl(codec);
3665 	if (err < 0)
3666 		goto error;
3667 
3668 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3669 
3670 	return 0;
3671 
3672  error:
3673 	snd_hda_gen_free(codec);
3674 	return err;
3675 }
3676 
3677 #ifdef ENABLE_AD_STATIC_QUIRKS
3678 static int patch_ad1884_basic(struct hda_codec *codec)
3679 {
3680 	struct ad198x_spec *spec;
3681 	int err;
3682 
3683 	err = alloc_ad_spec(codec);
3684 	if (err < 0)
3685 		return err;
3686 	spec = codec->spec;
3687 
3688 	err = snd_hda_attach_beep_device(codec, 0x10);
3689 	if (err < 0) {
3690 		ad198x_free(codec);
3691 		return err;
3692 	}
3693 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3694 
3695 	spec->multiout.max_channels = 2;
3696 	spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3697 	spec->multiout.dac_nids = ad1884_dac_nids;
3698 	spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3699 	spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3700 	spec->adc_nids = ad1884_adc_nids;
3701 	spec->capsrc_nids = ad1884_capsrc_nids;
3702 	spec->input_mux = &ad1884_capture_source;
3703 	spec->num_mixers = 1;
3704 	spec->mixers[0] = ad1884_base_mixers;
3705 	spec->num_init_verbs = 1;
3706 	spec->init_verbs[0] = ad1884_init_verbs;
3707 	spec->spdif_route = 0;
3708 #ifdef CONFIG_PM
3709 	spec->loopback.amplist = ad1884_loopbacks;
3710 #endif
3711 	spec->vmaster_nid = 0x04;
3712 	/* we need to cover all playback volumes */
3713 	spec->slave_vols = ad1884_slave_vols;
3714 	/* slaves may contain input volumes, so we can't raise to 0dB blindly */
3715 	spec->avoid_init_slave_vol = 1;
3716 
3717 	codec->patch_ops = ad198x_patch_ops;
3718 
3719 	codec->no_trigger_sense = 1;
3720 	codec->no_sticky_stream = 1;
3721 
3722 	return 0;
3723 }
3724 
3725 static int patch_ad1884(struct hda_codec *codec)
3726 {
3727 	int board_config;
3728 
3729 	board_config = snd_hda_check_board_config(codec, AD1884_MODELS,
3730 						  ad1884_models, NULL);
3731 	if (board_config < 0) {
3732 		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3733 		       codec->chip_name);
3734 		board_config = AD1884_AUTO;
3735 	}
3736 
3737 	if (board_config == AD1884_AUTO)
3738 		return ad1884_parse_auto_config(codec);
3739 	else
3740 		return patch_ad1884_basic(codec);
3741 }
3742 #else /* ENABLE_AD_STATIC_QUIRKS */
3743 #define patch_ad1884	ad1884_parse_auto_config
3744 #endif /* ENABLE_AD_STATIC_QUIRKS */
3745 
3746 
3747 #ifdef ENABLE_AD_STATIC_QUIRKS
3748 /*
3749  * Lenovo Thinkpad T61/X61
3750  */
3751 static const struct hda_input_mux ad1984_thinkpad_capture_source = {
3752 	.num_items = 4,
3753 	.items = {
3754 		{ "Mic", 0x0 },
3755 		{ "Internal Mic", 0x1 },
3756 		{ "Mix", 0x3 },
3757 		{ "Dock Mic", 0x4 },
3758 	},
3759 };
3760 
3761 
3762 /*
3763  * Dell Precision T3400
3764  */
3765 static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
3766 	.num_items = 3,
3767 	.items = {
3768 		{ "Front Mic", 0x0 },
3769 		{ "Line-In", 0x1 },
3770 		{ "Mix", 0x3 },
3771 	},
3772 };
3773 
3774 
3775 static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3776 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3777 	/* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3778 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3779 	HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3780 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3781 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3782 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3783 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3784 	HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3785 	HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3786 	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3787 	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3788 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3789 	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3790 	HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3791 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3792 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3793 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3794 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3795 	{
3796 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3797 		/* The multiple "Capture Source" controls confuse alsamixer
3798 		 * So call somewhat different..
3799 		 */
3800 		/* .name = "Capture Source", */
3801 		.name = "Input Source",
3802 		.count = 2,
3803 		.info = ad198x_mux_enum_info,
3804 		.get = ad198x_mux_enum_get,
3805 		.put = ad198x_mux_enum_put,
3806 	},
3807 	/* SPDIF controls */
3808 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3809 	{
3810 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3811 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3812 		/* identical with ad1983 */
3813 		.info = ad1983_spdif_route_info,
3814 		.get = ad1983_spdif_route_get,
3815 		.put = ad1983_spdif_route_put,
3816 	},
3817 	{ } /* end */
3818 };
3819 
3820 /* additional verbs */
3821 static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
3822 	/* Port-E (docking station mic) pin */
3823 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3824 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3825 	/* docking mic boost */
3826 	{0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3827 	/* Analog PC Beeper - allow firmware/ACPI beeps */
3828 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3829 	/* Analog mixer - docking mic; mute as default */
3830 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3831 	/* enable EAPD bit */
3832 	{0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3833 	{ } /* end */
3834 };
3835 
3836 /*
3837  * Dell Precision T3400
3838  */
3839 static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3840 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3841 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3842 	HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3843 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3844 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3845 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3846 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3847 	HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3848 	HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3849 	HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3850 	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3851 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3852 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3853 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3854 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3855 	{
3856 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3857 		/* The multiple "Capture Source" controls confuse alsamixer
3858 		 * So call somewhat different..
3859 		 */
3860 		/* .name = "Capture Source", */
3861 		.name = "Input Source",
3862 		.count = 2,
3863 		.info = ad198x_mux_enum_info,
3864 		.get = ad198x_mux_enum_get,
3865 		.put = ad198x_mux_enum_put,
3866 	},
3867 	{ } /* end */
3868 };
3869 
3870 /* Digial MIC ADC NID 0x05 + 0x06 */
3871 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3872 				   struct hda_codec *codec,
3873 				   unsigned int stream_tag,
3874 				   unsigned int format,
3875 				   struct snd_pcm_substream *substream)
3876 {
3877 	snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3878 				   stream_tag, 0, format);
3879 	return 0;
3880 }
3881 
3882 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3883 				   struct hda_codec *codec,
3884 				   struct snd_pcm_substream *substream)
3885 {
3886 	snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3887 	return 0;
3888 }
3889 
3890 static const struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3891 	.substreams = 2,
3892 	.channels_min = 2,
3893 	.channels_max = 2,
3894 	.nid = 0x05,
3895 	.ops = {
3896 		.prepare = ad1984_pcm_dmic_prepare,
3897 		.cleanup = ad1984_pcm_dmic_cleanup
3898 	},
3899 };
3900 
3901 static int ad1984_build_pcms(struct hda_codec *codec)
3902 {
3903 	struct ad198x_spec *spec = codec->spec;
3904 	struct hda_pcm *info;
3905 	int err;
3906 
3907 	err = ad198x_build_pcms(codec);
3908 	if (err < 0)
3909 		return err;
3910 
3911 	info = spec->pcm_rec + codec->num_pcms;
3912 	codec->num_pcms++;
3913 	info->name = "AD1984 Digital Mic";
3914 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3915 	return 0;
3916 }
3917 
3918 /* models */
3919 enum {
3920 	AD1984_AUTO,
3921 	AD1984_BASIC,
3922 	AD1984_THINKPAD,
3923 	AD1984_DELL_DESKTOP,
3924 	AD1984_MODELS
3925 };
3926 
3927 static const char * const ad1984_models[AD1984_MODELS] = {
3928 	[AD1984_AUTO]		= "auto",
3929 	[AD1984_BASIC]		= "basic",
3930 	[AD1984_THINKPAD]	= "thinkpad",
3931 	[AD1984_DELL_DESKTOP]	= "dell_desktop",
3932 };
3933 
3934 static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
3935 	/* Lenovo Thinkpad T61/X61 */
3936 	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3937 	SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3938 	SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3939 	{}
3940 };
3941 
3942 static int patch_ad1984(struct hda_codec *codec)
3943 {
3944 	struct ad198x_spec *spec;
3945 	int board_config, err;
3946 
3947 	board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3948 						  ad1984_models, ad1984_cfg_tbl);
3949 	if (board_config < 0) {
3950 		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3951 		       codec->chip_name);
3952 		board_config = AD1984_AUTO;
3953 	}
3954 
3955 	if (board_config == AD1984_AUTO)
3956 		return ad1884_parse_auto_config(codec);
3957 
3958 	err = patch_ad1884_basic(codec);
3959 	if (err < 0)
3960 		return err;
3961 	spec = codec->spec;
3962 
3963 	switch (board_config) {
3964 	case AD1984_BASIC:
3965 		/* additional digital mics */
3966 		spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3967 		codec->patch_ops.build_pcms = ad1984_build_pcms;
3968 		break;
3969 	case AD1984_THINKPAD:
3970 		if (codec->subsystem_id == 0x17aa20fb) {
3971 			/* Thinpad X300 does not have the ability to do SPDIF,
3972 			   or attach to docking station to use SPDIF */
3973 			spec->multiout.dig_out_nid = 0;
3974 		} else
3975 			spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3976 		spec->input_mux = &ad1984_thinkpad_capture_source;
3977 		spec->mixers[0] = ad1984_thinkpad_mixers;
3978 		spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3979 		spec->analog_beep = 1;
3980 		break;
3981 	case AD1984_DELL_DESKTOP:
3982 		spec->multiout.dig_out_nid = 0;
3983 		spec->input_mux = &ad1984_dell_desktop_capture_source;
3984 		spec->mixers[0] = ad1984_dell_desktop_mixers;
3985 		break;
3986 	}
3987 	return 0;
3988 }
3989 #else /* ENABLE_AD_STATIC_QUIRKS */
3990 #define patch_ad1984	ad1884_parse_auto_config
3991 #endif /* ENABLE_AD_STATIC_QUIRKS */
3992 
3993 
3994 /*
3995  * AD1883 / AD1884A / AD1984A / AD1984B
3996  *
3997  * port-B (0x14) - front mic-in
3998  * port-E (0x1c) - rear mic-in
3999  * port-F (0x16) - CD / ext out
4000  * port-C (0x15) - rear line-in
4001  * port-D (0x12) - rear line-out
4002  * port-A (0x11) - front hp-out
4003  *
4004  * AD1984A = AD1884A + digital-mic
4005  * AD1883 = equivalent with AD1984A
4006  * AD1984B = AD1984A + extra SPDIF-out
4007  *
4008  * FIXME:
4009  * We share the single DAC for both HP and line-outs (see AD1884/1984).
4010  */
4011 
4012 #ifdef ENABLE_AD_STATIC_QUIRKS
4013 static const hda_nid_t ad1884a_dac_nids[1] = {
4014 	0x03,
4015 };
4016 
4017 #define ad1884a_adc_nids	ad1884_adc_nids
4018 #define ad1884a_capsrc_nids	ad1884_capsrc_nids
4019 
4020 #define AD1884A_SPDIF_OUT	0x02
4021 
4022 static const struct hda_input_mux ad1884a_capture_source = {
4023 	.num_items = 5,
4024 	.items = {
4025 		{ "Front Mic", 0x0 },
4026 		{ "Mic", 0x4 },
4027 		{ "Line", 0x1 },
4028 		{ "CD", 0x2 },
4029 		{ "Mix", 0x3 },
4030 	},
4031 };
4032 
4033 static const struct snd_kcontrol_new ad1884a_base_mixers[] = {
4034 	HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4035 	HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4036 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4037 	HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4038 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4039 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4040 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4041 	HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4042 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4043 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4044 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4045 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4046 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4047 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4048 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
4049 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
4050 	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4051 	HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
4052 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4053 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4054 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4055 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4056 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4057 	{
4058 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4059 		/* The multiple "Capture Source" controls confuse alsamixer
4060 		 * So call somewhat different..
4061 		 */
4062 		/* .name = "Capture Source", */
4063 		.name = "Input Source",
4064 		.count = 2,
4065 		.info = ad198x_mux_enum_info,
4066 		.get = ad198x_mux_enum_get,
4067 		.put = ad198x_mux_enum_put,
4068 	},
4069 	/* SPDIF controls */
4070 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4071 	{
4072 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4073 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4074 		/* identical with ad1983 */
4075 		.info = ad1983_spdif_route_info,
4076 		.get = ad1983_spdif_route_get,
4077 		.put = ad1983_spdif_route_put,
4078 	},
4079 	{ } /* end */
4080 };
4081 
4082 /*
4083  * initialization verbs
4084  */
4085 static const struct hda_verb ad1884a_init_verbs[] = {
4086 	/* DACs; unmute as default */
4087 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4088 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4089 	/* Port-A (HP) mixer - route only from analog mixer */
4090 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4091 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4092 	/* Port-A pin */
4093 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4094 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4095 	/* Port-D (Line-out) mixer - route only from analog mixer */
4096 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4097 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4098 	/* Port-D pin */
4099 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4100 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4101 	/* Mono-out mixer - route only from analog mixer */
4102 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4103 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4104 	/* Mono-out pin */
4105 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4106 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4107 	/* Port-B (front mic) pin */
4108 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4109 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4110 	/* Port-C (rear line-in) pin */
4111 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4112 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4113 	/* Port-E (rear mic) pin */
4114 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4115 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4116 	{0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
4117 	/* Port-F (CD) pin */
4118 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4119 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4120 	/* Analog mixer; mute as default */
4121 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4122 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4123 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4124 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4125 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
4126 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4127 	/* Analog Mix output amp */
4128 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4129 	/* capture sources */
4130 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
4131 	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4132 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4133 	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4134 	/* SPDIF output amp */
4135 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4136 	{ } /* end */
4137 };
4138 
4139 #ifdef CONFIG_PM
4140 static const struct hda_amp_list ad1884a_loopbacks[] = {
4141 	{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
4142 	{ 0x20, HDA_INPUT, 1 }, /* Mic */
4143 	{ 0x20, HDA_INPUT, 2 }, /* CD */
4144 	{ 0x20, HDA_INPUT, 4 }, /* Docking */
4145 	{ } /* end */
4146 };
4147 #endif
4148 
4149 /*
4150  * Laptop model
4151  *
4152  * Port A: Headphone jack
4153  * Port B: MIC jack
4154  * Port C: Internal MIC
4155  * Port D: Dock Line Out (if enabled)
4156  * Port E: Dock Line In (if enabled)
4157  * Port F: Internal speakers
4158  */
4159 
4160 static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
4161 					struct snd_ctl_elem_value *ucontrol)
4162 {
4163 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4164 	int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
4165 	int mute = (!ucontrol->value.integer.value[0] &&
4166 		    !ucontrol->value.integer.value[1]);
4167 	/* toggle GPIO1 according to the mute state */
4168 	snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4169 			    mute ? 0x02 : 0x0);
4170 	return ret;
4171 }
4172 
4173 static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
4174 	HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4175 	{
4176 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4177 		.name = "Master Playback Switch",
4178 		.subdevice = HDA_SUBDEV_AMP_FLAG,
4179 		.info = snd_hda_mixer_amp_switch_info,
4180 		.get = snd_hda_mixer_amp_switch_get,
4181 		.put = ad1884a_mobile_master_sw_put,
4182 		.private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4183 	},
4184 	HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4185 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4186 	HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4187 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4188 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4189 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4190 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4191 	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4192 	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4193 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4194 	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4195 	HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4196 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4197 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4198 	{ } /* end */
4199 };
4200 
4201 static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
4202 	HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4203 	/*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4204 	{
4205 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4206 		.name = "Master Playback Switch",
4207 		.subdevice = HDA_SUBDEV_AMP_FLAG,
4208 		.info = snd_hda_mixer_amp_switch_info,
4209 		.get = snd_hda_mixer_amp_switch_get,
4210 		.put = ad1884a_mobile_master_sw_put,
4211 		.private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4212 	},
4213 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4214 	HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4215 	HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
4216 	HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
4217 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4218 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4219 	{ } /* end */
4220 };
4221 
4222 /* mute internal speaker if HP is plugged */
4223 static void ad1884a_hp_automute(struct hda_codec *codec)
4224 {
4225 	unsigned int present;
4226 
4227 	present = snd_hda_jack_detect(codec, 0x11);
4228 	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4229 				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4230 	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4231 			    present ? 0x00 : 0x02);
4232 }
4233 
4234 /* switch to external mic if plugged */
4235 static void ad1884a_hp_automic(struct hda_codec *codec)
4236 {
4237 	unsigned int present;
4238 
4239 	present = snd_hda_jack_detect(codec, 0x14);
4240 	snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
4241 			    present ? 0 : 1);
4242 }
4243 
4244 #define AD1884A_HP_EVENT		0x37
4245 #define AD1884A_MIC_EVENT		0x36
4246 
4247 /* unsolicited event for HP jack sensing */
4248 static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4249 {
4250 	switch (res >> 26) {
4251 	case AD1884A_HP_EVENT:
4252 		ad1884a_hp_automute(codec);
4253 		break;
4254 	case AD1884A_MIC_EVENT:
4255 		ad1884a_hp_automic(codec);
4256 		break;
4257 	}
4258 }
4259 
4260 /* initialize jack-sensing, too */
4261 static int ad1884a_hp_init(struct hda_codec *codec)
4262 {
4263 	ad198x_init(codec);
4264 	ad1884a_hp_automute(codec);
4265 	ad1884a_hp_automic(codec);
4266 	return 0;
4267 }
4268 
4269 /* mute internal speaker if HP or docking HP is plugged */
4270 static void ad1884a_laptop_automute(struct hda_codec *codec)
4271 {
4272 	unsigned int present;
4273 
4274 	present = snd_hda_jack_detect(codec, 0x11);
4275 	if (!present)
4276 		present = snd_hda_jack_detect(codec, 0x12);
4277 	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4278 				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4279 	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4280 			    present ? 0x00 : 0x02);
4281 }
4282 
4283 /* switch to external mic if plugged */
4284 static void ad1884a_laptop_automic(struct hda_codec *codec)
4285 {
4286 	unsigned int idx;
4287 
4288 	if (snd_hda_jack_detect(codec, 0x14))
4289 		idx = 0;
4290 	else if (snd_hda_jack_detect(codec, 0x1c))
4291 		idx = 4;
4292 	else
4293 		idx = 1;
4294 	snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
4295 }
4296 
4297 /* unsolicited event for HP jack sensing */
4298 static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
4299 				       unsigned int res)
4300 {
4301 	switch (res >> 26) {
4302 	case AD1884A_HP_EVENT:
4303 		ad1884a_laptop_automute(codec);
4304 		break;
4305 	case AD1884A_MIC_EVENT:
4306 		ad1884a_laptop_automic(codec);
4307 		break;
4308 	}
4309 }
4310 
4311 /* initialize jack-sensing, too */
4312 static int ad1884a_laptop_init(struct hda_codec *codec)
4313 {
4314 	ad198x_init(codec);
4315 	ad1884a_laptop_automute(codec);
4316 	ad1884a_laptop_automic(codec);
4317 	return 0;
4318 }
4319 
4320 /* additional verbs for laptop model */
4321 static const struct hda_verb ad1884a_laptop_verbs[] = {
4322 	/* Port-A (HP) pin - always unmuted */
4323 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4324 	/* Port-F (int speaker) mixer - route only from analog mixer */
4325 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4326 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4327 	/* Port-F (int speaker) pin */
4328 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4329 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4330 	/* required for compaq 6530s/6531s speaker output */
4331 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4332 	/* Port-C pin - internal mic-in */
4333 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4334 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4335 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4336 	/* Port-D (docking line-out) pin - default unmuted */
4337 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4338 	/* analog mix */
4339 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4340 	/* unsolicited event for pin-sense */
4341 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4342 	{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4343 	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4344 	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4345 	/* allow to touch GPIO1 (for mute control) */
4346 	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4347 	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4348 	{0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4349 	{ } /* end */
4350 };
4351 
4352 static const struct hda_verb ad1884a_mobile_verbs[] = {
4353 	/* DACs; unmute as default */
4354 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4355 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4356 	/* Port-A (HP) mixer - route only from analog mixer */
4357 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4358 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4359 	/* Port-A pin */
4360 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4361 	/* Port-A (HP) pin - always unmuted */
4362 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4363 	/* Port-B (mic jack) pin */
4364 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4365 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4366 	/* Port-C (int mic) pin */
4367 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4368 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4369 	/* Port-F (int speaker) mixer - route only from analog mixer */
4370 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4371 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4372 	/* Port-F pin */
4373 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4374 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4375 	/* Analog mixer; mute as default */
4376 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4377 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4378 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4379 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4380 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4381 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4382 	/* Analog Mix output amp */
4383 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4384 	/* capture sources */
4385 	/* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4386 	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4387 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4388 	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4389 	/* unsolicited event for pin-sense */
4390 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4391 	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4392 	/* allow to touch GPIO1 (for mute control) */
4393 	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4394 	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4395 	{0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4396 	{ } /* end */
4397 };
4398 
4399 /*
4400  * Thinkpad X300
4401  * 0x11 - HP
4402  * 0x12 - speaker
4403  * 0x14 - mic-in
4404  * 0x17 - built-in mic
4405  */
4406 
4407 static const struct hda_verb ad1984a_thinkpad_verbs[] = {
4408 	/* HP unmute */
4409 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4410 	/* analog mix */
4411 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4412 	/* turn on EAPD */
4413 	{0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4414 	/* unsolicited event for pin-sense */
4415 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4416 	/* internal mic - dmic */
4417 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4418 	/* set magic COEFs for dmic */
4419 	{0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4420 	{0x01, AC_VERB_SET_PROC_COEF, 0x08},
4421 	{ } /* end */
4422 };
4423 
4424 static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4425 	HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4426 	HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4427 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4428 	HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4429 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4430 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4431 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4432 	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4433 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4434 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4435 	{
4436 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4437 		.name = "Capture Source",
4438 		.info = ad198x_mux_enum_info,
4439 		.get = ad198x_mux_enum_get,
4440 		.put = ad198x_mux_enum_put,
4441 	},
4442 	{ } /* end */
4443 };
4444 
4445 static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
4446 	.num_items = 3,
4447 	.items = {
4448 		{ "Mic", 0x0 },
4449 		{ "Internal Mic", 0x5 },
4450 		{ "Mix", 0x3 },
4451 	},
4452 };
4453 
4454 /* mute internal speaker if HP is plugged */
4455 static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4456 {
4457 	unsigned int present;
4458 
4459 	present = snd_hda_jack_detect(codec, 0x11);
4460 	snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4461 				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4462 }
4463 
4464 /* unsolicited event for HP jack sensing */
4465 static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
4466 					 unsigned int res)
4467 {
4468 	if ((res >> 26) != AD1884A_HP_EVENT)
4469 		return;
4470 	ad1984a_thinkpad_automute(codec);
4471 }
4472 
4473 /* initialize jack-sensing, too */
4474 static int ad1984a_thinkpad_init(struct hda_codec *codec)
4475 {
4476 	ad198x_init(codec);
4477 	ad1984a_thinkpad_automute(codec);
4478 	return 0;
4479 }
4480 
4481 /*
4482  * Precision R5500
4483  * 0x12 - HP/line-out
4484  * 0x13 - speaker (mono)
4485  * 0x15 - mic-in
4486  */
4487 
4488 static const struct hda_verb ad1984a_precision_verbs[] = {
4489 	/* Unmute main output path */
4490 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4491 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
4492 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */
4493 	/* Analog mixer; mute as default */
4494 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4495 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4496 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4497 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4498 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4499 	/* Select mic as input */
4500 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
4501 	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */
4502 	/* Configure as mic */
4503 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4504 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4505 	/* HP unmute */
4506 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4507 	/* turn on EAPD */
4508 	{0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4509 	/* unsolicited event for pin-sense */
4510 	{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4511 	{ } /* end */
4512 };
4513 
4514 static const struct snd_kcontrol_new ad1984a_precision_mixers[] = {
4515 	HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4516 	HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4517 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4518 	HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4519 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4520 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4521 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4522 	HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4523 	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT),
4524 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4525 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4526 	{ } /* end */
4527 };
4528 
4529 
4530 /* mute internal speaker if HP is plugged */
4531 static void ad1984a_precision_automute(struct hda_codec *codec)
4532 {
4533 	unsigned int present;
4534 
4535 	present = snd_hda_jack_detect(codec, 0x12);
4536 	snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
4537 				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4538 }
4539 
4540 
4541 /* unsolicited event for HP jack sensing */
4542 static void ad1984a_precision_unsol_event(struct hda_codec *codec,
4543 					 unsigned int res)
4544 {
4545 	if ((res >> 26) != AD1884A_HP_EVENT)
4546 		return;
4547 	ad1984a_precision_automute(codec);
4548 }
4549 
4550 /* initialize jack-sensing, too */
4551 static int ad1984a_precision_init(struct hda_codec *codec)
4552 {
4553 	ad198x_init(codec);
4554 	ad1984a_precision_automute(codec);
4555 	return 0;
4556 }
4557 
4558 
4559 /*
4560  * HP Touchsmart
4561  * port-A (0x11)      - front hp-out
4562  * port-B (0x14)      - unused
4563  * port-C (0x15)      - unused
4564  * port-D (0x12)      - rear line out
4565  * port-E (0x1c)      - front mic-in
4566  * port-F (0x16)      - Internal speakers
4567  * digital-mic (0x17) - Internal mic
4568  */
4569 
4570 static const struct hda_verb ad1984a_touchsmart_verbs[] = {
4571 	/* DACs; unmute as default */
4572 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4573 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4574 	/* Port-A (HP) mixer - route only from analog mixer */
4575 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4576 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4577 	/* Port-A pin */
4578 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4579 	/* Port-A (HP) pin - always unmuted */
4580 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4581 	/* Port-E (int speaker) mixer - route only from analog mixer */
4582 	{0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4583 	/* Port-E pin */
4584 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4585 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4586 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4587 	/* Port-F (int speaker) mixer - route only from analog mixer */
4588 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4589 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4590 	/* Port-F pin */
4591 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4592 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4593 	/* Analog mixer; mute as default */
4594 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4595 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4596 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4597 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4598 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4599 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4600 	/* Analog Mix output amp */
4601 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4602 	/* capture sources */
4603 	/* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4604 	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4605 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4606 	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4607 	/* unsolicited event for pin-sense */
4608 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4609 	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4610 	/* allow to touch GPIO1 (for mute control) */
4611 	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4612 	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4613 	{0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4614 	/* internal mic - dmic */
4615 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4616 	/* set magic COEFs for dmic */
4617 	{0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4618 	{0x01, AC_VERB_SET_PROC_COEF, 0x08},
4619 	{ } /* end */
4620 };
4621 
4622 static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4623 	HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4624 /*	HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4625 	{
4626 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4627 		.subdevice = HDA_SUBDEV_AMP_FLAG,
4628 		.name = "Master Playback Switch",
4629 		.info = snd_hda_mixer_amp_switch_info,
4630 		.get = snd_hda_mixer_amp_switch_get,
4631 		.put = ad1884a_mobile_master_sw_put,
4632 		.private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4633 	},
4634 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4635 	HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4636 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4637 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4638 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4639 	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4640 	{ } /* end */
4641 };
4642 
4643 /* switch to external mic if plugged */
4644 static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4645 {
4646 	if (snd_hda_jack_detect(codec, 0x1c))
4647 		snd_hda_codec_write(codec, 0x0c, 0,
4648 				     AC_VERB_SET_CONNECT_SEL, 0x4);
4649 	else
4650 		snd_hda_codec_write(codec, 0x0c, 0,
4651 				     AC_VERB_SET_CONNECT_SEL, 0x5);
4652 }
4653 
4654 
4655 /* unsolicited event for HP jack sensing */
4656 static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4657 	unsigned int res)
4658 {
4659 	switch (res >> 26) {
4660 	case AD1884A_HP_EVENT:
4661 		ad1884a_hp_automute(codec);
4662 		break;
4663 	case AD1884A_MIC_EVENT:
4664 		ad1984a_touchsmart_automic(codec);
4665 		break;
4666 	}
4667 }
4668 
4669 /* initialize jack-sensing, too */
4670 static int ad1984a_touchsmart_init(struct hda_codec *codec)
4671 {
4672 	ad198x_init(codec);
4673 	ad1884a_hp_automute(codec);
4674 	ad1984a_touchsmart_automic(codec);
4675 	return 0;
4676 }
4677 
4678 
4679 /*
4680  */
4681 
4682 enum {
4683 	AD1884A_AUTO,
4684 	AD1884A_DESKTOP,
4685 	AD1884A_LAPTOP,
4686 	AD1884A_MOBILE,
4687 	AD1884A_THINKPAD,
4688 	AD1984A_TOUCHSMART,
4689 	AD1984A_PRECISION,
4690 	AD1884A_MODELS
4691 };
4692 
4693 static const char * const ad1884a_models[AD1884A_MODELS] = {
4694 	[AD1884A_AUTO]		= "auto",
4695 	[AD1884A_DESKTOP]	= "desktop",
4696 	[AD1884A_LAPTOP]	= "laptop",
4697 	[AD1884A_MOBILE]	= "mobile",
4698 	[AD1884A_THINKPAD]	= "thinkpad",
4699 	[AD1984A_TOUCHSMART]	= "touchsmart",
4700 	[AD1984A_PRECISION]	= "precision",
4701 };
4702 
4703 static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4704 	SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
4705 	SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4706 	SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4707 	SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
4708 	SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
4709 	SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4710 	SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4711 	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4712 	SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4713 	SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4714 	SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4715 	{}
4716 };
4717 
4718 static int patch_ad1884a(struct hda_codec *codec)
4719 {
4720 	struct ad198x_spec *spec;
4721 	int err, board_config;
4722 
4723 	board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
4724 						  ad1884a_models,
4725 						  ad1884a_cfg_tbl);
4726 	if (board_config < 0) {
4727 		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4728 		       codec->chip_name);
4729 		board_config = AD1884A_AUTO;
4730 	}
4731 
4732 	if (board_config == AD1884A_AUTO)
4733 		return ad1884_parse_auto_config(codec);
4734 
4735 	err = alloc_ad_spec(codec);
4736 	if (err < 0)
4737 		return err;
4738 	spec = codec->spec;
4739 
4740 	err = snd_hda_attach_beep_device(codec, 0x10);
4741 	if (err < 0) {
4742 		ad198x_free(codec);
4743 		return err;
4744 	}
4745 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4746 
4747 	spec->multiout.max_channels = 2;
4748 	spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
4749 	spec->multiout.dac_nids = ad1884a_dac_nids;
4750 	spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
4751 	spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
4752 	spec->adc_nids = ad1884a_adc_nids;
4753 	spec->capsrc_nids = ad1884a_capsrc_nids;
4754 	spec->input_mux = &ad1884a_capture_source;
4755 	spec->num_mixers = 1;
4756 	spec->mixers[0] = ad1884a_base_mixers;
4757 	spec->num_init_verbs = 1;
4758 	spec->init_verbs[0] = ad1884a_init_verbs;
4759 	spec->spdif_route = 0;
4760 #ifdef CONFIG_PM
4761 	spec->loopback.amplist = ad1884a_loopbacks;
4762 #endif
4763 	codec->patch_ops = ad198x_patch_ops;
4764 
4765 	/* override some parameters */
4766 	switch (board_config) {
4767 	case AD1884A_LAPTOP:
4768 		spec->mixers[0] = ad1884a_laptop_mixers;
4769 		spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4770 		spec->multiout.dig_out_nid = 0;
4771 		codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4772 		codec->patch_ops.init = ad1884a_laptop_init;
4773 		/* set the upper-limit for mixer amp to 0dB for avoiding the
4774 		 * possible damage by overloading
4775 		 */
4776 		snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4777 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4778 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4779 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4780 					  (1 << AC_AMPCAP_MUTE_SHIFT));
4781 		break;
4782 	case AD1884A_MOBILE:
4783 		spec->mixers[0] = ad1884a_mobile_mixers;
4784 		spec->init_verbs[0] = ad1884a_mobile_verbs;
4785 		spec->multiout.dig_out_nid = 0;
4786 		codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
4787 		codec->patch_ops.init = ad1884a_hp_init;
4788 		/* set the upper-limit for mixer amp to 0dB for avoiding the
4789 		 * possible damage by overloading
4790 		 */
4791 		snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4792 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4793 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4794 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4795 					  (1 << AC_AMPCAP_MUTE_SHIFT));
4796 		break;
4797 	case AD1884A_THINKPAD:
4798 		spec->mixers[0] = ad1984a_thinkpad_mixers;
4799 		spec->init_verbs[spec->num_init_verbs++] =
4800 			ad1984a_thinkpad_verbs;
4801 		spec->multiout.dig_out_nid = 0;
4802 		spec->input_mux = &ad1984a_thinkpad_capture_source;
4803 		codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4804 		codec->patch_ops.init = ad1984a_thinkpad_init;
4805 		break;
4806 	case AD1984A_PRECISION:
4807 		spec->mixers[0] = ad1984a_precision_mixers;
4808 		spec->init_verbs[spec->num_init_verbs++] =
4809 			ad1984a_precision_verbs;
4810 		spec->multiout.dig_out_nid = 0;
4811 		codec->patch_ops.unsol_event = ad1984a_precision_unsol_event;
4812 		codec->patch_ops.init = ad1984a_precision_init;
4813 		break;
4814 	case AD1984A_TOUCHSMART:
4815 		spec->mixers[0] = ad1984a_touchsmart_mixers;
4816 		spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4817 		spec->multiout.dig_out_nid = 0;
4818 		codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4819 		codec->patch_ops.init = ad1984a_touchsmart_init;
4820 		/* set the upper-limit for mixer amp to 0dB for avoiding the
4821 		 * possible damage by overloading
4822 		 */
4823 		snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4824 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4825 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4826 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4827 					  (1 << AC_AMPCAP_MUTE_SHIFT));
4828 		break;
4829 	}
4830 
4831 	codec->no_trigger_sense = 1;
4832 	codec->no_sticky_stream = 1;
4833 
4834 	return 0;
4835 }
4836 #else /* ENABLE_AD_STATIC_QUIRKS */
4837 #define patch_ad1884a	ad1884_parse_auto_config
4838 #endif /* ENABLE_AD_STATIC_QUIRKS */
4839 
4840 
4841 /*
4842  * AD1882 / AD1882A
4843  *
4844  * port-A - front hp-out
4845  * port-B - front mic-in
4846  * port-C - rear line-in, shared surr-out (3stack)
4847  * port-D - rear line-out
4848  * port-E - rear mic-in, shared clfe-out (3stack)
4849  * port-F - rear surr-out (6stack)
4850  * port-G - rear clfe-out (6stack)
4851  */
4852 
4853 #ifdef ENABLE_AD_STATIC_QUIRKS
4854 static const hda_nid_t ad1882_dac_nids[3] = {
4855 	0x04, 0x03, 0x05
4856 };
4857 
4858 static const hda_nid_t ad1882_adc_nids[2] = {
4859 	0x08, 0x09,
4860 };
4861 
4862 static const hda_nid_t ad1882_capsrc_nids[2] = {
4863 	0x0c, 0x0d,
4864 };
4865 
4866 #define AD1882_SPDIF_OUT	0x02
4867 
4868 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4869 static const struct hda_input_mux ad1882_capture_source = {
4870 	.num_items = 5,
4871 	.items = {
4872 		{ "Front Mic", 0x1 },
4873 		{ "Mic", 0x4 },
4874 		{ "Line", 0x2 },
4875 		{ "CD", 0x3 },
4876 		{ "Mix", 0x7 },
4877 	},
4878 };
4879 
4880 /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4881 static const struct hda_input_mux ad1882a_capture_source = {
4882 	.num_items = 5,
4883 	.items = {
4884 		{ "Front Mic", 0x1 },
4885 		{ "Mic", 0x4},
4886 		{ "Line", 0x2 },
4887 		{ "Digital Mic", 0x06 },
4888 		{ "Mix", 0x7 },
4889 	},
4890 };
4891 
4892 static const struct snd_kcontrol_new ad1882_base_mixers[] = {
4893 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4894 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4895 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4896 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4897 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4898 	HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4899 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4900 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4901 
4902 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
4903 	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
4904 	HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
4905 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4906 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4907 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4908 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4909 	{
4910 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4911 		/* The multiple "Capture Source" controls confuse alsamixer
4912 		 * So call somewhat different..
4913 		 */
4914 		/* .name = "Capture Source", */
4915 		.name = "Input Source",
4916 		.count = 2,
4917 		.info = ad198x_mux_enum_info,
4918 		.get = ad198x_mux_enum_get,
4919 		.put = ad198x_mux_enum_put,
4920 	},
4921 	/* SPDIF controls */
4922 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4923 	{
4924 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4925 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4926 		/* identical with ad1983 */
4927 		.info = ad1983_spdif_route_info,
4928 		.get = ad1983_spdif_route_get,
4929 		.put = ad1983_spdif_route_put,
4930 	},
4931 	{ } /* end */
4932 };
4933 
4934 static const struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4935 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4936 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4937 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4938 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4939 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4940 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4941 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4942 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4943 	{ } /* end */
4944 };
4945 
4946 static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4947 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4948 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4949 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4950 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4951 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4952 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4953 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4954 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4955 	HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
4956 	{ } /* end */
4957 };
4958 
4959 static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4960 	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4961 	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4962 	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4963 	{
4964 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4965 		.name = "Channel Mode",
4966 		.info = ad198x_ch_mode_info,
4967 		.get = ad198x_ch_mode_get,
4968 		.put = ad198x_ch_mode_put,
4969 	},
4970 	{ } /* end */
4971 };
4972 
4973 /* simple auto-mute control for AD1882 3-stack board */
4974 #define AD1882_HP_EVENT	0x01
4975 
4976 static void ad1882_3stack_automute(struct hda_codec *codec)
4977 {
4978 	bool mute = snd_hda_jack_detect(codec, 0x11);
4979 	snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4980 			    mute ? 0 : PIN_OUT);
4981 }
4982 
4983 static int ad1882_3stack_automute_init(struct hda_codec *codec)
4984 {
4985 	ad198x_init(codec);
4986 	ad1882_3stack_automute(codec);
4987 	return 0;
4988 }
4989 
4990 static void ad1882_3stack_unsol_event(struct hda_codec *codec, unsigned int res)
4991 {
4992 	switch (res >> 26) {
4993 	case AD1882_HP_EVENT:
4994 		ad1882_3stack_automute(codec);
4995 		break;
4996 	}
4997 }
4998 
4999 static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
5000 	HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5001 	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
5002 	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
5003 	{ } /* end */
5004 };
5005 
5006 static const struct hda_verb ad1882_ch2_init[] = {
5007 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5008 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5009 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5010 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5011 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5012 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5013 	{ } /* end */
5014 };
5015 
5016 static const struct hda_verb ad1882_ch4_init[] = {
5017 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5018 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5019 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5020 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5021 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5022 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5023 	{ } /* end */
5024 };
5025 
5026 static const struct hda_verb ad1882_ch6_init[] = {
5027 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5028 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5029 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5030 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5031 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5032 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5033 	{ } /* end */
5034 };
5035 
5036 static const struct hda_channel_mode ad1882_modes[3] = {
5037 	{ 2, ad1882_ch2_init },
5038 	{ 4, ad1882_ch4_init },
5039 	{ 6, ad1882_ch6_init },
5040 };
5041 
5042 /*
5043  * initialization verbs
5044  */
5045 static const struct hda_verb ad1882_init_verbs[] = {
5046 	/* DACs; mute as default */
5047 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5048 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5049 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5050 	/* Port-A (HP) mixer */
5051 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5052 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5053 	/* Port-A pin */
5054 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5055 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5056 	/* HP selector - select DAC2 */
5057 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
5058 	/* Port-D (Line-out) mixer */
5059 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5060 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5061 	/* Port-D pin */
5062 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5063 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5064 	/* Mono-out mixer */
5065 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5066 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5067 	/* Mono-out pin */
5068 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5069 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5070 	/* Port-B (front mic) pin */
5071 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5072 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5073 	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5074 	/* Port-C (line-in) pin */
5075 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5076 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5077 	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5078 	/* Port-C mixer - mute as input */
5079 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5080 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5081 	/* Port-E (mic-in) pin */
5082 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5083 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5084 	{0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5085 	/* Port-E mixer - mute as input */
5086 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5087 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5088 	/* Port-F (surround) */
5089 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5090 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5091 	/* Port-G (CLFE) */
5092 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5093 	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5094 	/* Analog mixer; mute as default */
5095 	/* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
5096 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5097 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5098 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5099 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5100 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5101 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
5102 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
5103 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
5104 	/* Analog Mix output amp */
5105 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
5106 	/* SPDIF output selector */
5107 	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
5108 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
5109 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
5110 	{ } /* end */
5111 };
5112 
5113 static const struct hda_verb ad1882_3stack_automute_verbs[] = {
5114 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1882_HP_EVENT},
5115 	{ } /* end */
5116 };
5117 
5118 #ifdef CONFIG_PM
5119 static const struct hda_amp_list ad1882_loopbacks[] = {
5120 	{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
5121 	{ 0x20, HDA_INPUT, 1 }, /* Mic */
5122 	{ 0x20, HDA_INPUT, 4 }, /* Line */
5123 	{ 0x20, HDA_INPUT, 6 }, /* CD */
5124 	{ } /* end */
5125 };
5126 #endif
5127 
5128 /* models */
5129 enum {
5130 	AD1882_AUTO,
5131 	AD1882_3STACK,
5132 	AD1882_6STACK,
5133 	AD1882_3STACK_AUTOMUTE,
5134 	AD1882_MODELS
5135 };
5136 
5137 static const char * const ad1882_models[AD1986A_MODELS] = {
5138 	[AD1882_AUTO]		= "auto",
5139 	[AD1882_3STACK]		= "3stack",
5140 	[AD1882_6STACK]		= "6stack",
5141 	[AD1882_3STACK_AUTOMUTE] = "3stack-automute",
5142 };
5143 #endif /* ENABLE_AD_STATIC_QUIRKS */
5144 
5145 static int ad1882_parse_auto_config(struct hda_codec *codec)
5146 {
5147 	struct ad198x_spec *spec;
5148 	int err;
5149 
5150 	err = alloc_ad_spec(codec);
5151 	if (err < 0)
5152 		return err;
5153 	spec = codec->spec;
5154 
5155 	spec->gen.mixer_nid = 0x20;
5156 	spec->gen.mixer_merge_nid = 0x21;
5157 	spec->gen.beep_nid = 0x10;
5158 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
5159 	err = ad198x_parse_auto_config(codec);
5160 	if (err < 0)
5161 		goto error;
5162 	err = ad1988_add_spdif_mux_ctl(codec);
5163 	if (err < 0)
5164 		goto error;
5165 	return 0;
5166 
5167  error:
5168 	snd_hda_gen_free(codec);
5169 	return err;
5170 }
5171 
5172 #ifdef ENABLE_AD_STATIC_QUIRKS
5173 static int patch_ad1882(struct hda_codec *codec)
5174 {
5175 	struct ad198x_spec *spec;
5176 	int err, board_config;
5177 
5178 	board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
5179 						  ad1882_models, NULL);
5180 	if (board_config < 0) {
5181 		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5182 		       codec->chip_name);
5183 		board_config = AD1882_AUTO;
5184 	}
5185 
5186 	if (board_config == AD1882_AUTO)
5187 		return ad1882_parse_auto_config(codec);
5188 
5189 	err = alloc_ad_spec(codec);
5190 	if (err < 0)
5191 		return err;
5192 	spec = codec->spec;
5193 
5194 	err = snd_hda_attach_beep_device(codec, 0x10);
5195 	if (err < 0) {
5196 		ad198x_free(codec);
5197 		return err;
5198 	}
5199 	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
5200 
5201 	spec->multiout.max_channels = 6;
5202 	spec->multiout.num_dacs = 3;
5203 	spec->multiout.dac_nids = ad1882_dac_nids;
5204 	spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
5205 	spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
5206 	spec->adc_nids = ad1882_adc_nids;
5207 	spec->capsrc_nids = ad1882_capsrc_nids;
5208 	if (codec->vendor_id == 0x11d41882)
5209 		spec->input_mux = &ad1882_capture_source;
5210 	else
5211 		spec->input_mux = &ad1882a_capture_source;
5212 	spec->num_mixers = 2;
5213 	spec->mixers[0] = ad1882_base_mixers;
5214 	if (codec->vendor_id == 0x11d41882)
5215 		spec->mixers[1] = ad1882_loopback_mixers;
5216 	else
5217 		spec->mixers[1] = ad1882a_loopback_mixers;
5218 	spec->num_init_verbs = 1;
5219 	spec->init_verbs[0] = ad1882_init_verbs;
5220 	spec->spdif_route = 0;
5221 #ifdef CONFIG_PM
5222 	spec->loopback.amplist = ad1882_loopbacks;
5223 #endif
5224 	spec->vmaster_nid = 0x04;
5225 
5226 	codec->patch_ops = ad198x_patch_ops;
5227 
5228 	/* override some parameters */
5229 	switch (board_config) {
5230 	default:
5231 	case AD1882_3STACK:
5232 	case AD1882_3STACK_AUTOMUTE:
5233 		spec->num_mixers = 3;
5234 		spec->mixers[2] = ad1882_3stack_mixers;
5235 		spec->channel_mode = ad1882_modes;
5236 		spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
5237 		spec->need_dac_fix = 1;
5238 		spec->multiout.max_channels = 2;
5239 		spec->multiout.num_dacs = 1;
5240 		if (board_config != AD1882_3STACK) {
5241 			spec->init_verbs[spec->num_init_verbs++] =
5242 				ad1882_3stack_automute_verbs;
5243 			codec->patch_ops.unsol_event = ad1882_3stack_unsol_event;
5244 			codec->patch_ops.init = ad1882_3stack_automute_init;
5245 		}
5246 		break;
5247 	case AD1882_6STACK:
5248 		spec->num_mixers = 3;
5249 		spec->mixers[2] = ad1882_6stack_mixers;
5250 		break;
5251 	}
5252 
5253 	codec->no_trigger_sense = 1;
5254 	codec->no_sticky_stream = 1;
5255 
5256 	return 0;
5257 }
5258 #else /* ENABLE_AD_STATIC_QUIRKS */
5259 #define patch_ad1882	ad1882_parse_auto_config
5260 #endif /* ENABLE_AD_STATIC_QUIRKS */
5261 
5262 
5263 /*
5264  * patch entries
5265  */
5266 static const struct hda_codec_preset snd_hda_preset_analog[] = {
5267 	{ .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
5268 	{ .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
5269 	{ .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
5270 	{ .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
5271 	{ .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
5272 	{ .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
5273 	{ .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
5274 	{ .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
5275 	{ .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
5276 	{ .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
5277 	{ .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
5278 	{ .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
5279 	{ .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
5280 	{ .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
5281 	{ .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
5282 	{} /* terminator */
5283 };
5284 
5285 MODULE_ALIAS("snd-hda-codec-id:11d4*");
5286 
5287 MODULE_LICENSE("GPL");
5288 MODULE_DESCRIPTION("Analog Devices HD-audio codec");
5289 
5290 static struct hda_codec_preset_list analog_list = {
5291 	.preset = snd_hda_preset_analog,
5292 	.owner = THIS_MODULE,
5293 };
5294 
5295 static int __init patch_analog_init(void)
5296 {
5297 	return snd_hda_add_codec_preset(&analog_list);
5298 }
5299 
5300 static void __exit patch_analog_exit(void)
5301 {
5302 	snd_hda_delete_codec_preset(&analog_list);
5303 }
5304 
5305 module_init(patch_analog_init)
5306 module_exit(patch_analog_exit)
5307