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