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