xref: /openbmc/linux/sound/pci/hda/patch_analog.c (revision c21b37f6)
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 <sound/driver.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/slab.h>
26 #include <linux/pci.h>
27 #include <linux/mutex.h>
28 
29 #include <sound/core.h>
30 #include "hda_codec.h"
31 #include "hda_local.h"
32 
33 struct ad198x_spec {
34 	struct snd_kcontrol_new *mixers[5];
35 	int num_mixers;
36 
37 	const struct hda_verb *init_verbs[5];	/* initialization verbs
38 						 * don't forget NULL termination!
39 						 */
40 	unsigned int num_init_verbs;
41 
42 	/* playback */
43 	struct hda_multi_out multiout;	/* playback set-up
44 					 * max_channels, dacs must be set
45 					 * dig_out_nid and hp_nid are optional
46 					 */
47 	unsigned int cur_eapd;
48 	unsigned int need_dac_fix;
49 
50 	/* capture */
51 	unsigned int num_adc_nids;
52 	hda_nid_t *adc_nids;
53 	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
54 
55 	/* capture source */
56 	const struct hda_input_mux *input_mux;
57 	hda_nid_t *capsrc_nids;
58 	unsigned int cur_mux[3];
59 
60 	/* channel model */
61 	const struct hda_channel_mode *channel_mode;
62 	int num_channel_mode;
63 
64 	/* PCM information */
65 	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
66 
67 	struct mutex amp_mutex;	/* PCM volume/mute control mutex */
68 	unsigned int spdif_route;
69 
70 	/* dynamic controls, init_verbs and input_mux */
71 	struct auto_pin_cfg autocfg;
72 	unsigned int num_kctl_alloc, num_kctl_used;
73 	struct snd_kcontrol_new *kctl_alloc;
74 	struct hda_input_mux private_imux;
75 	hda_nid_t private_dac_nids[4];
76 };
77 
78 /*
79  * input MUX handling (common part)
80  */
81 static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
82 {
83 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
84 	struct ad198x_spec *spec = codec->spec;
85 
86 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
87 }
88 
89 static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
90 {
91 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
92 	struct ad198x_spec *spec = codec->spec;
93 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
94 
95 	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
96 	return 0;
97 }
98 
99 static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
100 {
101 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
102 	struct ad198x_spec *spec = codec->spec;
103 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
104 
105 	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
106 				     spec->capsrc_nids[adc_idx],
107 				     &spec->cur_mux[adc_idx]);
108 }
109 
110 /*
111  * initialization (common callbacks)
112  */
113 static int ad198x_init(struct hda_codec *codec)
114 {
115 	struct ad198x_spec *spec = codec->spec;
116 	int i;
117 
118 	for (i = 0; i < spec->num_init_verbs; i++)
119 		snd_hda_sequence_write(codec, spec->init_verbs[i]);
120 	return 0;
121 }
122 
123 static int ad198x_build_controls(struct hda_codec *codec)
124 {
125 	struct ad198x_spec *spec = codec->spec;
126 	unsigned int i;
127 	int err;
128 
129 	for (i = 0; i < spec->num_mixers; i++) {
130 		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
131 		if (err < 0)
132 			return err;
133 	}
134 	if (spec->multiout.dig_out_nid) {
135 		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
136 		if (err < 0)
137 			return err;
138 	}
139 	if (spec->dig_in_nid) {
140 		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
141 		if (err < 0)
142 			return err;
143 	}
144 	return 0;
145 }
146 
147 /*
148  * Analog playback callbacks
149  */
150 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
151 				    struct hda_codec *codec,
152 				    struct snd_pcm_substream *substream)
153 {
154 	struct ad198x_spec *spec = codec->spec;
155 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
156 }
157 
158 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
159 				       struct hda_codec *codec,
160 				       unsigned int stream_tag,
161 				       unsigned int format,
162 				       struct snd_pcm_substream *substream)
163 {
164 	struct ad198x_spec *spec = codec->spec;
165 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
166 						format, substream);
167 }
168 
169 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
170 				       struct hda_codec *codec,
171 				       struct snd_pcm_substream *substream)
172 {
173 	struct ad198x_spec *spec = codec->spec;
174 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
175 }
176 
177 /*
178  * Digital out
179  */
180 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
181 					struct hda_codec *codec,
182 					struct snd_pcm_substream *substream)
183 {
184 	struct ad198x_spec *spec = codec->spec;
185 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
186 }
187 
188 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
189 					 struct hda_codec *codec,
190 					 struct snd_pcm_substream *substream)
191 {
192 	struct ad198x_spec *spec = codec->spec;
193 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
194 }
195 
196 static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
197 					   struct hda_codec *codec,
198 					   unsigned int stream_tag,
199 					   unsigned int format,
200 					   struct snd_pcm_substream *substream)
201 {
202 	struct ad198x_spec *spec = codec->spec;
203 	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
204 					     format, substream);
205 }
206 
207 /*
208  * Analog capture
209  */
210 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
211 				      struct hda_codec *codec,
212 				      unsigned int stream_tag,
213 				      unsigned int format,
214 				      struct snd_pcm_substream *substream)
215 {
216 	struct ad198x_spec *spec = codec->spec;
217 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
218 				   stream_tag, 0, format);
219 	return 0;
220 }
221 
222 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
223 				      struct hda_codec *codec,
224 				      struct snd_pcm_substream *substream)
225 {
226 	struct ad198x_spec *spec = codec->spec;
227 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
228 				   0, 0, 0);
229 	return 0;
230 }
231 
232 
233 /*
234  */
235 static struct hda_pcm_stream ad198x_pcm_analog_playback = {
236 	.substreams = 1,
237 	.channels_min = 2,
238 	.channels_max = 6, /* changed later */
239 	.nid = 0, /* fill later */
240 	.ops = {
241 		.open = ad198x_playback_pcm_open,
242 		.prepare = ad198x_playback_pcm_prepare,
243 		.cleanup = ad198x_playback_pcm_cleanup
244 	},
245 };
246 
247 static struct hda_pcm_stream ad198x_pcm_analog_capture = {
248 	.substreams = 1,
249 	.channels_min = 2,
250 	.channels_max = 2,
251 	.nid = 0, /* fill later */
252 	.ops = {
253 		.prepare = ad198x_capture_pcm_prepare,
254 		.cleanup = ad198x_capture_pcm_cleanup
255 	},
256 };
257 
258 static struct hda_pcm_stream ad198x_pcm_digital_playback = {
259 	.substreams = 1,
260 	.channels_min = 2,
261 	.channels_max = 2,
262 	.nid = 0, /* fill later */
263 	.ops = {
264 		.open = ad198x_dig_playback_pcm_open,
265 		.close = ad198x_dig_playback_pcm_close,
266 		.prepare = ad198x_dig_playback_pcm_prepare
267 	},
268 };
269 
270 static struct hda_pcm_stream ad198x_pcm_digital_capture = {
271 	.substreams = 1,
272 	.channels_min = 2,
273 	.channels_max = 2,
274 	/* NID is set in alc_build_pcms */
275 };
276 
277 static int ad198x_build_pcms(struct hda_codec *codec)
278 {
279 	struct ad198x_spec *spec = codec->spec;
280 	struct hda_pcm *info = spec->pcm_rec;
281 
282 	codec->num_pcms = 1;
283 	codec->pcm_info = info;
284 
285 	info->name = "AD198x Analog";
286 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
287 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
288 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
289 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
290 	info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
291 	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
292 
293 	if (spec->multiout.dig_out_nid) {
294 		info++;
295 		codec->num_pcms++;
296 		info->name = "AD198x Digital";
297 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
298 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
299 		if (spec->dig_in_nid) {
300 			info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
301 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
302 		}
303 	}
304 
305 	return 0;
306 }
307 
308 static void ad198x_free(struct hda_codec *codec)
309 {
310 	struct ad198x_spec *spec = codec->spec;
311 	unsigned int i;
312 
313 	if (spec->kctl_alloc) {
314 		for (i = 0; i < spec->num_kctl_used; i++)
315 			kfree(spec->kctl_alloc[i].name);
316 		kfree(spec->kctl_alloc);
317 	}
318 	kfree(codec->spec);
319 }
320 
321 #ifdef CONFIG_PM
322 static int ad198x_resume(struct hda_codec *codec)
323 {
324 	struct ad198x_spec *spec = codec->spec;
325 	int i;
326 
327 	codec->patch_ops.init(codec);
328 	for (i = 0; i < spec->num_mixers; i++)
329 		snd_hda_resume_ctls(codec, spec->mixers[i]);
330 	if (spec->multiout.dig_out_nid)
331 		snd_hda_resume_spdif_out(codec);
332 	if (spec->dig_in_nid)
333 		snd_hda_resume_spdif_in(codec);
334 	return 0;
335 }
336 #endif
337 
338 static struct hda_codec_ops ad198x_patch_ops = {
339 	.build_controls = ad198x_build_controls,
340 	.build_pcms = ad198x_build_pcms,
341 	.init = ad198x_init,
342 	.free = ad198x_free,
343 #ifdef CONFIG_PM
344 	.resume = ad198x_resume,
345 #endif
346 };
347 
348 
349 /*
350  * EAPD control
351  * the private value = nid | (invert << 8)
352  */
353 static int ad198x_eapd_info(struct snd_kcontrol *kcontrol,
354 			    struct snd_ctl_elem_info *uinfo)
355 {
356 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
357 	uinfo->count = 1;
358 	uinfo->value.integer.min = 0;
359 	uinfo->value.integer.max = 1;
360 	return 0;
361 }
362 
363 static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
364 			   struct snd_ctl_elem_value *ucontrol)
365 {
366 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
367 	struct ad198x_spec *spec = codec->spec;
368 	int invert = (kcontrol->private_value >> 8) & 1;
369 	if (invert)
370 		ucontrol->value.integer.value[0] = ! spec->cur_eapd;
371 	else
372 		ucontrol->value.integer.value[0] = spec->cur_eapd;
373 	return 0;
374 }
375 
376 static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
377 			   struct snd_ctl_elem_value *ucontrol)
378 {
379 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
380 	struct ad198x_spec *spec = codec->spec;
381 	int invert = (kcontrol->private_value >> 8) & 1;
382 	hda_nid_t nid = kcontrol->private_value & 0xff;
383 	unsigned int eapd;
384 	eapd = ucontrol->value.integer.value[0];
385 	if (invert)
386 		eapd = !eapd;
387 	if (eapd == spec->cur_eapd && ! codec->in_resume)
388 		return 0;
389 	spec->cur_eapd = eapd;
390 	snd_hda_codec_write(codec, nid,
391 			    0, AC_VERB_SET_EAPD_BTLENABLE,
392 			    eapd ? 0x02 : 0x00);
393 	return 1;
394 }
395 
396 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
397 			       struct snd_ctl_elem_info *uinfo);
398 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
399 			      struct snd_ctl_elem_value *ucontrol);
400 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
401 			      struct snd_ctl_elem_value *ucontrol);
402 
403 
404 /*
405  * AD1986A specific
406  */
407 
408 #define AD1986A_SPDIF_OUT	0x02
409 #define AD1986A_FRONT_DAC	0x03
410 #define AD1986A_SURR_DAC	0x04
411 #define AD1986A_CLFE_DAC	0x05
412 #define AD1986A_ADC		0x06
413 
414 static hda_nid_t ad1986a_dac_nids[3] = {
415 	AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
416 };
417 static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
418 static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
419 
420 static struct hda_input_mux ad1986a_capture_source = {
421 	.num_items = 7,
422 	.items = {
423 		{ "Mic", 0x0 },
424 		{ "CD", 0x1 },
425 		{ "Aux", 0x3 },
426 		{ "Line", 0x4 },
427 		{ "Mix", 0x5 },
428 		{ "Mono", 0x6 },
429 		{ "Phone", 0x7 },
430 	},
431 };
432 
433 /*
434  * PCM control
435  *
436  * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
437  */
438 
439 #define ad1986a_pcm_amp_vol_info	snd_hda_mixer_amp_volume_info
440 
441 static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
442 {
443 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
444 	struct ad198x_spec *ad = codec->spec;
445 
446 	mutex_lock(&ad->amp_mutex);
447 	snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
448 	mutex_unlock(&ad->amp_mutex);
449 	return 0;
450 }
451 
452 static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
453 {
454 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
455 	struct ad198x_spec *ad = codec->spec;
456 	int i, change = 0;
457 
458 	mutex_lock(&ad->amp_mutex);
459 	for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
460 		kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
461 		change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
462 	}
463 	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
464 	mutex_unlock(&ad->amp_mutex);
465 	return change;
466 }
467 
468 #define ad1986a_pcm_amp_sw_info		snd_hda_mixer_amp_switch_info
469 
470 static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
471 {
472 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
473 	struct ad198x_spec *ad = codec->spec;
474 
475 	mutex_lock(&ad->amp_mutex);
476 	snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
477 	mutex_unlock(&ad->amp_mutex);
478 	return 0;
479 }
480 
481 static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
482 {
483 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
484 	struct ad198x_spec *ad = codec->spec;
485 	int i, change = 0;
486 
487 	mutex_lock(&ad->amp_mutex);
488 	for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
489 		kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
490 		change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
491 	}
492 	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
493 	mutex_unlock(&ad->amp_mutex);
494 	return change;
495 }
496 
497 /*
498  * mixers
499  */
500 static struct snd_kcontrol_new ad1986a_mixers[] = {
501 	{
502 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
503 		.name = "PCM Playback Volume",
504 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
505 			  SNDRV_CTL_ELEM_ACCESS_TLV_READ |
506 			  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
507 		.info = ad1986a_pcm_amp_vol_info,
508 		.get = ad1986a_pcm_amp_vol_get,
509 		.put = ad1986a_pcm_amp_vol_put,
510 		.tlv = { .c = snd_hda_mixer_amp_tlv },
511 		.private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
512 	},
513 	{
514 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
515 		.name = "PCM Playback Switch",
516 		.info = ad1986a_pcm_amp_sw_info,
517 		.get = ad1986a_pcm_amp_sw_get,
518 		.put = ad1986a_pcm_amp_sw_put,
519 		.private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
520 	},
521 	HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
522 	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
523 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
524 	HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
525 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
526 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
527 	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
528 	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
529 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
530 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
531 	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
532 	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
533 	HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
534 	HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
535 	HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
536 	HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
537 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
538 	HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
539 	HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
540 	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
541 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
542 	HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
543 	HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
544 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
545 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
546 	{
547 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
548 		.name = "Capture Source",
549 		.info = ad198x_mux_enum_info,
550 		.get = ad198x_mux_enum_get,
551 		.put = ad198x_mux_enum_put,
552 	},
553 	HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
554 	{ } /* end */
555 };
556 
557 /* additional mixers for 3stack mode */
558 static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
559 	{
560 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
561 		.name = "Channel Mode",
562 		.info = ad198x_ch_mode_info,
563 		.get = ad198x_ch_mode_get,
564 		.put = ad198x_ch_mode_put,
565 	},
566 	{ } /* end */
567 };
568 
569 /* laptop model - 2ch only */
570 static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
571 
572 static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
573 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
574 	HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
575 	HDA_CODEC_VOLUME("Master Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
576 	HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
577 	/* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
578 	   HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), */
579 	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
580 	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
581 	HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
582 	HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
583 	HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
584 	HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
585 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
586 	HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
587 	HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
588 	/* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
589 	   HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
590 	   HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
591 	   HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
592 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
593 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
594 	{
595 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
596 		.name = "Capture Source",
597 		.info = ad198x_mux_enum_info,
598 		.get = ad198x_mux_enum_get,
599 		.put = ad198x_mux_enum_put,
600 	},
601 	{ } /* end */
602 };
603 
604 /* laptop-eapd model - 2ch only */
605 
606 /* master controls both pins 0x1a and 0x1b */
607 static int ad1986a_laptop_master_vol_put(struct snd_kcontrol *kcontrol,
608 					 struct snd_ctl_elem_value *ucontrol)
609 {
610 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
611 	long *valp = ucontrol->value.integer.value;
612 	int change;
613 
614 	change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
615 					  0x7f, valp[0] & 0x7f);
616 	change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
617 					   0x7f, valp[1] & 0x7f);
618 	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
619 				 0x7f, valp[0] & 0x7f);
620 	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
621 				 0x7f, valp[1] & 0x7f);
622 	return change;
623 }
624 
625 static int ad1986a_laptop_master_sw_put(struct snd_kcontrol *kcontrol,
626 					struct snd_ctl_elem_value *ucontrol)
627 {
628 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
629 	long *valp = ucontrol->value.integer.value;
630 	int change;
631 
632 	change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
633 					  0x80, valp[0] ? 0 : 0x80);
634 	change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
635 					   0x80, valp[1] ? 0 : 0x80);
636 	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
637 				 0x80, valp[0] ? 0 : 0x80);
638 	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
639 				 0x80, valp[1] ? 0 : 0x80);
640 	return change;
641 }
642 
643 static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
644 	.num_items = 3,
645 	.items = {
646 		{ "Mic", 0x0 },
647 		{ "Internal Mic", 0x4 },
648 		{ "Mix", 0x5 },
649 	},
650 };
651 
652 static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
653 	{
654 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
655 		.name = "Master Playback Volume",
656 		.info = snd_hda_mixer_amp_volume_info,
657 		.get = snd_hda_mixer_amp_volume_get,
658 		.put = ad1986a_laptop_master_vol_put,
659 		.tlv = { .c = snd_hda_mixer_amp_tlv },
660 		.private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
661 	},
662 	{
663 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
664 		.name = "Master Playback Switch",
665 		.info = snd_hda_mixer_amp_switch_info,
666 		.get = snd_hda_mixer_amp_switch_get,
667 		.put = ad1986a_laptop_master_sw_put,
668 		.private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
669 	},
670 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
671 	HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
672 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
673 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
674 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
675 	HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
676 	HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
677 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
678 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
679 	{
680 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
681 		.name = "Capture Source",
682 		.info = ad198x_mux_enum_info,
683 		.get = ad198x_mux_enum_get,
684 		.put = ad198x_mux_enum_put,
685 	},
686 	{
687 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
688 		.name = "External Amplifier",
689 		.info = ad198x_eapd_info,
690 		.get = ad198x_eapd_get,
691 		.put = ad198x_eapd_put,
692 		.private_value = 0x1b | (1 << 8), /* port-D, inversed */
693 	},
694 	{ } /* end */
695 };
696 
697 /*
698  * initialization verbs
699  */
700 static struct hda_verb ad1986a_init_verbs[] = {
701 	/* Front, Surround, CLFE DAC; mute as default */
702 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
703 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
704 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
705 	/* Downmix - off */
706 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
707 	/* HP, Line-Out, Surround, CLFE selectors */
708 	{0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
709 	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
710 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
711 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
712 	/* Mono selector */
713 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
714 	/* Mic selector: Mic 1/2 pin */
715 	{0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
716 	/* Line-in selector: Line-in */
717 	{0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
718 	/* Mic 1/2 swap */
719 	{0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
720 	/* Record selector: mic */
721 	{0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
722 	/* Mic, Phone, CD, Aux, Line-In amp; mute as default */
723 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
724 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
725 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
726 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
727 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
728 	/* PC beep */
729 	{0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
730 	/* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
731 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
732 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
733 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
734 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
735 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
736 	/* HP Pin */
737 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
738 	/* Front, Surround, CLFE Pins */
739 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
740 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
741 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
742 	/* Mono Pin */
743 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
744 	/* Mic Pin */
745 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
746 	/* Line, Aux, CD, Beep-In Pin */
747 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
748 	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
749 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
750 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
751 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
752 	{ } /* end */
753 };
754 
755 static struct hda_verb ad1986a_ch2_init[] = {
756 	/* Surround out -> Line In */
757 	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
758  	/* Line-in selectors */
759 	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
760 	/* CLFE -> Mic in */
761 	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
762 	/* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
763 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
764 	{ } /* end */
765 };
766 
767 static struct hda_verb ad1986a_ch4_init[] = {
768 	/* Surround out -> Surround */
769 	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
770 	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
771 	/* CLFE -> Mic in */
772 	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
773 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
774 	{ } /* end */
775 };
776 
777 static struct hda_verb ad1986a_ch6_init[] = {
778 	/* Surround out -> Surround out */
779 	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
780 	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
781 	/* CLFE -> CLFE */
782 	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
783 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
784 	{ } /* end */
785 };
786 
787 static struct hda_channel_mode ad1986a_modes[3] = {
788 	{ 2, ad1986a_ch2_init },
789 	{ 4, ad1986a_ch4_init },
790 	{ 6, ad1986a_ch6_init },
791 };
792 
793 /* eapd initialization */
794 static struct hda_verb ad1986a_eapd_init_verbs[] = {
795 	{0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
796 	{}
797 };
798 
799 /* Ultra initialization */
800 static struct hda_verb ad1986a_ultra_init[] = {
801 	/* eapd initialization */
802 	{ 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
803 	/* CLFE -> Mic in */
804 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
805 	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
806 	{ 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
807 	{ } /* end */
808 };
809 
810 /* models */
811 enum {
812 	AD1986A_6STACK,
813 	AD1986A_3STACK,
814 	AD1986A_LAPTOP,
815 	AD1986A_LAPTOP_EAPD,
816 	AD1986A_ULTRA,
817 	AD1986A_MODELS
818 };
819 
820 static const char *ad1986a_models[AD1986A_MODELS] = {
821 	[AD1986A_6STACK]	= "6stack",
822 	[AD1986A_3STACK]	= "3stack",
823 	[AD1986A_LAPTOP]	= "laptop",
824 	[AD1986A_LAPTOP_EAPD]	= "laptop-eapd",
825 	[AD1986A_ULTRA]		= "ultra",
826 };
827 
828 static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
829 	SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
830 	SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
831 	SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
832 	SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
833 	SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
834 	SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
835 	SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
836 	SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
837 	SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
838 	SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
839 	SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
840 	SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
841 	SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
842 	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
843 	SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
844 	SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
845 	SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
846 	SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD),
847 	SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD),
848 	SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD),
849 	SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
850 	SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
851 	SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
852 	SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
853 	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD),
854 	SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
855 	{}
856 };
857 
858 static int patch_ad1986a(struct hda_codec *codec)
859 {
860 	struct ad198x_spec *spec;
861 	int board_config;
862 
863 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
864 	if (spec == NULL)
865 		return -ENOMEM;
866 
867 	mutex_init(&spec->amp_mutex);
868 	codec->spec = spec;
869 
870 	spec->multiout.max_channels = 6;
871 	spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
872 	spec->multiout.dac_nids = ad1986a_dac_nids;
873 	spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
874 	spec->num_adc_nids = 1;
875 	spec->adc_nids = ad1986a_adc_nids;
876 	spec->capsrc_nids = ad1986a_capsrc_nids;
877 	spec->input_mux = &ad1986a_capture_source;
878 	spec->num_mixers = 1;
879 	spec->mixers[0] = ad1986a_mixers;
880 	spec->num_init_verbs = 1;
881 	spec->init_verbs[0] = ad1986a_init_verbs;
882 
883 	codec->patch_ops = ad198x_patch_ops;
884 
885 	/* override some parameters */
886 	board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
887 						  ad1986a_models,
888 						  ad1986a_cfg_tbl);
889 	switch (board_config) {
890 	case AD1986A_3STACK:
891 		spec->num_mixers = 2;
892 		spec->mixers[1] = ad1986a_3st_mixers;
893 		spec->num_init_verbs = 2;
894 		spec->init_verbs[1] = ad1986a_ch2_init;
895 		spec->channel_mode = ad1986a_modes;
896 		spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
897 		spec->need_dac_fix = 1;
898 		spec->multiout.max_channels = 2;
899 		spec->multiout.num_dacs = 1;
900 		break;
901 	case AD1986A_LAPTOP:
902 		spec->mixers[0] = ad1986a_laptop_mixers;
903 		spec->multiout.max_channels = 2;
904 		spec->multiout.num_dacs = 1;
905 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
906 		break;
907 	case AD1986A_LAPTOP_EAPD:
908 		spec->mixers[0] = ad1986a_laptop_eapd_mixers;
909 		spec->num_init_verbs = 2;
910 		spec->init_verbs[1] = ad1986a_eapd_init_verbs;
911 		spec->multiout.max_channels = 2;
912 		spec->multiout.num_dacs = 1;
913 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
914 		spec->multiout.dig_out_nid = 0;
915 		spec->input_mux = &ad1986a_laptop_eapd_capture_source;
916 		break;
917 	case AD1986A_ULTRA:
918 		spec->mixers[0] = ad1986a_laptop_eapd_mixers;
919 		spec->num_init_verbs = 2;
920 		spec->init_verbs[1] = ad1986a_ultra_init;
921 		spec->multiout.max_channels = 2;
922 		spec->multiout.num_dacs = 1;
923 		spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
924 		spec->multiout.dig_out_nid = 0;
925 		break;
926 	}
927 
928 	return 0;
929 }
930 
931 /*
932  * AD1983 specific
933  */
934 
935 #define AD1983_SPDIF_OUT	0x02
936 #define AD1983_DAC		0x03
937 #define AD1983_ADC		0x04
938 
939 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
940 static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
941 static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
942 
943 static struct hda_input_mux ad1983_capture_source = {
944 	.num_items = 4,
945 	.items = {
946 		{ "Mic", 0x0 },
947 		{ "Line", 0x1 },
948 		{ "Mix", 0x2 },
949 		{ "Mix Mono", 0x3 },
950 	},
951 };
952 
953 /*
954  * SPDIF playback route
955  */
956 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
957 {
958 	static char *texts[] = { "PCM", "ADC" };
959 
960 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
961 	uinfo->count = 1;
962 	uinfo->value.enumerated.items = 2;
963 	if (uinfo->value.enumerated.item > 1)
964 		uinfo->value.enumerated.item = 1;
965 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
966 	return 0;
967 }
968 
969 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
970 {
971 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
972 	struct ad198x_spec *spec = codec->spec;
973 
974 	ucontrol->value.enumerated.item[0] = spec->spdif_route;
975 	return 0;
976 }
977 
978 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
979 {
980 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
981 	struct ad198x_spec *spec = codec->spec;
982 
983 	if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
984 		spec->spdif_route = ucontrol->value.enumerated.item[0];
985 		snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0,
986 				    AC_VERB_SET_CONNECT_SEL, spec->spdif_route);
987 		return 1;
988 	}
989 	return 0;
990 }
991 
992 static struct snd_kcontrol_new ad1983_mixers[] = {
993 	HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
994 	HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
995 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
996 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
997 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
998 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
999 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1000 	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1001 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1002 	HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1003 	HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1004 	HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1005 	HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
1006 	HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
1007 	HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
1008 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1009 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1010 	{
1011 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1012 		.name = "Capture Source",
1013 		.info = ad198x_mux_enum_info,
1014 		.get = ad198x_mux_enum_get,
1015 		.put = ad198x_mux_enum_put,
1016 	},
1017 	{
1018 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1019 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1020 		.info = ad1983_spdif_route_info,
1021 		.get = ad1983_spdif_route_get,
1022 		.put = ad1983_spdif_route_put,
1023 	},
1024 	{ } /* end */
1025 };
1026 
1027 static struct hda_verb ad1983_init_verbs[] = {
1028 	/* Front, HP, Mono; mute as default */
1029 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1030 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1031 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1032 	/* Beep, PCM, Mic, Line-In: mute */
1033 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1034 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1035 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1036 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1037 	/* Front, HP selectors; from Mix */
1038 	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1039 	{0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1040 	/* Mono selector; from Mix */
1041 	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1042 	/* Mic selector; Mic */
1043 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1044 	/* Line-in selector: Line-in */
1045 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1046 	/* Mic boost: 0dB */
1047 	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1048 	/* Record selector: mic */
1049 	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1050 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1051 	/* SPDIF route: PCM */
1052 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1053 	/* Front Pin */
1054 	{0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1055 	/* HP Pin */
1056 	{0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1057 	/* Mono Pin */
1058 	{0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1059 	/* Mic Pin */
1060 	{0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1061 	/* Line Pin */
1062 	{0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1063 	{ } /* end */
1064 };
1065 
1066 
1067 static int patch_ad1983(struct hda_codec *codec)
1068 {
1069 	struct ad198x_spec *spec;
1070 
1071 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1072 	if (spec == NULL)
1073 		return -ENOMEM;
1074 
1075 	mutex_init(&spec->amp_mutex);
1076 	codec->spec = spec;
1077 
1078 	spec->multiout.max_channels = 2;
1079 	spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1080 	spec->multiout.dac_nids = ad1983_dac_nids;
1081 	spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1082 	spec->num_adc_nids = 1;
1083 	spec->adc_nids = ad1983_adc_nids;
1084 	spec->capsrc_nids = ad1983_capsrc_nids;
1085 	spec->input_mux = &ad1983_capture_source;
1086 	spec->num_mixers = 1;
1087 	spec->mixers[0] = ad1983_mixers;
1088 	spec->num_init_verbs = 1;
1089 	spec->init_verbs[0] = ad1983_init_verbs;
1090 	spec->spdif_route = 0;
1091 
1092 	codec->patch_ops = ad198x_patch_ops;
1093 
1094 	return 0;
1095 }
1096 
1097 
1098 /*
1099  * AD1981 HD specific
1100  */
1101 
1102 #define AD1981_SPDIF_OUT	0x02
1103 #define AD1981_DAC		0x03
1104 #define AD1981_ADC		0x04
1105 
1106 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1107 static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1108 static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1109 
1110 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1111 static struct hda_input_mux ad1981_capture_source = {
1112 	.num_items = 7,
1113 	.items = {
1114 		{ "Front Mic", 0x0 },
1115 		{ "Line", 0x1 },
1116 		{ "Mix", 0x2 },
1117 		{ "Mix Mono", 0x3 },
1118 		{ "CD", 0x4 },
1119 		{ "Mic", 0x6 },
1120 		{ "Aux", 0x7 },
1121 	},
1122 };
1123 
1124 static struct snd_kcontrol_new ad1981_mixers[] = {
1125 	HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1126 	HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1127 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1128 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1129 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1130 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1131 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1132 	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1133 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1134 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1135 	HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1136 	HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1137 	HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1138 	HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1139 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1140 	HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1141 	HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1142 	HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1143 	HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1144 	HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
1145 	HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
1146 	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
1147 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1148 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1149 	{
1150 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1151 		.name = "Capture Source",
1152 		.info = ad198x_mux_enum_info,
1153 		.get = ad198x_mux_enum_get,
1154 		.put = ad198x_mux_enum_put,
1155 	},
1156 	/* identical with AD1983 */
1157 	{
1158 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1159 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1160 		.info = ad1983_spdif_route_info,
1161 		.get = ad1983_spdif_route_get,
1162 		.put = ad1983_spdif_route_put,
1163 	},
1164 	{ } /* end */
1165 };
1166 
1167 static struct hda_verb ad1981_init_verbs[] = {
1168 	/* Front, HP, Mono; mute as default */
1169 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1170 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1171 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1172 	/* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1173 	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1174 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1175 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1176 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1177 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1178 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1179 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1180 	/* Front, HP selectors; from Mix */
1181 	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1182 	{0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1183 	/* Mono selector; from Mix */
1184 	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1185 	/* Mic Mixer; select Front Mic */
1186 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1187 	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1188 	/* Mic boost: 0dB */
1189 	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1190 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1191 	/* Record selector: Front mic */
1192 	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1193 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1194 	/* SPDIF route: PCM */
1195 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1196 	/* Front Pin */
1197 	{0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1198 	/* HP Pin */
1199 	{0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1200 	/* Mono Pin */
1201 	{0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1202 	/* Front & Rear Mic Pins */
1203 	{0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1204 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1205 	/* Line Pin */
1206 	{0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1207 	/* Digital Beep */
1208 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1209 	/* Line-Out as Input: disabled */
1210 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1211 	{ } /* end */
1212 };
1213 
1214 /*
1215  * Patch for HP nx6320
1216  *
1217  * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1218  * speaker output enabled _and_ mute-LED off.
1219  */
1220 
1221 #define AD1981_HP_EVENT		0x37
1222 #define AD1981_MIC_EVENT	0x38
1223 
1224 static struct hda_verb ad1981_hp_init_verbs[] = {
1225 	{0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1226 	/* pin sensing on HP and Mic jacks */
1227 	{0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1228 	{0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1229 	{}
1230 };
1231 
1232 /* turn on/off EAPD (+ mute HP) as a master switch */
1233 static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1234 				   struct snd_ctl_elem_value *ucontrol)
1235 {
1236 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1237 	struct ad198x_spec *spec = codec->spec;
1238 
1239 	if (! ad198x_eapd_put(kcontrol, ucontrol))
1240 		return 0;
1241 
1242 	/* toggle HP mute appropriately */
1243 	snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0,
1244 				 0x80, spec->cur_eapd ? 0 : 0x80);
1245 	snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0,
1246 				 0x80, spec->cur_eapd ? 0 : 0x80);
1247 	return 1;
1248 }
1249 
1250 /* bind volumes of both NID 0x05 and 0x06 */
1251 static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol,
1252 				    struct snd_ctl_elem_value *ucontrol)
1253 {
1254 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1255 	long *valp = ucontrol->value.integer.value;
1256 	int change;
1257 
1258 	change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
1259 					  0x7f, valp[0] & 0x7f);
1260 	change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
1261 					   0x7f, valp[1] & 0x7f);
1262 	snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0,
1263 				 0x7f, valp[0] & 0x7f);
1264 	snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0,
1265 				 0x7f, valp[1] & 0x7f);
1266 	return change;
1267 }
1268 
1269 /* mute internal speaker if HP is plugged */
1270 static void ad1981_hp_automute(struct hda_codec *codec)
1271 {
1272 	unsigned int present;
1273 
1274 	present = snd_hda_codec_read(codec, 0x06, 0,
1275 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1276 	snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
1277 				 0x80, present ? 0x80 : 0);
1278 	snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
1279 				 0x80, present ? 0x80 : 0);
1280 }
1281 
1282 /* toggle input of built-in and mic jack appropriately */
1283 static void ad1981_hp_automic(struct hda_codec *codec)
1284 {
1285 	static struct hda_verb mic_jack_on[] = {
1286 		{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1287 		{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1288 		{}
1289 	};
1290 	static struct hda_verb mic_jack_off[] = {
1291 		{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1292 		{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1293 		{}
1294 	};
1295 	unsigned int present;
1296 
1297 	present = snd_hda_codec_read(codec, 0x08, 0,
1298 			    	 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1299 	if (present)
1300 		snd_hda_sequence_write(codec, mic_jack_on);
1301 	else
1302 		snd_hda_sequence_write(codec, mic_jack_off);
1303 }
1304 
1305 /* unsolicited event for HP jack sensing */
1306 static void ad1981_hp_unsol_event(struct hda_codec *codec,
1307 				  unsigned int res)
1308 {
1309 	res >>= 26;
1310 	switch (res) {
1311 	case AD1981_HP_EVENT:
1312 		ad1981_hp_automute(codec);
1313 		break;
1314 	case AD1981_MIC_EVENT:
1315 		ad1981_hp_automic(codec);
1316 		break;
1317 	}
1318 }
1319 
1320 static struct hda_input_mux ad1981_hp_capture_source = {
1321 	.num_items = 3,
1322 	.items = {
1323 		{ "Mic", 0x0 },
1324 		{ "Docking-Station", 0x1 },
1325 		{ "Mix", 0x2 },
1326 	},
1327 };
1328 
1329 static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1330 	{
1331 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1332 		.name = "Master Playback Volume",
1333 		.info = snd_hda_mixer_amp_volume_info,
1334 		.get = snd_hda_mixer_amp_volume_get,
1335 		.put = ad1981_hp_master_vol_put,
1336 		.private_value = HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1337 	},
1338 	{
1339 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1340 		.name = "Master Playback Switch",
1341 		.info = ad198x_eapd_info,
1342 		.get = ad198x_eapd_get,
1343 		.put = ad1981_hp_master_sw_put,
1344 		.private_value = 0x05,
1345 	},
1346 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1347 	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1348 #if 0
1349 	/* FIXME: analog mic/line loopback doesn't work with my tests...
1350 	 *        (although recording is OK)
1351 	 */
1352 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1353 	HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1354 	HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1355 	HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1356 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1357 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1358 	/* FIXME: does this laptop have analog CD connection? */
1359 	HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1360 	HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1361 #endif
1362 	HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1363 	HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT),
1364 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1365 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1366 	{
1367 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1368 		.name = "Capture Source",
1369 		.info = ad198x_mux_enum_info,
1370 		.get = ad198x_mux_enum_get,
1371 		.put = ad198x_mux_enum_put,
1372 	},
1373 	{ } /* end */
1374 };
1375 
1376 /* initialize jack-sensing, too */
1377 static int ad1981_hp_init(struct hda_codec *codec)
1378 {
1379 	ad198x_init(codec);
1380 	ad1981_hp_automute(codec);
1381 	ad1981_hp_automic(codec);
1382 	return 0;
1383 }
1384 
1385 /* configuration for Toshiba Laptops */
1386 static struct hda_verb ad1981_toshiba_init_verbs[] = {
1387 	{0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1388 	/* pin sensing on HP and Mic jacks */
1389 	{0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1390 	{0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1391 	{}
1392 };
1393 
1394 static struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1395 	HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1396 	HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1397 	{ }
1398 };
1399 
1400 /* configuration for Lenovo Thinkpad T60 */
1401 static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1402 	HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1403 	HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1404 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1405 	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1406 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1407 	HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1408 	HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1409 	HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1410 	HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1411 	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1412 	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1413 	{
1414 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1415 		.name = "Capture Source",
1416 		.info = ad198x_mux_enum_info,
1417 		.get = ad198x_mux_enum_get,
1418 		.put = ad198x_mux_enum_put,
1419 	},
1420 	/* identical with AD1983 */
1421 	{
1422 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1423 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1424 		.info = ad1983_spdif_route_info,
1425 		.get = ad1983_spdif_route_get,
1426 		.put = ad1983_spdif_route_put,
1427 	},
1428 	{ } /* end */
1429 };
1430 
1431 static struct hda_input_mux ad1981_thinkpad_capture_source = {
1432 	.num_items = 3,
1433 	.items = {
1434 		{ "Mic", 0x0 },
1435 		{ "Mix", 0x2 },
1436 		{ "CD", 0x4 },
1437 	},
1438 };
1439 
1440 /* models */
1441 enum {
1442 	AD1981_BASIC,
1443 	AD1981_HP,
1444 	AD1981_THINKPAD,
1445 	AD1981_TOSHIBA,
1446 	AD1981_MODELS
1447 };
1448 
1449 static const char *ad1981_models[AD1981_MODELS] = {
1450 	[AD1981_HP]		= "hp",
1451 	[AD1981_THINKPAD]	= "thinkpad",
1452 	[AD1981_BASIC]		= "basic",
1453 	[AD1981_TOSHIBA]	= "toshiba"
1454 };
1455 
1456 static struct snd_pci_quirk ad1981_cfg_tbl[] = {
1457 	/* All HP models */
1458 	SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
1459 	/* HP nx6320 (reversed SSID, H/W bug) */
1460 	SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
1461 	/* Lenovo Thinkpad T60/X60/Z6xx */
1462 	SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD),
1463 	SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1464 	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
1465 	{}
1466 };
1467 
1468 static int patch_ad1981(struct hda_codec *codec)
1469 {
1470 	struct ad198x_spec *spec;
1471 	int board_config;
1472 
1473 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1474 	if (spec == NULL)
1475 		return -ENOMEM;
1476 
1477 	mutex_init(&spec->amp_mutex);
1478 	codec->spec = spec;
1479 
1480 	spec->multiout.max_channels = 2;
1481 	spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
1482 	spec->multiout.dac_nids = ad1981_dac_nids;
1483 	spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
1484 	spec->num_adc_nids = 1;
1485 	spec->adc_nids = ad1981_adc_nids;
1486 	spec->capsrc_nids = ad1981_capsrc_nids;
1487 	spec->input_mux = &ad1981_capture_source;
1488 	spec->num_mixers = 1;
1489 	spec->mixers[0] = ad1981_mixers;
1490 	spec->num_init_verbs = 1;
1491 	spec->init_verbs[0] = ad1981_init_verbs;
1492 	spec->spdif_route = 0;
1493 
1494 	codec->patch_ops = ad198x_patch_ops;
1495 
1496 	/* override some parameters */
1497 	board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
1498 						  ad1981_models,
1499 						  ad1981_cfg_tbl);
1500 	switch (board_config) {
1501 	case AD1981_HP:
1502 		spec->mixers[0] = ad1981_hp_mixers;
1503 		spec->num_init_verbs = 2;
1504 		spec->init_verbs[1] = ad1981_hp_init_verbs;
1505 		spec->multiout.dig_out_nid = 0;
1506 		spec->input_mux = &ad1981_hp_capture_source;
1507 
1508 		codec->patch_ops.init = ad1981_hp_init;
1509 		codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1510 		break;
1511 	case AD1981_THINKPAD:
1512 		spec->mixers[0] = ad1981_thinkpad_mixers;
1513 		spec->input_mux = &ad1981_thinkpad_capture_source;
1514 		break;
1515 	case AD1981_TOSHIBA:
1516 		spec->mixers[0] = ad1981_hp_mixers;
1517 		spec->mixers[1] = ad1981_toshiba_mixers;
1518 		spec->num_init_verbs = 2;
1519 		spec->init_verbs[1] = ad1981_toshiba_init_verbs;
1520 		spec->multiout.dig_out_nid = 0;
1521 		spec->input_mux = &ad1981_hp_capture_source;
1522 		codec->patch_ops.init = ad1981_hp_init;
1523 		codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1524 		break;
1525 	}
1526 	return 0;
1527 }
1528 
1529 
1530 /*
1531  * AD1988
1532  *
1533  * Output pins and routes
1534  *
1535  *        Pin               Mix     Sel     DAC (*)
1536  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
1537  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
1538  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
1539  * port-D 0x12 (mute/hp) <- 0x29         <- 04
1540  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
1541  * port-F 0x16 (mute)    <- 0x2a         <- 06
1542  * port-G 0x24 (mute)    <- 0x27         <- 05
1543  * port-H 0x25 (mute)    <- 0x28         <- 0a
1544  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
1545  *
1546  * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
1547  * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
1548  *
1549  * Input pins and routes
1550  *
1551  *        pin     boost   mix input # / adc input #
1552  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
1553  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
1554  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
1555  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
1556  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
1557  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
1558  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
1559  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
1560  *
1561  *
1562  * DAC assignment
1563  *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
1564  *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
1565  *
1566  * Inputs of Analog Mix (0x20)
1567  *   0:Port-B (front mic)
1568  *   1:Port-C/G/H (line-in)
1569  *   2:Port-A
1570  *   3:Port-D (line-in/2)
1571  *   4:Port-E/G/H (mic-in)
1572  *   5:Port-F (mic2-in)
1573  *   6:CD
1574  *   7:Beep
1575  *
1576  * ADC selection
1577  *   0:Port-A
1578  *   1:Port-B (front mic-in)
1579  *   2:Port-C (line-in)
1580  *   3:Port-F (mic2-in)
1581  *   4:Port-E (mic-in)
1582  *   5:CD
1583  *   6:Port-G
1584  *   7:Port-H
1585  *   8:Port-D (line-in/2)
1586  *   9:Mix
1587  *
1588  * Proposed pin assignments by the datasheet
1589  *
1590  * 6-stack
1591  * Port-A front headphone
1592  *      B front mic-in
1593  *      C rear line-in
1594  *      D rear front-out
1595  *      E rear mic-in
1596  *      F rear surround
1597  *      G rear CLFE
1598  *      H rear side
1599  *
1600  * 3-stack
1601  * Port-A front headphone
1602  *      B front mic
1603  *      C rear line-in/surround
1604  *      D rear front-out
1605  *      E rear mic-in/CLFE
1606  *
1607  * laptop
1608  * Port-A headphone
1609  *      B mic-in
1610  *      C docking station
1611  *      D internal speaker (with EAPD)
1612  *      E/F quad mic array
1613  */
1614 
1615 
1616 /* models */
1617 enum {
1618 	AD1988_6STACK,
1619 	AD1988_6STACK_DIG,
1620 	AD1988_3STACK,
1621 	AD1988_3STACK_DIG,
1622 	AD1988_LAPTOP,
1623 	AD1988_LAPTOP_DIG,
1624 	AD1988_AUTO,
1625 	AD1988_MODEL_LAST,
1626 };
1627 
1628 /* reivision id to check workarounds */
1629 #define AD1988A_REV2		0x100200
1630 
1631 #define is_rev2(codec) \
1632 	((codec)->vendor_id == 0x11d41988 && \
1633 	 (codec)->revision_id == AD1988A_REV2)
1634 
1635 /*
1636  * mixers
1637  */
1638 
1639 static hda_nid_t ad1988_6stack_dac_nids[4] = {
1640 	0x04, 0x06, 0x05, 0x0a
1641 };
1642 
1643 static hda_nid_t ad1988_3stack_dac_nids[3] = {
1644 	0x04, 0x05, 0x0a
1645 };
1646 
1647 /* for AD1988A revision-2, DAC2-4 are swapped */
1648 static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
1649 	0x04, 0x05, 0x0a, 0x06
1650 };
1651 
1652 static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
1653 	0x04, 0x0a, 0x06
1654 };
1655 
1656 static hda_nid_t ad1988_adc_nids[3] = {
1657 	0x08, 0x09, 0x0f
1658 };
1659 
1660 static hda_nid_t ad1988_capsrc_nids[3] = {
1661 	0x0c, 0x0d, 0x0e
1662 };
1663 
1664 #define AD1988_SPDIF_OUT	0x02
1665 #define AD1988_SPDIF_IN		0x07
1666 
1667 static struct hda_input_mux ad1988_6stack_capture_source = {
1668 	.num_items = 5,
1669 	.items = {
1670 		{ "Front Mic", 0x0 },
1671 		{ "Line", 0x1 },
1672 		{ "Mic", 0x4 },
1673 		{ "CD", 0x5 },
1674 		{ "Mix", 0x9 },
1675 	},
1676 };
1677 
1678 static struct hda_input_mux ad1988_laptop_capture_source = {
1679 	.num_items = 3,
1680 	.items = {
1681 		{ "Mic/Line", 0x0 },
1682 		{ "CD", 0x5 },
1683 		{ "Mix", 0x9 },
1684 	},
1685 };
1686 
1687 /*
1688  */
1689 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
1690 			       struct snd_ctl_elem_info *uinfo)
1691 {
1692 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1693 	struct ad198x_spec *spec = codec->spec;
1694 	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
1695 				    spec->num_channel_mode);
1696 }
1697 
1698 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
1699 			      struct snd_ctl_elem_value *ucontrol)
1700 {
1701 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1702 	struct ad198x_spec *spec = codec->spec;
1703 	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
1704 				   spec->num_channel_mode, spec->multiout.max_channels);
1705 }
1706 
1707 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
1708 			      struct snd_ctl_elem_value *ucontrol)
1709 {
1710 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1711 	struct ad198x_spec *spec = codec->spec;
1712 	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
1713 				      spec->num_channel_mode,
1714 				      &spec->multiout.max_channels);
1715 	if (err >= 0 && spec->need_dac_fix)
1716 		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
1717 	return err;
1718 }
1719 
1720 /* 6-stack mode */
1721 static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
1722 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1723 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1724 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1725 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1726 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1727 	{ } /* end */
1728 };
1729 
1730 static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
1731 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1732 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1733 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1734 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
1735 	HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1736 	{ } /* end */
1737 };
1738 
1739 static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
1740 	HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1741 	HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
1742 	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
1743 	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
1744 	HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
1745 	HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1746 	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1747 
1748 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1749 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1750 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1751 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1752 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1753 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1754 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
1755 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
1756 
1757 	HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1758 	HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1759 
1760 	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1761 	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1762 
1763 	HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1764 	HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
1765 
1766 	{ } /* end */
1767 };
1768 
1769 /* 3-stack mode */
1770 static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
1771 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1772 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1773 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
1774 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
1775 	{ } /* end */
1776 };
1777 
1778 static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
1779 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1780 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
1781 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
1782 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
1783 	{ } /* end */
1784 };
1785 
1786 static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
1787 	HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
1788 	HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
1789 	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
1790 	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
1791 	HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
1792 	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1793 
1794 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1795 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1796 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1797 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1798 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1799 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1800 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
1801 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
1802 
1803 	HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1804 	HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1805 
1806 	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1807 	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1808 
1809 	HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1810 	HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
1811 	{
1812 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1813 		.name = "Channel Mode",
1814 		.info = ad198x_ch_mode_info,
1815 		.get = ad198x_ch_mode_get,
1816 		.put = ad198x_ch_mode_put,
1817 	},
1818 
1819 	{ } /* end */
1820 };
1821 
1822 /* laptop mode */
1823 static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
1824 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
1825 	HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
1826 	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
1827 
1828 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
1829 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
1830 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
1831 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
1832 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
1833 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
1834 
1835 	HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
1836 	HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1837 
1838 	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
1839 	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
1840 
1841 	HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT),
1842 
1843 	{
1844 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1845 		.name = "External Amplifier",
1846 		.info = ad198x_eapd_info,
1847 		.get = ad198x_eapd_get,
1848 		.put = ad198x_eapd_put,
1849 		.private_value = 0x12 | (1 << 8), /* port-D, inversed */
1850 	},
1851 
1852 	{ } /* end */
1853 };
1854 
1855 /* capture */
1856 static struct snd_kcontrol_new ad1988_capture_mixers[] = {
1857 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
1858 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
1859 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
1860 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
1861 	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
1862 	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
1863 	{
1864 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1865 		/* The multiple "Capture Source" controls confuse alsamixer
1866 		 * So call somewhat different..
1867 		 * FIXME: the controls appear in the "playback" view!
1868 		 */
1869 		/* .name = "Capture Source", */
1870 		.name = "Input Source",
1871 		.count = 3,
1872 		.info = ad198x_mux_enum_info,
1873 		.get = ad198x_mux_enum_get,
1874 		.put = ad198x_mux_enum_put,
1875 	},
1876 	{ } /* end */
1877 };
1878 
1879 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
1880 					     struct snd_ctl_elem_info *uinfo)
1881 {
1882 	static char *texts[] = {
1883 		"PCM", "ADC1", "ADC2", "ADC3"
1884 	};
1885 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1886 	uinfo->count = 1;
1887 	uinfo->value.enumerated.items = 4;
1888 	if (uinfo->value.enumerated.item >= 4)
1889 		uinfo->value.enumerated.item = 3;
1890 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1891 	return 0;
1892 }
1893 
1894 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
1895 					    struct snd_ctl_elem_value *ucontrol)
1896 {
1897 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1898 	unsigned int sel;
1899 
1900 	sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
1901 	if (sel > 0) {
1902 		sel = snd_hda_codec_read(codec, 0x0b, 0,
1903 					 AC_VERB_GET_CONNECT_SEL, 0);
1904 		if (sel < 3)
1905 			sel++;
1906 		else
1907 			sel = 0;
1908 	}
1909 	ucontrol->value.enumerated.item[0] = sel;
1910 	return 0;
1911 }
1912 
1913 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
1914 					    struct snd_ctl_elem_value *ucontrol)
1915 {
1916 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1917 	unsigned int val, sel;
1918 	int change;
1919 
1920 	val = ucontrol->value.enumerated.item[0];
1921 	sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
1922 	if (!val) {
1923 		change = sel != 0;
1924 		if (change || codec->in_resume)
1925 			snd_hda_codec_write(codec, 0x02, 0,
1926 					    AC_VERB_SET_CONNECT_SEL, 0);
1927 	} else {
1928 		change = sel == 0;
1929 		if (change || codec->in_resume)
1930 			snd_hda_codec_write(codec, 0x02, 0,
1931 					    AC_VERB_SET_CONNECT_SEL, 1);
1932 		sel = snd_hda_codec_read(codec, 0x0b, 0,
1933 					 AC_VERB_GET_CONNECT_SEL, 0) + 1;
1934 		change |= sel != val;
1935 		if (change || codec->in_resume)
1936 			snd_hda_codec_write(codec, 0x0b, 0,
1937 					    AC_VERB_SET_CONNECT_SEL, val - 1);
1938 	}
1939 	return change;
1940 }
1941 
1942 static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
1943 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1944 	{
1945 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1946 		.name = "IEC958 Playback Source",
1947 		.info = ad1988_spdif_playback_source_info,
1948 		.get = ad1988_spdif_playback_source_get,
1949 		.put = ad1988_spdif_playback_source_put,
1950 	},
1951 	{ } /* end */
1952 };
1953 
1954 static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
1955 	HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
1956 	{ } /* end */
1957 };
1958 
1959 
1960 /*
1961  * initialization verbs
1962  */
1963 
1964 /*
1965  * for 6-stack (+dig)
1966  */
1967 static struct hda_verb ad1988_6stack_init_verbs[] = {
1968 	/* Front, Surround, CLFE, side DAC; unmute as default */
1969 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1970 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1971 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1972 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1973 	/* Port-A front headphon path */
1974 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
1975 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1976 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1977 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1978 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1979 	/* Port-D line-out path */
1980 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1981 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1982 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1983 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1984 	/* Port-F surround path */
1985 	{0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1986 	{0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1987 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1988 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1989 	/* Port-G CLFE path */
1990 	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1991 	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1992 	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1993 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1994 	/* Port-H side path */
1995 	{0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1996 	{0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1997 	{0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1998 	{0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1999 	/* Mono out path */
2000 	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2001 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2002 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2003 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2004 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2005 	/* Port-B front mic-in path */
2006 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2007 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2008 	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2009 	/* Port-C line-in path */
2010 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2011 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2012 	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2013 	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2014 	/* Port-E mic-in path */
2015 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2016 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2017 	{0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2018 	{0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2019 
2020 	{ }
2021 };
2022 
2023 static struct hda_verb ad1988_capture_init_verbs[] = {
2024 	/* mute analog mix */
2025 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2026 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2027 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2028 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2029 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2030 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2031 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2032 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2033 	/* select ADCs - front-mic */
2034 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2035 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2036 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2037 	/* ADCs; muted */
2038 	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2039 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2040 	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2041 
2042 	{ }
2043 };
2044 
2045 static struct hda_verb ad1988_spdif_init_verbs[] = {
2046 	/* SPDIF out sel */
2047 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2048 	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2049 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2050 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2051 	/* SPDIF out pin */
2052 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2053 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x17}, /* 0dB */
2054 
2055 	{ }
2056 };
2057 
2058 /*
2059  * verbs for 3stack (+dig)
2060  */
2061 static struct hda_verb ad1988_3stack_ch2_init[] = {
2062 	/* set port-C to line-in */
2063 	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2064 	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2065 	/* set port-E to mic-in */
2066 	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2067 	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2068 	{ } /* end */
2069 };
2070 
2071 static struct hda_verb ad1988_3stack_ch6_init[] = {
2072 	/* set port-C to surround out */
2073 	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2074 	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2075 	/* set port-E to CLFE out */
2076 	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2077 	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2078 	{ } /* end */
2079 };
2080 
2081 static struct hda_channel_mode ad1988_3stack_modes[2] = {
2082 	{ 2, ad1988_3stack_ch2_init },
2083 	{ 6, ad1988_3stack_ch6_init },
2084 };
2085 
2086 static struct hda_verb ad1988_3stack_init_verbs[] = {
2087 	/* Front, Surround, CLFE, side DAC; unmute as default */
2088 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2089 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2090 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2091 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2092 	/* Port-A front headphon path */
2093 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2094 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2095 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2096 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2097 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2098 	/* Port-D line-out path */
2099 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2100 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2101 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2102 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2103 	/* Mono out path */
2104 	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2105 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2106 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2107 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2108 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2109 	/* Port-B front mic-in path */
2110 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2111 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2112 	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2113 	/* Port-C line-in/surround path - 6ch mode as default */
2114 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2115 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2116 	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2117 	{0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2118 	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2119 	/* Port-E mic-in/CLFE path - 6ch mode as default */
2120 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2121 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2122 	{0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2123 	{0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2124 	{0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2125 	/* mute analog mix */
2126 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2127 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2128 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2129 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2130 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2131 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2132 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2133 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2134 	/* select ADCs - front-mic */
2135 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2136 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2137 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2138 	/* ADCs; muted */
2139 	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2140 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2141 	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2142 	{ }
2143 };
2144 
2145 /*
2146  * verbs for laptop mode (+dig)
2147  */
2148 static struct hda_verb ad1988_laptop_hp_on[] = {
2149 	/* unmute port-A and mute port-D */
2150 	{ 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2151 	{ 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2152 	{ } /* end */
2153 };
2154 static struct hda_verb ad1988_laptop_hp_off[] = {
2155 	/* mute port-A and unmute port-D */
2156 	{ 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2157 	{ 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2158 	{ } /* end */
2159 };
2160 
2161 #define AD1988_HP_EVENT	0x01
2162 
2163 static struct hda_verb ad1988_laptop_init_verbs[] = {
2164 	/* Front, Surround, CLFE, side DAC; unmute as default */
2165 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2166 	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2167 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2168 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2169 	/* Port-A front headphon path */
2170 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2171 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2172 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2173 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2174 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2175 	/* unsolicited event for pin-sense */
2176 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2177 	/* Port-D line-out path + EAPD */
2178 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2179 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2180 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2181 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2182 	{0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2183 	/* Mono out path */
2184 	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2185 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2186 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2187 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2188 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2189 	/* Port-B mic-in path */
2190 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2191 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2192 	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2193 	/* Port-C docking station - try to output */
2194 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2195 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2196 	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2197 	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2198 	/* mute analog mix */
2199 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2200 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2201 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2202 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2203 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2204 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2205 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2206 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2207 	/* select ADCs - mic */
2208 	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2209 	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2210 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2211 	/* ADCs; muted */
2212 	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2213 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2214 	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2215 	{ }
2216 };
2217 
2218 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2219 {
2220 	if ((res >> 26) != AD1988_HP_EVENT)
2221 		return;
2222 	if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31))
2223 		snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2224 	else
2225 		snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2226 }
2227 
2228 
2229 /*
2230  * Automatic parse of I/O pins from the BIOS configuration
2231  */
2232 
2233 #define NUM_CONTROL_ALLOC	32
2234 #define NUM_VERB_ALLOC		32
2235 
2236 enum {
2237 	AD_CTL_WIDGET_VOL,
2238 	AD_CTL_WIDGET_MUTE,
2239 	AD_CTL_BIND_MUTE,
2240 };
2241 static struct snd_kcontrol_new ad1988_control_templates[] = {
2242 	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2243 	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2244 	HDA_BIND_MUTE(NULL, 0, 0, 0),
2245 };
2246 
2247 /* add dynamic controls */
2248 static int add_control(struct ad198x_spec *spec, int type, const char *name,
2249 		       unsigned long val)
2250 {
2251 	struct snd_kcontrol_new *knew;
2252 
2253 	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2254 		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2255 
2256 		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2257 		if (! knew)
2258 			return -ENOMEM;
2259 		if (spec->kctl_alloc) {
2260 			memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2261 			kfree(spec->kctl_alloc);
2262 		}
2263 		spec->kctl_alloc = knew;
2264 		spec->num_kctl_alloc = num;
2265 	}
2266 
2267 	knew = &spec->kctl_alloc[spec->num_kctl_used];
2268 	*knew = ad1988_control_templates[type];
2269 	knew->name = kstrdup(name, GFP_KERNEL);
2270 	if (! knew->name)
2271 		return -ENOMEM;
2272 	knew->private_value = val;
2273 	spec->num_kctl_used++;
2274 	return 0;
2275 }
2276 
2277 #define AD1988_PIN_CD_NID		0x18
2278 #define AD1988_PIN_BEEP_NID		0x10
2279 
2280 static hda_nid_t ad1988_mixer_nids[8] = {
2281 	/* A     B     C     D     E     F     G     H */
2282 	0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2283 };
2284 
2285 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2286 {
2287 	static hda_nid_t idx_to_dac[8] = {
2288 		/* A     B     C     D     E     F     G     H */
2289 		0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2290 	};
2291 	static hda_nid_t idx_to_dac_rev2[8] = {
2292 		/* A     B     C     D     E     F     G     H */
2293 		0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2294 	};
2295 	if (is_rev2(codec))
2296 		return idx_to_dac_rev2[idx];
2297 	else
2298 		return idx_to_dac[idx];
2299 }
2300 
2301 static hda_nid_t ad1988_boost_nids[8] = {
2302 	0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2303 };
2304 
2305 static int ad1988_pin_idx(hda_nid_t nid)
2306 {
2307 	static hda_nid_t ad1988_io_pins[8] = {
2308 		0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2309 	};
2310 	int i;
2311 	for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2312 		if (ad1988_io_pins[i] == nid)
2313 			return i;
2314 	return 0; /* should be -1 */
2315 }
2316 
2317 static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2318 {
2319 	static int loopback_idx[8] = {
2320 		2, 0, 1, 3, 4, 5, 1, 4
2321 	};
2322 	switch (nid) {
2323 	case AD1988_PIN_CD_NID:
2324 		return 6;
2325 	default:
2326 		return loopback_idx[ad1988_pin_idx(nid)];
2327 	}
2328 }
2329 
2330 static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2331 {
2332 	static int adc_idx[8] = {
2333 		0, 1, 2, 8, 4, 3, 6, 7
2334 	};
2335 	switch (nid) {
2336 	case AD1988_PIN_CD_NID:
2337 		return 5;
2338 	default:
2339 		return adc_idx[ad1988_pin_idx(nid)];
2340 	}
2341 }
2342 
2343 /* fill in the dac_nids table from the parsed pin configuration */
2344 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2345 				     const struct auto_pin_cfg *cfg)
2346 {
2347 	struct ad198x_spec *spec = codec->spec;
2348 	int i, idx;
2349 
2350 	spec->multiout.dac_nids = spec->private_dac_nids;
2351 
2352 	/* check the pins hardwired to audio widget */
2353 	for (i = 0; i < cfg->line_outs; i++) {
2354 		idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2355 		spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2356 	}
2357 	spec->multiout.num_dacs = cfg->line_outs;
2358 	return 0;
2359 }
2360 
2361 /* add playback controls from the parsed DAC table */
2362 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2363 					     const struct auto_pin_cfg *cfg)
2364 {
2365 	char name[32];
2366 	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2367 	hda_nid_t nid;
2368 	int i, err;
2369 
2370 	for (i = 0; i < cfg->line_outs; i++) {
2371 		hda_nid_t dac = spec->multiout.dac_nids[i];
2372 		if (! dac)
2373 			continue;
2374 		nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2375 		if (i == 2) {
2376 			/* Center/LFE */
2377 			err = add_control(spec, AD_CTL_WIDGET_VOL,
2378 					  "Center Playback Volume",
2379 					  HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2380 			if (err < 0)
2381 				return err;
2382 			err = add_control(spec, AD_CTL_WIDGET_VOL,
2383 					  "LFE Playback Volume",
2384 					  HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2385 			if (err < 0)
2386 				return err;
2387 			err = add_control(spec, AD_CTL_BIND_MUTE,
2388 					  "Center Playback Switch",
2389 					  HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2390 			if (err < 0)
2391 				return err;
2392 			err = add_control(spec, AD_CTL_BIND_MUTE,
2393 					  "LFE Playback Switch",
2394 					  HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2395 			if (err < 0)
2396 				return err;
2397 		} else {
2398 			sprintf(name, "%s Playback Volume", chname[i]);
2399 			err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2400 					  HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2401 			if (err < 0)
2402 				return err;
2403 			sprintf(name, "%s Playback Switch", chname[i]);
2404 			err = add_control(spec, AD_CTL_BIND_MUTE, name,
2405 					  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2406 			if (err < 0)
2407 				return err;
2408 		}
2409 	}
2410 	return 0;
2411 }
2412 
2413 /* add playback controls for speaker and HP outputs */
2414 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2415 					const char *pfx)
2416 {
2417 	struct ad198x_spec *spec = codec->spec;
2418 	hda_nid_t nid;
2419 	int idx, err;
2420 	char name[32];
2421 
2422 	if (! pin)
2423 		return 0;
2424 
2425 	idx = ad1988_pin_idx(pin);
2426 	nid = ad1988_idx_to_dac(codec, idx);
2427 	/* specify the DAC as the extra output */
2428 	if (! spec->multiout.hp_nid)
2429 		spec->multiout.hp_nid = nid;
2430 	else
2431 		spec->multiout.extra_out_nid[0] = nid;
2432 	/* control HP volume/switch on the output mixer amp */
2433 	sprintf(name, "%s Playback Volume", pfx);
2434 	if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2435 			       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2436 		return err;
2437 	nid = ad1988_mixer_nids[idx];
2438 	sprintf(name, "%s Playback Switch", pfx);
2439 	if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
2440 			       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2441 		return err;
2442 	return 0;
2443 }
2444 
2445 /* create input playback/capture controls for the given pin */
2446 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2447 			    const char *ctlname, int boost)
2448 {
2449 	char name[32];
2450 	int err, idx;
2451 
2452 	sprintf(name, "%s Playback Volume", ctlname);
2453 	idx = ad1988_pin_to_loopback_idx(pin);
2454 	if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2455 			       HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2456 		return err;
2457 	sprintf(name, "%s Playback Switch", ctlname);
2458 	if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
2459 			       HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2460 		return err;
2461 	if (boost) {
2462 		hda_nid_t bnid;
2463 		idx = ad1988_pin_idx(pin);
2464 		bnid = ad1988_boost_nids[idx];
2465 		if (bnid) {
2466 			sprintf(name, "%s Boost", ctlname);
2467 			return add_control(spec, AD_CTL_WIDGET_VOL, name,
2468 					   HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2469 
2470 		}
2471 	}
2472 	return 0;
2473 }
2474 
2475 /* create playback/capture controls for input pins */
2476 static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
2477 						const struct auto_pin_cfg *cfg)
2478 {
2479 	struct hda_input_mux *imux = &spec->private_imux;
2480 	int i, err;
2481 
2482 	for (i = 0; i < AUTO_PIN_LAST; i++) {
2483 		err = new_analog_input(spec, cfg->input_pins[i],
2484 				       auto_pin_cfg_labels[i],
2485 				       i <= AUTO_PIN_FRONT_MIC);
2486 		if (err < 0)
2487 			return err;
2488 		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2489 		imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
2490 		imux->num_items++;
2491 	}
2492 	imux->items[imux->num_items].label = "Mix";
2493 	imux->items[imux->num_items].index = 9;
2494 	imux->num_items++;
2495 
2496 	if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
2497 			       "Analog Mix Playback Volume",
2498 			       HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2499 		return err;
2500 	if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
2501 			       "Analog Mix Playback Switch",
2502 			       HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
2503 		return err;
2504 
2505 	return 0;
2506 }
2507 
2508 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
2509 					      hda_nid_t nid, int pin_type,
2510 					      int dac_idx)
2511 {
2512 	/* set as output */
2513 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2514 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2515 	switch (nid) {
2516 	case 0x11: /* port-A - DAC 04 */
2517 		snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2518 		break;
2519 	case 0x14: /* port-B - DAC 06 */
2520 		snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
2521 		break;
2522 	case 0x15: /* port-C - DAC 05 */
2523 		snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
2524 		break;
2525 	case 0x17: /* port-E - DAC 0a */
2526 		snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2527 		break;
2528 	case 0x13: /* mono - DAC 04 */
2529 		snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
2530 		break;
2531 	}
2532 }
2533 
2534 static void ad1988_auto_init_multi_out(struct hda_codec *codec)
2535 {
2536 	struct ad198x_spec *spec = codec->spec;
2537 	int i;
2538 
2539 	for (i = 0; i < spec->autocfg.line_outs; i++) {
2540 		hda_nid_t nid = spec->autocfg.line_out_pins[i];
2541 		ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2542 	}
2543 }
2544 
2545 static void ad1988_auto_init_extra_out(struct hda_codec *codec)
2546 {
2547 	struct ad198x_spec *spec = codec->spec;
2548 	hda_nid_t pin;
2549 
2550 	pin = spec->autocfg.speaker_pins[0];
2551 	if (pin) /* connect to front */
2552 		ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2553 	pin = spec->autocfg.hp_pins[0];
2554 	if (pin) /* connect to front */
2555 		ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2556 }
2557 
2558 static void ad1988_auto_init_analog_input(struct hda_codec *codec)
2559 {
2560 	struct ad198x_spec *spec = codec->spec;
2561 	int i, idx;
2562 
2563 	for (i = 0; i < AUTO_PIN_LAST; i++) {
2564 		hda_nid_t nid = spec->autocfg.input_pins[i];
2565 		if (! nid)
2566 			continue;
2567 		switch (nid) {
2568 		case 0x15: /* port-C */
2569 			snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2570 			break;
2571 		case 0x17: /* port-E */
2572 			snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
2573 			break;
2574 		}
2575 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2576 				    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2577 		if (nid != AD1988_PIN_CD_NID)
2578 			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2579 					    AMP_OUT_MUTE);
2580 		idx = ad1988_pin_idx(nid);
2581 		if (ad1988_boost_nids[idx])
2582 			snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
2583 					    AC_VERB_SET_AMP_GAIN_MUTE,
2584 					    AMP_OUT_ZERO);
2585 	}
2586 }
2587 
2588 /* parse the BIOS configuration and set up the alc_spec */
2589 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */
2590 static int ad1988_parse_auto_config(struct hda_codec *codec)
2591 {
2592 	struct ad198x_spec *spec = codec->spec;
2593 	int err;
2594 
2595 	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
2596 		return err;
2597 	if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
2598 		return err;
2599 	if (! spec->autocfg.line_outs)
2600 		return 0; /* can't find valid BIOS pin config */
2601 	if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2602 	    (err = ad1988_auto_create_extra_out(codec,
2603 						spec->autocfg.speaker_pins[0],
2604 						"Speaker")) < 0 ||
2605 	    (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
2606 						"Headphone")) < 0 ||
2607 	    (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2608 		return err;
2609 
2610 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2611 
2612 	if (spec->autocfg.dig_out_pin)
2613 		spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2614 	if (spec->autocfg.dig_in_pin)
2615 		spec->dig_in_nid = AD1988_SPDIF_IN;
2616 
2617 	if (spec->kctl_alloc)
2618 		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2619 
2620 	spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
2621 
2622 	spec->input_mux = &spec->private_imux;
2623 
2624 	return 1;
2625 }
2626 
2627 /* init callback for auto-configuration model -- overriding the default init */
2628 static int ad1988_auto_init(struct hda_codec *codec)
2629 {
2630 	ad198x_init(codec);
2631 	ad1988_auto_init_multi_out(codec);
2632 	ad1988_auto_init_extra_out(codec);
2633 	ad1988_auto_init_analog_input(codec);
2634 	return 0;
2635 }
2636 
2637 
2638 /*
2639  */
2640 
2641 static const char *ad1988_models[AD1988_MODEL_LAST] = {
2642 	[AD1988_6STACK]		= "6stack",
2643 	[AD1988_6STACK_DIG]	= "6stack-dig",
2644 	[AD1988_3STACK]		= "3stack",
2645 	[AD1988_3STACK_DIG]	= "3stack-dig",
2646 	[AD1988_LAPTOP]		= "laptop",
2647 	[AD1988_LAPTOP_DIG]	= "laptop-dig",
2648 	[AD1988_AUTO]		= "auto",
2649 };
2650 
2651 static struct snd_pci_quirk ad1988_cfg_tbl[] = {
2652 	SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
2653 	SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
2654 	{}
2655 };
2656 
2657 static int patch_ad1988(struct hda_codec *codec)
2658 {
2659 	struct ad198x_spec *spec;
2660 	int board_config;
2661 
2662 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2663 	if (spec == NULL)
2664 		return -ENOMEM;
2665 
2666 	mutex_init(&spec->amp_mutex);
2667 	codec->spec = spec;
2668 
2669 	if (is_rev2(codec))
2670 		snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
2671 
2672 	board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
2673 						  ad1988_models, ad1988_cfg_tbl);
2674 	if (board_config < 0) {
2675 		printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
2676 		board_config = AD1988_AUTO;
2677 	}
2678 
2679 	if (board_config == AD1988_AUTO) {
2680 		/* automatic parse from the BIOS config */
2681 		int err = ad1988_parse_auto_config(codec);
2682 		if (err < 0) {
2683 			ad198x_free(codec);
2684 			return err;
2685 		} else if (! err) {
2686 			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
2687 			board_config = AD1988_6STACK;
2688 		}
2689 	}
2690 
2691 	switch (board_config) {
2692 	case AD1988_6STACK:
2693 	case AD1988_6STACK_DIG:
2694 		spec->multiout.max_channels = 8;
2695 		spec->multiout.num_dacs = 4;
2696 		if (is_rev2(codec))
2697 			spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
2698 		else
2699 			spec->multiout.dac_nids = ad1988_6stack_dac_nids;
2700 		spec->input_mux = &ad1988_6stack_capture_source;
2701 		spec->num_mixers = 2;
2702 		if (is_rev2(codec))
2703 			spec->mixers[0] = ad1988_6stack_mixers1_rev2;
2704 		else
2705 			spec->mixers[0] = ad1988_6stack_mixers1;
2706 		spec->mixers[1] = ad1988_6stack_mixers2;
2707 		spec->num_init_verbs = 1;
2708 		spec->init_verbs[0] = ad1988_6stack_init_verbs;
2709 		if (board_config == AD1988_6STACK_DIG) {
2710 			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2711 			spec->dig_in_nid = AD1988_SPDIF_IN;
2712 		}
2713 		break;
2714 	case AD1988_3STACK:
2715 	case AD1988_3STACK_DIG:
2716 		spec->multiout.max_channels = 6;
2717 		spec->multiout.num_dacs = 3;
2718 		if (is_rev2(codec))
2719 			spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
2720 		else
2721 			spec->multiout.dac_nids = ad1988_3stack_dac_nids;
2722 		spec->input_mux = &ad1988_6stack_capture_source;
2723 		spec->channel_mode = ad1988_3stack_modes;
2724 		spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
2725 		spec->num_mixers = 2;
2726 		if (is_rev2(codec))
2727 			spec->mixers[0] = ad1988_3stack_mixers1_rev2;
2728 		else
2729 			spec->mixers[0] = ad1988_3stack_mixers1;
2730 		spec->mixers[1] = ad1988_3stack_mixers2;
2731 		spec->num_init_verbs = 1;
2732 		spec->init_verbs[0] = ad1988_3stack_init_verbs;
2733 		if (board_config == AD1988_3STACK_DIG)
2734 			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2735 		break;
2736 	case AD1988_LAPTOP:
2737 	case AD1988_LAPTOP_DIG:
2738 		spec->multiout.max_channels = 2;
2739 		spec->multiout.num_dacs = 1;
2740 		spec->multiout.dac_nids = ad1988_3stack_dac_nids;
2741 		spec->input_mux = &ad1988_laptop_capture_source;
2742 		spec->num_mixers = 1;
2743 		spec->mixers[0] = ad1988_laptop_mixers;
2744 		spec->num_init_verbs = 1;
2745 		spec->init_verbs[0] = ad1988_laptop_init_verbs;
2746 		if (board_config == AD1988_LAPTOP_DIG)
2747 			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
2748 		break;
2749 	}
2750 
2751 	spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
2752 	spec->adc_nids = ad1988_adc_nids;
2753 	spec->capsrc_nids = ad1988_capsrc_nids;
2754 	spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
2755 	spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
2756 	if (spec->multiout.dig_out_nid) {
2757 		spec->mixers[spec->num_mixers++] = ad1988_spdif_out_mixers;
2758 		spec->init_verbs[spec->num_init_verbs++] = ad1988_spdif_init_verbs;
2759 	}
2760 	if (spec->dig_in_nid)
2761 		spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
2762 
2763 	codec->patch_ops = ad198x_patch_ops;
2764 	switch (board_config) {
2765 	case AD1988_AUTO:
2766 		codec->patch_ops.init = ad1988_auto_init;
2767 		break;
2768 	case AD1988_LAPTOP:
2769 	case AD1988_LAPTOP_DIG:
2770 		codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
2771 		break;
2772 	}
2773 
2774 	return 0;
2775 }
2776 
2777 
2778 /*
2779  * AD1884 / AD1984
2780  *
2781  * port-B - front line/mic-in
2782  * port-E - aux in/out
2783  * port-F - aux in/out
2784  * port-C - rear line/mic-in
2785  * port-D - rear line/hp-out
2786  * port-A - front line/hp-out
2787  *
2788  * AD1984 = AD1884 + two digital mic-ins
2789  *
2790  * FIXME:
2791  * For simplicity, we share the single DAC for both HP and line-outs
2792  * right now.  The inidividual playbacks could be easily implemented,
2793  * but no build-up framework is given, so far.
2794  */
2795 
2796 static hda_nid_t ad1884_dac_nids[1] = {
2797 	0x04,
2798 };
2799 
2800 static hda_nid_t ad1884_adc_nids[2] = {
2801 	0x08, 0x09,
2802 };
2803 
2804 static hda_nid_t ad1884_capsrc_nids[2] = {
2805 	0x0c, 0x0d,
2806 };
2807 
2808 #define AD1884_SPDIF_OUT	0x02
2809 
2810 static struct hda_input_mux ad1884_capture_source = {
2811 	.num_items = 4,
2812 	.items = {
2813 		{ "Front Mic", 0x0 },
2814 		{ "Mic", 0x1 },
2815 		{ "CD", 0x2 },
2816 		{ "Mix", 0x3 },
2817 	},
2818 };
2819 
2820 static struct snd_kcontrol_new ad1884_base_mixers[] = {
2821 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2822 	/* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
2823 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2824 	HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2825 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
2826 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
2827 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
2828 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
2829 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
2830 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
2831 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
2832 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
2833 	/*
2834 	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
2835 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
2836 	HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
2837 	HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
2838 	*/
2839 	HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
2840 	HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
2841 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2842 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2843 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2844 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2845 	{
2846 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2847 		/* The multiple "Capture Source" controls confuse alsamixer
2848 		 * So call somewhat different..
2849 		 * FIXME: the controls appear in the "playback" view!
2850 		 */
2851 		/* .name = "Capture Source", */
2852 		.name = "Input Source",
2853 		.count = 2,
2854 		.info = ad198x_mux_enum_info,
2855 		.get = ad198x_mux_enum_get,
2856 		.put = ad198x_mux_enum_put,
2857 	},
2858 	/* SPDIF controls */
2859 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2860 	{
2861 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2862 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2863 		/* identical with ad1983 */
2864 		.info = ad1983_spdif_route_info,
2865 		.get = ad1983_spdif_route_get,
2866 		.put = ad1983_spdif_route_put,
2867 	},
2868 	{ } /* end */
2869 };
2870 
2871 static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
2872 	HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
2873 	HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
2874 	HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
2875 			     HDA_INPUT),
2876 	HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
2877 			   HDA_INPUT),
2878 	{ } /* end */
2879 };
2880 
2881 /*
2882  * initialization verbs
2883  */
2884 static struct hda_verb ad1884_init_verbs[] = {
2885 	/* DACs; mute as default */
2886 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2887 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2888 	/* Port-A (HP) mixer */
2889 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2890 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2891 	/* Port-A pin */
2892 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2893 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2894 	/* HP selector - select DAC2 */
2895 	{0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
2896 	/* Port-D (Line-out) mixer */
2897 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2898 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2899 	/* Port-D pin */
2900 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2901 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2902 	/* Mono-out mixer */
2903 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2904 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2905 	/* Mono-out pin */
2906 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2907 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2908 	/* Mono selector */
2909 	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2910 	/* Port-B (front mic) pin */
2911 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2912 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2913 	/* Port-C (rear mic) pin */
2914 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2915 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2916 	/* Analog mixer; mute as default */
2917 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2918 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2919 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2920 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2921 	/* Analog Mix output amp */
2922 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2923 	/* SPDIF output selector */
2924 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2925 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2926 	{ } /* end */
2927 };
2928 
2929 static int patch_ad1884(struct hda_codec *codec)
2930 {
2931 	struct ad198x_spec *spec;
2932 
2933 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2934 	if (spec == NULL)
2935 		return -ENOMEM;
2936 
2937 	mutex_init(&spec->amp_mutex);
2938 	codec->spec = spec;
2939 
2940 	spec->multiout.max_channels = 2;
2941 	spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
2942 	spec->multiout.dac_nids = ad1884_dac_nids;
2943 	spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
2944 	spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
2945 	spec->adc_nids = ad1884_adc_nids;
2946 	spec->capsrc_nids = ad1884_capsrc_nids;
2947 	spec->input_mux = &ad1884_capture_source;
2948 	spec->num_mixers = 1;
2949 	spec->mixers[0] = ad1884_base_mixers;
2950 	spec->num_init_verbs = 1;
2951 	spec->init_verbs[0] = ad1884_init_verbs;
2952 	spec->spdif_route = 0;
2953 
2954 	codec->patch_ops = ad198x_patch_ops;
2955 
2956 	return 0;
2957 }
2958 
2959 /*
2960  * Lenovo Thinkpad T61/X61
2961  */
2962 static struct hda_input_mux ad1984_thinkpad_capture_source = {
2963 	.num_items = 3,
2964 	.items = {
2965 		{ "Mic", 0x0 },
2966 		{ "Internal Mic", 0x1 },
2967 		{ "Mix", 0x3 },
2968 	},
2969 };
2970 
2971 static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
2972 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2973 	/* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
2974 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2975 	HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2976 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
2977 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
2978 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
2979 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
2980 	HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
2981 	HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
2982 	HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
2983 	HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
2984 	HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
2985 	HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
2986 	HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
2987 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2988 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2989 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2990 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2991 	{
2992 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2993 		/* The multiple "Capture Source" controls confuse alsamixer
2994 		 * So call somewhat different..
2995 		 * FIXME: the controls appear in the "playback" view!
2996 		 */
2997 		/* .name = "Capture Source", */
2998 		.name = "Input Source",
2999 		.count = 2,
3000 		.info = ad198x_mux_enum_info,
3001 		.get = ad198x_mux_enum_get,
3002 		.put = ad198x_mux_enum_put,
3003 	},
3004 	{ } /* end */
3005 };
3006 
3007 /* additional verbs */
3008 static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3009 	/* Port-E (docking station mic) pin */
3010 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3011 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3012 	/* docking mic boost */
3013 	{0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3014 	/* Analog mixer - docking mic; mute as default */
3015 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3016 	/* enable EAPD bit */
3017 	{0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3018 	{ } /* end */
3019 };
3020 
3021 /* Digial MIC ADC NID 0x05 + 0x06 */
3022 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3023 				   struct hda_codec *codec,
3024 				   unsigned int stream_tag,
3025 				   unsigned int format,
3026 				   struct snd_pcm_substream *substream)
3027 {
3028 	snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3029 				   stream_tag, 0, format);
3030 	return 0;
3031 }
3032 
3033 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3034 				   struct hda_codec *codec,
3035 				   struct snd_pcm_substream *substream)
3036 {
3037 	snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3038 				   0, 0, 0);
3039 	return 0;
3040 }
3041 
3042 static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3043 	.substreams = 2,
3044 	.channels_min = 2,
3045 	.channels_max = 2,
3046 	.nid = 0x05,
3047 	.ops = {
3048 		.prepare = ad1984_pcm_dmic_prepare,
3049 		.cleanup = ad1984_pcm_dmic_cleanup
3050 	},
3051 };
3052 
3053 static int ad1984_build_pcms(struct hda_codec *codec)
3054 {
3055 	struct ad198x_spec *spec = codec->spec;
3056 	struct hda_pcm *info;
3057 	int err;
3058 
3059 	err = ad198x_build_pcms(codec);
3060 	if (err < 0)
3061 		return err;
3062 
3063 	info = spec->pcm_rec + codec->num_pcms;
3064 	codec->num_pcms++;
3065 	info->name = "AD1984 Digital Mic";
3066 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3067 	return 0;
3068 }
3069 
3070 /* models */
3071 enum {
3072 	AD1984_BASIC,
3073 	AD1984_THINKPAD,
3074 	AD1984_MODELS
3075 };
3076 
3077 static const char *ad1984_models[AD1984_MODELS] = {
3078 	[AD1984_BASIC]		= "basic",
3079 	[AD1984_THINKPAD]	= "thinkpad",
3080 };
3081 
3082 static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3083 	/* Lenovo Thinkpad T61/X61 */
3084 	SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD),
3085 	{}
3086 };
3087 
3088 static int patch_ad1984(struct hda_codec *codec)
3089 {
3090 	struct ad198x_spec *spec;
3091 	int board_config, err;
3092 
3093 	err = patch_ad1884(codec);
3094 	if (err < 0)
3095 		return err;
3096 	spec = codec->spec;
3097 	board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3098 						  ad1984_models, ad1984_cfg_tbl);
3099 	switch (board_config) {
3100 	case AD1984_BASIC:
3101 		/* additional digital mics */
3102 		spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3103 		codec->patch_ops.build_pcms = ad1984_build_pcms;
3104 		break;
3105 	case AD1984_THINKPAD:
3106 		spec->multiout.dig_out_nid = 0;
3107 		spec->input_mux = &ad1984_thinkpad_capture_source;
3108 		spec->mixers[0] = ad1984_thinkpad_mixers;
3109 		spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3110 		break;
3111 	}
3112 	return 0;
3113 }
3114 
3115 
3116 /*
3117  * AD1882
3118  *
3119  * port-A - front hp-out
3120  * port-B - front mic-in
3121  * port-C - rear line-in, shared surr-out (3stack)
3122  * port-D - rear line-out
3123  * port-E - rear mic-in, shared clfe-out (3stack)
3124  * port-F - rear surr-out (6stack)
3125  * port-G - rear clfe-out (6stack)
3126  */
3127 
3128 static hda_nid_t ad1882_dac_nids[3] = {
3129 	0x04, 0x03, 0x05
3130 };
3131 
3132 static hda_nid_t ad1882_adc_nids[2] = {
3133 	0x08, 0x09,
3134 };
3135 
3136 static hda_nid_t ad1882_capsrc_nids[2] = {
3137 	0x0c, 0x0d,
3138 };
3139 
3140 #define AD1882_SPDIF_OUT	0x02
3141 
3142 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
3143 static struct hda_input_mux ad1882_capture_source = {
3144 	.num_items = 5,
3145 	.items = {
3146 		{ "Front Mic", 0x1 },
3147 		{ "Mic", 0x4 },
3148 		{ "Line", 0x2 },
3149 		{ "CD", 0x3 },
3150 		{ "Mix", 0x7 },
3151 	},
3152 };
3153 
3154 static struct snd_kcontrol_new ad1882_base_mixers[] = {
3155 	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3156 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
3157 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
3158 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
3159 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3160 	HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3161 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3162 	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3163 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3164 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3165 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3166 	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3167 	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
3168 	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
3169 	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
3170 	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
3171 	HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
3172 	HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
3173 	HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
3174 	HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
3175 	HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
3176 	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3177 	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3178 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3179 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3180 	{
3181 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3182 		/* The multiple "Capture Source" controls confuse alsamixer
3183 		 * So call somewhat different..
3184 		 * FIXME: the controls appear in the "playback" view!
3185 		 */
3186 		/* .name = "Capture Source", */
3187 		.name = "Input Source",
3188 		.count = 2,
3189 		.info = ad198x_mux_enum_info,
3190 		.get = ad198x_mux_enum_get,
3191 		.put = ad198x_mux_enum_put,
3192 	},
3193 	/* SPDIF controls */
3194 	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3195 	{
3196 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3197 		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3198 		/* identical with ad1983 */
3199 		.info = ad1983_spdif_route_info,
3200 		.get = ad1983_spdif_route_get,
3201 		.put = ad1983_spdif_route_put,
3202 	},
3203 	{ } /* end */
3204 };
3205 
3206 static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
3207 	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3208 	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
3209 	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
3210 	{
3211 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3212 		.name = "Channel Mode",
3213 		.info = ad198x_ch_mode_info,
3214 		.get = ad198x_ch_mode_get,
3215 		.put = ad198x_ch_mode_put,
3216 	},
3217 	{ } /* end */
3218 };
3219 
3220 static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
3221 	HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
3222 	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
3223 	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
3224 	{ } /* end */
3225 };
3226 
3227 static struct hda_verb ad1882_ch2_init[] = {
3228 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3229 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3230 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3231 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3232 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3233 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3234 	{ } /* end */
3235 };
3236 
3237 static struct hda_verb ad1882_ch4_init[] = {
3238 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3239 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3240 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3241 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3242 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3243 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3244 	{ } /* end */
3245 };
3246 
3247 static struct hda_verb ad1882_ch6_init[] = {
3248 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3249 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3250 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3251 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3252 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3253 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3254 	{ } /* end */
3255 };
3256 
3257 static struct hda_channel_mode ad1882_modes[3] = {
3258 	{ 2, ad1882_ch2_init },
3259 	{ 4, ad1882_ch4_init },
3260 	{ 6, ad1882_ch6_init },
3261 };
3262 
3263 /*
3264  * initialization verbs
3265  */
3266 static struct hda_verb ad1882_init_verbs[] = {
3267 	/* DACs; mute as default */
3268 	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3269 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3270 	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3271 	/* Port-A (HP) mixer */
3272 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3273 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3274 	/* Port-A pin */
3275 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3276 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3277 	/* HP selector - select DAC2 */
3278 	{0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
3279 	/* Port-D (Line-out) mixer */
3280 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3281 	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3282 	/* Port-D pin */
3283 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3284 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3285 	/* Mono-out mixer */
3286 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3287 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3288 	/* Mono-out pin */
3289 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3290 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3291 	/* Port-B (front mic) pin */
3292 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3293 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3294 	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3295 	/* Port-C (line-in) pin */
3296 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3297 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3298 	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3299 	/* Port-C mixer - mute as input */
3300 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3301 	{0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3302 	/* Port-E (mic-in) pin */
3303 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3304 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3305 	{0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3306 	/* Port-E mixer - mute as input */
3307 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3308 	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3309 	/* Port-F (surround) */
3310 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3311 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3312 	/* Port-G (CLFE) */
3313 	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3314 	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3315 	/* Analog mixer; mute as default */
3316 	/* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
3317 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3318 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3319 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3320 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3321 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3322 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3323 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3324 	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3325 	/* Analog Mix output amp */
3326 	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3327 	/* SPDIF output selector */
3328 	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3329 	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3330 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3331 	{ } /* end */
3332 };
3333 
3334 /* models */
3335 enum {
3336 	AD1882_3STACK,
3337 	AD1882_6STACK,
3338 	AD1882_MODELS
3339 };
3340 
3341 static const char *ad1882_models[AD1986A_MODELS] = {
3342 	[AD1882_3STACK]		= "3stack",
3343 	[AD1882_6STACK]		= "6stack",
3344 };
3345 
3346 
3347 static int patch_ad1882(struct hda_codec *codec)
3348 {
3349 	struct ad198x_spec *spec;
3350 	int board_config;
3351 
3352 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3353 	if (spec == NULL)
3354 		return -ENOMEM;
3355 
3356 	mutex_init(&spec->amp_mutex);
3357 	codec->spec = spec;
3358 
3359 	spec->multiout.max_channels = 6;
3360 	spec->multiout.num_dacs = 3;
3361 	spec->multiout.dac_nids = ad1882_dac_nids;
3362 	spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
3363 	spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
3364 	spec->adc_nids = ad1882_adc_nids;
3365 	spec->capsrc_nids = ad1882_capsrc_nids;
3366 	spec->input_mux = &ad1882_capture_source;
3367 	spec->num_mixers = 1;
3368 	spec->mixers[0] = ad1882_base_mixers;
3369 	spec->num_init_verbs = 1;
3370 	spec->init_verbs[0] = ad1882_init_verbs;
3371 	spec->spdif_route = 0;
3372 
3373 	codec->patch_ops = ad198x_patch_ops;
3374 
3375 	/* override some parameters */
3376 	board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
3377 						  ad1882_models, NULL);
3378 	switch (board_config) {
3379 	default:
3380 	case AD1882_3STACK:
3381 		spec->num_mixers = 2;
3382 		spec->mixers[1] = ad1882_3stack_mixers;
3383 		spec->channel_mode = ad1882_modes;
3384 		spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
3385 		spec->need_dac_fix = 1;
3386 		spec->multiout.max_channels = 2;
3387 		spec->multiout.num_dacs = 1;
3388 		break;
3389 	case AD1882_6STACK:
3390 		spec->num_mixers = 2;
3391 		spec->mixers[1] = ad1882_6stack_mixers;
3392 		break;
3393 	}
3394 	return 0;
3395 }
3396 
3397 
3398 /*
3399  * patch entries
3400  */
3401 struct hda_codec_preset snd_hda_preset_analog[] = {
3402 	{ .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
3403 	{ .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
3404 	{ .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
3405 	{ .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
3406 	{ .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
3407 	{ .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
3408 	{ .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
3409 	{ .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
3410 	{} /* terminator */
3411 };
3412