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