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