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