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