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