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